diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 4e1242a6..9f6abba 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4528,6 +4528,10 @@
       "webauthn/cablev2_devices.h",
       "webauthn/chrome_authenticator_request_delegate.cc",
       "webauthn/chrome_authenticator_request_delegate.h",
+      "webauthn/enclave_manager.cc",
+      "webauthn/enclave_manager.h",
+      "webauthn/enclave_manager_factory.cc",
+      "webauthn/enclave_manager_factory.h",
       "webauthn/local_credential_management.cc",
       "webauthn/local_credential_management.h",
       "webauthn/observable_authenticator_list.cc",
@@ -4587,12 +4591,14 @@
       "//chrome/browser/ui/webui/web_app_internals:mojo_bindings",
       "//chrome/browser/web_applications",
       "//chrome/browser/web_applications/app_service",
+      "//chrome/browser/webauthn/proto",
       "//chrome/common/apps/platform_apps",
       "//chrome/common/importer:interfaces",
       "//chrome/common/themes:autogenerated_theme_util",
       "//chrome/services/media_gallery_util/public/cpp",
       "//components/access_code_cast/common:metrics",
       "//components/app_constants",
+      "//components/cbor",
       "//components/commerce/core:cart_db_content_proto",
       "//components/commerce/core:coupon_db_content_proto",
       "//components/commerce/core:discounts_db_content_proto",
diff --git a/chrome/browser/webauthn/DEPS b/chrome/browser/webauthn/DEPS
index 8c2c087..99277687 100644
--- a/chrome/browser/webauthn/DEPS
+++ b/chrome/browser/webauthn/DEPS
@@ -2,4 +2,7 @@
   "+components/webauthn/android",
   "+components/externalauth/android",
   "+device/fido",
+  # EnclaveManager speaks CBOR to the passkeys enclave, which is a trustworth
+  # entity authenticated via the WebPKI and a public key baked into Chrome.
+  "+components/cbor",
 ]
diff --git a/chrome/browser/webauthn/enclave_manager.cc b/chrome/browser/webauthn/enclave_manager.cc
new file mode 100644
index 0000000..f31f49af
--- /dev/null
+++ b/chrome/browser/webauthn/enclave_manager.cc
@@ -0,0 +1,1197 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webauthn/enclave_manager.h"
+
+#include "base/files/file_util.h"
+#include "base/files/important_file_writer.h"
+#include "base/functional/overloaded.h"
+#include "base/stl_util.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "chrome/browser/webauthn/proto/enclave_local_state.pb.h"
+#include "components/cbor/diagnostic_writer.h"
+#include "components/cbor/reader.h"
+#include "components/cbor/values.h"
+#include "components/cbor/writer.h"
+#include "components/device_event_log/device_event_log.h"
+#include "components/os_crypt/sync/os_crypt.h"
+#include "components/signin/public/identity_manager/access_token_info.h"
+#include "components/signin/public/identity_manager/account_info.h"
+#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h"
+#include "components/trusted_vault/frontend_trusted_vault_connection.h"
+#include "components/trusted_vault/securebox.h"
+#include "components/trusted_vault/trusted_vault_connection.h"
+#include "components/trusted_vault/trusted_vault_server_constants.h"
+#include "crypto/sha2.h"
+#include "crypto/unexportable_key.h"
+#include "device/fido/enclave/constants.h"
+#include "device/fido/enclave/enclave_websocket_client.h"
+#include "device/fido/enclave/transact.h"
+#include "device/fido/enclave/types.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "google_apis/gaia/gaia_constants.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace enclave = device::enclave;
+using webauthn_pb::EnclaveLocalState;
+
+namespace {
+
+// Since protobuf maps `bytes` to `std::string` (rather than
+// `std::vector<uint8_t>`), functions for jumping between these representations
+// are needed.
+
+base::span<const uint8_t> ToSpan(const std::string& s) {
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(s.data());
+  return base::span<const uint8_t>(data, s.size());
+}
+
+std::vector<uint8_t> ToVector(const std::string& s) {
+  const auto span = ToSpan(s);
+  return std::vector<uint8_t>(span.begin(), span.end());
+}
+
+std::string VecToString(base::span<const uint8_t> v) {
+  const char* data = reinterpret_cast<const char*>(v.data());
+  return std::string(data, data + v.size());
+}
+
+bool IsValidSubjectPublicKeyInfo(base::span<const uint8_t> spki) {
+  CBS cbs;
+  CBS_init(&cbs, spki.data(), spki.size());
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs));
+  return static_cast<bool>(pkey);
+}
+
+bool IsValidUncompressedP256X962(base::span<const uint8_t> x962) {
+  if (x962.empty() || x962[0] != 4) {
+    return false;
+  }
+  const EC_GROUP* group = EC_group_p256();
+  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group));
+  return 1 == EC_POINT_oct2point(group, point.get(), x962.data(), x962.size(),
+                                 /*bn_ctx=*/nullptr);
+}
+
+// CheckInvariants checks all the invariants of `user`, returning either a
+// line-number for the failing check, or else `nullopt` to indicate success.
+std::optional<int> CheckInvariants(const EnclaveLocalState::User& user) {
+  if (user.wrapped_hardware_private_key().empty() !=
+      user.hardware_public_key().empty()) {
+    return __LINE__;
+  }
+  if (!user.hardware_public_key().empty() &&
+      !IsValidSubjectPublicKeyInfo(ToSpan(user.hardware_public_key()))) {
+    return __LINE__;
+  }
+  if (user.wrapped_hardware_private_key().empty() != user.device_id().empty()) {
+    return __LINE__;
+  }
+
+  if (user.wrapped_uv_private_key().empty() != user.uv_public_key().empty()) {
+    return __LINE__;
+  }
+  if (!user.uv_public_key().empty() &&
+      !IsValidSubjectPublicKeyInfo(ToSpan(user.uv_public_key()))) {
+    return __LINE__;
+  }
+
+  if (user.registered() && user.wrapped_hardware_private_key().empty()) {
+    return __LINE__;
+  }
+  if (user.registered() != !user.wrapped_member_private_key().empty()) {
+    return __LINE__;
+  }
+  if (user.wrapped_member_private_key().empty() !=
+      user.member_public_key().empty()) {
+    return __LINE__;
+  }
+  if (!user.member_public_key().empty() &&
+      !IsValidUncompressedP256X962(ToSpan(user.member_public_key()))) {
+    return __LINE__;
+  }
+
+  if (user.joined() && !user.registered()) {
+    return __LINE__;
+  }
+  if (!user.wrapped_security_domain_secrets().empty() != user.joined()) {
+    return __LINE__;
+  }
+
+  return absl::nullopt;
+}
+
+// Build an enclave request that registers a new device and requests a new
+// wrapped asymmetric key which will be used to join the security domain.
+cbor::Value BuildRegistrationMessage(
+    const std::string& device_id,
+    crypto::UnexportableSigningKey* hardware_key) {
+  cbor::Value::MapValue pub_keys;
+  pub_keys.emplace(enclave::kHardwareKey,
+                   hardware_key->GetSubjectPublicKeyInfo());
+
+  cbor::Value::MapValue request1;
+  request1.emplace(enclave::kRequestCommandKey, enclave::kRegisterCommandName);
+  request1.emplace(enclave::kRegisterDeviceIdKey,
+                   std::vector<uint8_t>(device_id.begin(), device_id.end()));
+  request1.emplace(enclave::kRegisterPubKeysKey, std::move(pub_keys));
+
+  cbor::Value::MapValue request2;
+  request2.emplace(enclave::kRequestCommandKey,
+                   enclave::kGenKeyPairCommandName);
+  request2.emplace(enclave::kWrappingPurpose,
+                   enclave::kKeyPurposeSecurityDomainMemberKey);
+
+  cbor::Value::ArrayValue requests;
+  requests.emplace_back(std::move(request1));
+  requests.emplace_back(std::move(request2));
+
+  return cbor::Value(std::move(requests));
+}
+
+EnclaveLocalState::User* StateForUser(EnclaveLocalState* local_state,
+                                      const CoreAccountInfo& account) {
+  auto it = local_state->mutable_users()->find(account.gaia);
+  if (it == local_state->mutable_users()->end()) {
+    return nullptr;
+  }
+  return &(it->second);
+}
+
+EnclaveLocalState::User* CreateStateForUser(EnclaveLocalState* local_state,
+                                            const CoreAccountInfo& account) {
+  auto pair = local_state->mutable_users()->insert(
+      {account.gaia, EnclaveLocalState::User()});
+  CHECK(pair.second);
+  return &(pair.first->second);
+}
+
+// Returns true if `response` contains exactly `num_responses` results, and none
+// of them is an error. This is used for checking whether an enclave response is
+// successful or not.
+bool IsAllOk(const cbor::Value& response, const size_t num_responses) {
+  if (!response.is_array()) {
+    return false;
+  }
+  const cbor::Value::ArrayValue& responses = response.GetArray();
+  if (responses.size() != num_responses) {
+    return false;
+  }
+  for (size_t i = 0; i < num_responses; i++) {
+    const cbor::Value& inner_response = responses[i];
+    if (!inner_response.is_map()) {
+      return false;
+    }
+    const cbor::Value::MapValue& inner_response_map = inner_response.GetMap();
+    if (inner_response_map.find(cbor::Value(enclave::kResponseSuccessKey)) ==
+        inner_response_map.end()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// Update `user` with the wrapped security domain member key in `response`.
+// This is used when registering with the enclave, which provides a wrapped
+// asymmetric key that becomes the security domain member key for this device.
+bool SetSecurityDomainMemberKey(EnclaveLocalState::User* user,
+                                const cbor::Value& wrap_response) {
+  if (!wrap_response.is_map()) {
+    return false;
+  }
+  const cbor::Value::MapValue& map = wrap_response.GetMap();
+  const auto pub_it =
+      map.find(cbor::Value(enclave::kWrappingResponsePublicKey));
+  const auto priv_it =
+      map.find(cbor::Value(enclave::kWrappingResponseWrappedPrivateKey));
+  if (pub_it == map.end() || priv_it == map.end() ||
+      !pub_it->second.is_bytestring() || !priv_it->second.is_bytestring()) {
+    return false;
+  }
+
+  user->set_wrapped_member_private_key(
+      VecToString(priv_it->second.GetBytestring()));
+  user->set_member_public_key(VecToString(pub_it->second.GetBytestring()));
+  return true;
+}
+
+// Build an enclave request to wrap the given security domain secrets.
+cbor::Value BuildWrappingMessage(
+    const base::flat_map<int32_t, std::vector<uint8_t>>
+        new_security_domain_secrets) {
+  cbor::Value::ArrayValue requests;
+  for (const auto& it : new_security_domain_secrets) {
+    cbor::Value::MapValue request;
+    request.emplace(enclave::kRequestCommandKey, enclave::kWrapKeyCommandName);
+    request.emplace(enclave::kWrappingPurpose,
+                    enclave::kKeyPurposeSecurityDomainSecret);
+    request.emplace(enclave::kWrappingKeyToWrap, it.second);
+    requests.emplace_back(cbor::Value(std::move(request)));
+  }
+
+  return cbor::Value(std::move(requests));
+}
+
+// Update `user` with the wrapped secrets in `response`. The
+// `new_security_domain_secrets` argument is used to determine the version
+// numbers of the wrapped secrets and this value must be the same as was passed
+// to `BuildWrappingMessage` to generate the enclave request.
+bool StoreWrappedSecrets(EnclaveLocalState::User* user,
+                         const base::flat_map<int32_t, std::vector<uint8_t>>
+                             new_security_domain_secrets,
+                         const cbor::Value& response) {
+  const cbor::Value::ArrayValue& responses = response.GetArray();
+  CHECK_EQ(new_security_domain_secrets.size(), responses.size());
+
+  size_t i = 0;
+  for (const auto& it : new_security_domain_secrets) {
+    const cbor::Value& wrapped_value =
+        responses[i++]
+            .GetMap()
+            .find(cbor::Value(enclave::kResponseSuccessKey))
+            ->second;
+    if (!wrapped_value.is_bytestring()) {
+      return false;
+    }
+    const std::vector<uint8_t>& wrapped = wrapped_value.GetBytestring();
+    if (wrapped.empty()) {
+      return false;
+    }
+    user->mutable_wrapped_security_domain_secrets()->insert(
+        {it.first, VecToString(wrapped)});
+  }
+
+  return true;
+}
+
+const char* TrustedVaultRegistrationStatusToString(
+    trusted_vault::TrustedVaultRegistrationStatus status) {
+  switch (status) {
+    case trusted_vault::TrustedVaultRegistrationStatus::kSuccess:
+      return "Success";
+    case trusted_vault::TrustedVaultRegistrationStatus::kAlreadyRegistered:
+      return "AlreadyRegistered";
+    case trusted_vault::TrustedVaultRegistrationStatus::kLocalDataObsolete:
+      return "LocalDataObsolete";
+    case trusted_vault::TrustedVaultRegistrationStatus::
+        kTransientAccessTokenFetchError:
+      return "TransientAccessTokenFetchError";
+    case trusted_vault::TrustedVaultRegistrationStatus::
+        kPersistentAccessTokenFetchError:
+      return "PersistentAccessTokenFetchError";
+    case trusted_vault::TrustedVaultRegistrationStatus::
+        kPrimaryAccountChangeAccessTokenFetchError:
+      return "PrimaryAccountChangeAccessTokenFetchError";
+    case trusted_vault::TrustedVaultRegistrationStatus::kNetworkError:
+      return "NetworkError";
+    case trusted_vault::TrustedVaultRegistrationStatus::kOtherError:
+      return "OtherError";
+  }
+}
+
+// The list of algorithms that are acceptable as device identity keys.
+constexpr crypto::SignatureVerifier::SignatureAlgorithm kSigningAlgorithms[] = {
+    // This is in preference order and the enclave must support all the
+    // algorithms listed here.
+    crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256,
+    crypto::SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256,
+};
+
+// Parse the contents of the decrypted state file. In the event of an error, an
+// empty state is returned. This causes a corrupt state file to reset the
+// enclave state for the current profile. Users will have to re-register with
+// the enclave.
+std::unique_ptr<EnclaveLocalState> ParseStateFile(
+    const std::string& contents_str) {
+  auto ret = std::make_unique<EnclaveLocalState>();
+
+  const base::span<const uint8_t> contents = ToSpan(contents_str);
+  if (contents.size() < crypto::kSHA256Length) {
+    FIDO_LOG(ERROR) << "Enclave state too small to be valid";
+    return ret;
+  }
+
+  const base::span<const uint8_t> digest = contents.last(crypto::kSHA256Length);
+  const base::span<const uint8_t> payload =
+      contents.first(contents.size() - crypto::kSHA256Length);
+  const std::array<uint8_t, crypto::kSHA256Length> calculated =
+      crypto::SHA256Hash(payload);
+  if (memcmp(calculated.data(), digest.data(), crypto::kSHA256Length) != 0) {
+    FIDO_LOG(ERROR) << "Checksum mismatch. Discarding state.";
+    return ret;
+  }
+
+  if (!ret->ParseFromArray(payload.data(), payload.size())) {
+    FIDO_LOG(ERROR) << "Parse failure loading enclave state";
+    // Just in case the failed parse left partial state, reset it.
+    ret = std::make_unique<EnclaveLocalState>();
+  }
+
+  return ret;
+}
+
+base::flat_set<std::string> GetGaiaIDs(
+    const std::vector<gaia::ListedAccount>& listed_accounts) {
+  base::flat_set<std::string> result;
+  for (const gaia::ListedAccount& listed_account : listed_accounts) {
+    result.insert(listed_account.gaia_id);
+  }
+  return result;
+}
+
+base::flat_set<std::string> GetGaiaIDs(
+    const google::protobuf::Map<std::string, EnclaveLocalState::User>& users) {
+  base::flat_set<std::string> result;
+  for (const auto& it : users) {
+    result.insert(it.first);
+  }
+  return result;
+}
+
+}  // namespace
+
+EnclaveManager::EnclaveManager(
+    const base::FilePath& base_dir,
+    signin::IdentityManager* identity_manager,
+    raw_ptr<network::mojom::NetworkContext> network_context,
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
+    : file_path_(base_dir.Append(FILE_PATH_LITERAL("passkey_enclave_state"))),
+      identity_manager_(identity_manager),
+      network_context_(network_context),
+      url_loader_factory_(url_loader_factory),
+      trusted_vault_conn_(trusted_vault::NewFrontendTrustedVaultConnection(
+          trusted_vault::SecurityDomainId::kPasskeys,
+          identity_manager,
+          url_loader_factory_)),
+      identity_observer_(
+          std::make_unique<IdentityObserver>(identity_manager_, this)) {}
+
+EnclaveManager::~EnclaveManager() = default;
+
+bool EnclaveManager::is_idle() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return state_ == State::kIdle;
+}
+
+bool EnclaveManager::is_loaded() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return static_cast<bool>(local_state_);
+}
+
+bool EnclaveManager::is_registered() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return user_ && user_->registered();
+}
+
+bool EnclaveManager::is_ready() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return is_registered() && !user_->wrapped_security_domain_secrets().empty();
+}
+
+unsigned EnclaveManager::store_keys_count() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return store_keys_count_;
+}
+
+void EnclaveManager::Start() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (state_ == State::kInit) {
+    state_ = State::kIdle;
+    ActIfIdle();
+  }
+}
+
+void EnclaveManager::RegisterIfNeeded() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (user_ && user_->registered()) {
+    return;
+  }
+  want_registration_ = true;
+  ActIfIdle();
+}
+
+enclave::SigningCallback EnclaveManager::HardwareKeySigningCallback() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(!user_->wrapped_hardware_private_key().empty());
+  CHECK(user_->registered());
+
+  return base::BindRepeating(
+      // TODO: this callback should also take a WeakPtr to the EnclaveManager so
+      // that the EnclaveManager can hold a cache of loaded keys and so that
+      // signing errors can be signaled up and cause the registration to be
+      // erased. (TPMs sometimes lose keys in practice.)
+      [](std::string wrapped_hardware_private_key, std::string device_id,
+         base::span<const uint8_t> message_to_be_signed)
+          -> enclave::ClientSignature {
+        // TODO: cache the key loading. TPMs are slow.
+        auto provider = crypto::GetSoftwareUnsecureUnexportableKeyProvider();
+        std::unique_ptr<crypto::UnexportableSigningKey> key =
+            provider->FromWrappedSigningKeySlowly(
+                ToVector(wrapped_hardware_private_key));
+        std::optional<std::vector<uint8_t>> signature =
+            key->SignSlowly(message_to_be_signed);
+        // TODO: this should be allowed to fail.
+        CHECK(signature);
+
+        enclave::ClientSignature ret;
+        ret.device_id = ToVector(device_id);
+        ret.signature = std::move(*signature);
+        ret.key_type = enclave::ClientKeyType::kHardware;
+
+        return ret;
+      },
+      user_->wrapped_hardware_private_key(), user_->device_id());
+}
+
+std::optional<std::vector<uint8_t>> EnclaveManager::GetWrappedKey(
+    int32_t version) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(is_ready());
+  const auto it = user_->wrapped_security_domain_secrets().find(version);
+  if (it == user_->wrapped_security_domain_secrets().end()) {
+    return absl::nullopt;
+  }
+  return ToVector(it->second);
+}
+
+std::vector<std::vector<uint8_t>> EnclaveManager::GetWrappedKeys() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(is_ready());
+  std::vector<std::vector<uint8_t>> ret;
+  for (const auto& it : user_->wrapped_security_domain_secrets()) {
+    ret.emplace_back(ToVector(it.second));
+  }
+  return ret;
+}
+
+void EnclaveManager::AddObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observer_list_.AddObserver(observer);
+}
+
+void EnclaveManager::RemoveObserver(Observer* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observer_list_.RemoveObserver(observer);
+}
+
+// Holds the arguments to `StoreKeys` so that they can be processed when the
+// state machine is ready for them.
+struct EnclaveManager::StoreKeysArgs {
+  std::string gaia_id;
+  std::vector<std::vector<uint8_t>> keys;
+  int last_key_version;
+};
+
+void EnclaveManager::StoreKeys(const std::string& gaia_id,
+                               std::vector<std::vector<uint8_t>> keys,
+                               int last_key_version) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  store_keys_args_ = std::make_unique<StoreKeysArgs>();
+  store_keys_args_->gaia_id = gaia_id;
+  store_keys_args_->keys = std::move(keys);
+  store_keys_args_->last_key_version = last_key_version;
+  store_keys_count_++;
+
+  ActIfIdle();
+}
+
+bool EnclaveManager::RunWhenStoppedForTesting(base::OnceClosure on_stop) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(state_ == State::kIdle || state_ == State::kInit);
+  if (!currently_writing_) {
+    return false;
+  }
+  write_finished_callback_ = std::move(on_stop);
+  return true;
+}
+
+const webauthn_pb::EnclaveLocalState& EnclaveManager::local_state_for_testing()
+    const {
+  return *local_state_;
+}
+
+// Observes the `IdentityManager` and tells the `EnclaveManager` when the
+// primary account for the profile has changed.
+class EnclaveManager::IdentityObserver
+    : public signin::IdentityManager::Observer {
+ public:
+  IdentityObserver(signin::IdentityManager* identity_manager,
+                   EnclaveManager* manager)
+      : identity_manager_(identity_manager), manager_(manager) {
+    identity_manager_->AddObserver(this);
+  }
+
+  ~IdentityObserver() override {
+    if (observing_) {
+      identity_manager_->RemoveObserver(this);
+    }
+  }
+
+  void OnPrimaryAccountChanged(
+      const signin::PrimaryAccountChangeEvent& event_details) override {
+    manager_->identity_updated_ = true;
+    manager_->ActIfIdle();
+  }
+
+  void OnAccountsInCookieUpdated(
+      const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
+      const GoogleServiceAuthError& error) override {
+    manager_->identity_updated_ = true;
+    manager_->ActIfIdle();
+  }
+
+  void OnIdentityManagerShutdown(
+      signin::IdentityManager* identity_manager) override {
+    if (observing_) {
+      identity_manager_->RemoveObserver(this);
+      observing_ = false;
+    }
+  }
+
+ private:
+  bool observing_ = true;
+  const raw_ptr<signin::IdentityManager> identity_manager_;
+  const raw_ptr<EnclaveManager> manager_;
+};
+
+// static
+std::string EnclaveManager::ToString(State state) {
+  switch (state) {
+    case State::kInit:
+      return "Init";
+    case State::kIdle:
+      return "Idle";
+    case State::kLoading:
+      return "Loading";
+    case State::kNextAction:
+      return "NextAction";
+    case State::kGeneratingKey:
+      return "GeneratingKey";
+    case State::kWaitingForEnclaveTokenForRegistration:
+      return "WaitingForEnclaveTokenForRegistration";
+    case State::kRegisteringWithEnclave:
+      return "RegisteringWithEnclave";
+    case State::kWaitingForEnclaveTokenForWrapping:
+      return "WaitingForEnclaveTokenForWrapping";
+    case State::kWrappingSecrets:
+      return "WrappingSecrets";
+    case State::kJoiningDomain:
+      return "JoiningDomain";
+  }
+}
+
+// static
+std::string EnclaveManager::ToString(const Event& event) {
+  return absl::visit(
+      base::Overloaded{
+          [](const None&) { return std::string(); },
+          [](const Failure&) { return std::string("Failure"); },
+          [](const FileContents&) { return std::string("FileContents"); },
+          [](const KeyReady&) { return std::string("KeyReady"); },
+          [](const EnclaveResponse&) { return std::string("EnclaveResponse"); },
+          [](const AccessToken&) { return std::string("AccessToken"); },
+          [](const JoinStatus& status) {
+            return std::string("JoinStatus(") +
+                   TrustedVaultRegistrationStatusToString(status.value()) + ")";
+          },
+      },
+      event);
+}
+
+void EnclaveManager::ActIfIdle() {
+  if (is_idle()) {
+    state_ = State::kNextAction;
+    Loop(None());
+  }
+}
+
+void EnclaveManager::Loop(Event in_event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  for (;;) {
+    const State initial_state = state_;
+    Event event = std::move(in_event);
+    in_event = None();
+
+    switch (state_) {
+      case State::kInit:
+        // This state should never be observed. `Start` should set the state to
+        // `kIdle` before starting the event loop for the first time.
+        NOTREACHED();
+        break;
+
+      case State::kIdle:
+        CHECK(absl::holds_alternative<None>(event)) << ToString(event);
+        ResetActionState();
+        for (Observer& observer : observer_list_) {
+          observer.OnEnclaveManagerIdle();
+        }
+        return;
+
+      case State::kNextAction:
+        CHECK(absl::holds_alternative<None>(event)) << ToString(event);
+        DoNextAction(std::move(event));
+        break;
+
+      case State::kLoading: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        }
+        DoLoading(std::move(event));
+        break;
+      }
+
+      case State::kGeneratingKey: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        } else if (absl::holds_alternative<Failure>(event)) {
+          // The object that requested the registration will observe when this
+          // object idles again, and will notice that the user still isn't
+          // registered.
+          state_ = State::kNextAction;
+          return;
+        }
+        DoGeneratingKey(std::move(event));
+        break;
+      }
+
+      case State::kWaitingForEnclaveTokenForRegistration: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        }
+        DoWaitingForEnclaveTokenForRegistration(std::move(event));
+        break;
+      }
+
+      case State::kRegisteringWithEnclave: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        } else if (absl::holds_alternative<Failure>(event)) {
+          // The object that requested the registration will observe when this
+          // object idles again, and will notice that the user still isn't
+          // registered.
+          FIDO_LOG(ERROR) << "Failed to register with enclave";
+          state_ = State::kNextAction;
+          break;
+        }
+        DoRegisteringWithEnclave(std::move(event));
+
+        break;
+      }
+
+      case State::kWaitingForEnclaveTokenForWrapping: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        }
+        DoWaitingForEnclaveTokenForWrapping(std::move(event));
+        break;
+      }
+
+      case State::kWrappingSecrets: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        }
+        DoWrappingSecrets(std::move(event));
+
+        break;
+      }
+
+      case State::kJoiningDomain: {
+        if (absl::holds_alternative<None>(event)) {
+          return;
+        }
+
+        DoJoiningDomain(std::move(event));
+        break;
+      }
+    }
+
+    FIDO_LOG(EVENT) << ToString(initial_state) << " -" << ToString(event)
+                    << "-> " << ToString(state_);
+  }
+}
+
+void EnclaveManager::ResetActionState() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  store_keys_args_for_joining_.reset();
+  hardware_key_.reset();
+  new_security_domain_secrets_.clear();
+  join_request_.reset();
+  access_token_fetcher_.reset();
+}
+
+void EnclaveManager::DoNextAction(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!local_state_) {
+    StartLoadingState();
+    return;
+  }
+
+  if (identity_updated_) {
+    identity_updated_ = false;
+    HandleIdentityChange();
+  }
+
+  if (want_registration_ && user_ && !user_->registered()) {
+    want_registration_ = false;
+    StartEnclaveRegistration();
+    return;
+  }
+
+  if (user_ && user_->registered() && store_keys_args_) {
+    auto store_keys_args = std::move(store_keys_args_);
+    store_keys_args_.reset();
+
+    if (store_keys_args->gaia_id != primary_account_info_->gaia) {
+      FIDO_LOG(ERROR) << "Have keys for GAIA " << store_keys_args->gaia_id
+                      << " but primary account is "
+                      << primary_account_info_->gaia;
+    } else {
+      new_security_domain_secrets_ =
+          GetNewSecretsToStore(*user_, *store_keys_args);
+      if (!new_security_domain_secrets_.empty()) {
+        state_ = State::kWaitingForEnclaveTokenForWrapping;
+        store_keys_args_for_joining_ = std::move(store_keys_args);
+        GetAccessToken();
+        return;
+      } else if (!user_->joined() && !user_->member_public_key().empty()) {
+        store_keys_args_for_joining_ = std::move(store_keys_args);
+        JoinDomain();
+        return;
+      }
+    }
+  }
+
+  state_ = State::kIdle;
+}
+
+void EnclaveManager::StartLoadingState() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  state_ = State::kLoading;
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+      base::BindOnce(
+          [](base::FilePath path) -> Event {
+            std::string contents, decrypted;
+            if (!base::ReadFileToString(path, &contents) ||
+                !OSCrypt::DecryptString(contents, &decrypted)) {
+              return Failure();
+            }
+
+            return FileContents(std::move(decrypted));
+          },
+          file_path_),
+      base::BindOnce(&EnclaveManager::Loop, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::HandleIdentityChange() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  ResetActionState();
+  CoreAccountInfo primary_account_info =
+      identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
+  if (!primary_account_info.IsEmpty()) {
+    user_ = StateForUser(local_state_.get(), primary_account_info);
+    if (!user_) {
+      user_ = CreateStateForUser(local_state_.get(), primary_account_info);
+    }
+    primary_account_info_ =
+        std::make_unique<CoreAccountInfo>(std::move(primary_account_info));
+  } else {
+    user_ = nullptr;
+    primary_account_info_.reset();
+  }
+
+  const signin::AccountsInCookieJarInfo in_jar =
+      identity_manager_->GetAccountsInCookieJar();
+  if (!in_jar.accounts_are_fresh) {
+    return;
+  }
+
+  // If the user has signed out of any non-primary accounts, erase their enclave
+  // state.
+  const base::flat_set<std::string> gaia_ids_in_cookie_jar =
+      base::STLSetUnion<base::flat_set<std::string>>(
+          GetGaiaIDs(in_jar.signed_in_accounts),
+          GetGaiaIDs(in_jar.signed_out_accounts));
+  const base::flat_set<std::string> gaia_ids_in_state =
+      GetGaiaIDs(local_state_->users());
+  base::flat_set<std::string> to_remove =
+      base::STLSetDifference<base::flat_set<std::string>>(
+          gaia_ids_in_state, gaia_ids_in_cookie_jar);
+  if (primary_account_info_) {
+    to_remove.erase(primary_account_info_->gaia);
+  }
+  for (const auto& gaia_id : to_remove) {
+    CHECK(local_state_->mutable_users()->erase(gaia_id));
+  }
+  WriteState();
+}
+
+void EnclaveManager::StartEnclaveRegistration() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  state_ = State::kGeneratingKey;
+  std::optional<std::vector<uint8_t>> existing_key_id;
+  if (user_ && !user_->wrapped_hardware_private_key().empty()) {
+    existing_key_id = ToVector(user_->wrapped_hardware_private_key());
+  }
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
+      base::BindOnce(
+          [](std::optional<std::vector<uint8_t>> key_id) -> Event {
+            auto provider =
+                crypto::GetSoftwareUnsecureUnexportableKeyProvider();
+            if (!provider) {
+              return Failure();
+            }
+            if (key_id) {
+              std::unique_ptr<crypto::UnexportableSigningKey> key =
+                  provider->FromWrappedSigningKeySlowly(*key_id);
+              if (key) {
+                return KeyReady(std::move(key));
+              }
+            }
+            std::unique_ptr<crypto::UnexportableSigningKey> key =
+                provider->GenerateSigningKeySlowly(kSigningAlgorithms);
+            if (!key) {
+              return Failure();
+            }
+            return KeyReady(std::move(key));
+          },
+          std::move(existing_key_id)),
+      base::BindOnce(&EnclaveManager::Loop, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::DoLoading(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const FileContents* contents = absl::get_if<FileContents>(&event);
+  if (contents) {
+    local_state_ = ParseStateFile(std::move(contents->value()));
+  } else if (absl::holds_alternative<Failure>(event)) {
+    local_state_ = std::make_unique<EnclaveLocalState>();
+  } else {
+    NOTREACHED() << "Unexpected event " << ToString(event);
+  }
+
+  for (const auto& it : local_state_->users()) {
+    std::optional<int> error_line = CheckInvariants(it.second);
+    if (error_line.has_value()) {
+      FIDO_LOG(ERROR) << "State invariant failed on line " << *error_line;
+      local_state_ = std::make_unique<EnclaveLocalState>();
+      break;
+    }
+  }
+
+  state_ = State::kNextAction;
+}
+
+void EnclaveManager::DoGeneratingKey(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(absl::holds_alternative<KeyReady>(event)) << ToString(event);
+
+  hardware_key_ = std::move(absl::get_if<KeyReady>(&event)->value());
+
+  const std::vector<uint8_t> spki = hardware_key_->GetSubjectPublicKeyInfo();
+  const std::string spki_str = VecToString(spki);
+  if (user_->hardware_public_key() != spki_str) {
+    std::array<uint8_t, crypto::kSHA256Length> device_id =
+        crypto::SHA256Hash(spki);
+    user_->set_hardware_public_key(spki_str);
+    user_->set_wrapped_hardware_private_key(
+        VecToString(hardware_key_->GetWrappedKey()));
+    user_->set_device_id(VecToString(device_id));
+
+    WriteState();
+  }
+
+  state_ = State::kWaitingForEnclaveTokenForRegistration;
+  GetAccessToken();
+}
+
+void EnclaveManager::DoWaitingForEnclaveTokenForRegistration(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  access_token_fetcher_.reset();
+  if (absl::holds_alternative<Failure>(event)) {
+    FIDO_LOG(ERROR) << "Failed to get access token for enclave";
+    state_ = State::kNextAction;
+    return;
+  }
+  CHECK(absl::holds_alternative<AccessToken>(event)) << ToString(event);
+
+  state_ = State::kRegisteringWithEnclave;
+  std::string token = std::move(absl::get_if<AccessToken>(&event)->value());
+  enclave::Transact(
+      network_context_, enclave::GetEnclaveIdentity(), std::move(token),
+      BuildRegistrationMessage(user_->device_id(), hardware_key_.get()),
+      enclave::SigningCallback(),
+      base::BindOnce(
+          [](base::WeakPtr<EnclaveManager> client,
+             std::optional<cbor::Value> response) {
+            if (!client) {
+              return;
+            }
+            if (!response) {
+              client->Loop(Failure());
+            } else {
+              client->Loop(EnclaveResponse(std::move(*response)));
+            }
+          },
+          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::DoRegisteringWithEnclave(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  cbor::Value response =
+      std::move(absl::get_if<EnclaveResponse>(&event)->value());
+  if (!IsAllOk(response, 2)) {
+    FIDO_LOG(ERROR) << "Registration resulted in error response: "
+                    << cbor::DiagnosticWriter::Write(response);
+    state_ = State::kNextAction;
+    return;
+  }
+
+  if (!SetSecurityDomainMemberKey(
+          user_, response.GetArray()[1]
+                     .GetMap()
+                     .find(cbor::Value(enclave::kResponseSuccessKey))
+                     ->second)) {
+    FIDO_LOG(ERROR) << "Wrapped member key was invalid: "
+                    << cbor::DiagnosticWriter::Write(response);
+    state_ = State::kNextAction;
+    return;
+  }
+
+  user_->set_registered(true);
+  WriteState();
+  state_ = State::kNextAction;
+}
+
+void EnclaveManager::DoWaitingForEnclaveTokenForWrapping(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  access_token_fetcher_.reset();
+  if (absl::holds_alternative<Failure>(event)) {
+    FIDO_LOG(ERROR) << "Failed to get access token for enclave";
+    state_ = State::kNextAction;
+    return;
+  }
+
+  state_ = State::kWrappingSecrets;
+  std::string token = std::move(absl::get_if<AccessToken>(&event)->value());
+  enclave::Transact(network_context_, enclave::GetEnclaveIdentity(),
+                    std::move(token),
+                    BuildWrappingMessage(new_security_domain_secrets_),
+                    HardwareKeySigningCallback(),
+                    base::BindOnce(
+                        [](base::WeakPtr<EnclaveManager> client,
+                           std::optional<cbor::Value> response) {
+                          if (!client) {
+                            return;
+                          }
+                          if (!response) {
+                            client->Loop(Failure());
+                          } else {
+                            client->Loop(EnclaveResponse(std::move(*response)));
+                          }
+                        },
+                        weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::DoWrappingSecrets(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const auto new_security_domain_secrets =
+      std::move(new_security_domain_secrets_);
+  new_security_domain_secrets_.clear();
+
+  if (absl::holds_alternative<Failure>(event)) {
+    FIDO_LOG(ERROR) << "Failed to wrap security domain secrets";
+    state_ = State::kNextAction;
+    return;
+  }
+
+  cbor::Value response =
+      std::move(absl::get_if<EnclaveResponse>(&event)->value());
+  if (!IsAllOk(response, new_security_domain_secrets.size())) {
+    FIDO_LOG(ERROR) << "Wrapping resulted in error response: "
+                    << cbor::DiagnosticWriter::Write(response);
+    state_ = State::kNextAction;
+    return;
+  }
+
+  if (!StoreWrappedSecrets(user_, new_security_domain_secrets, response)) {
+    FIDO_LOG(ERROR) << "Failed to store wrapped secrets";
+    state_ = State::kNextAction;
+    return;
+  }
+
+  if (!user_->joined()) {
+    JoinDomain();
+  } else {
+    WriteState();
+    state_ = State::kNextAction;
+  }
+}
+
+void EnclaveManager::JoinDomain() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  state_ = State::kJoiningDomain;
+  const auto secure_box_pub_key =
+      trusted_vault::SecureBoxPublicKey::CreateByImport(
+          ToSpan(user_->member_public_key()));
+  join_request_ = trusted_vault_conn_->RegisterAuthenticationFactor(
+      *primary_account_info_, store_keys_args_for_joining_->keys,
+      store_keys_args_for_joining_->last_key_version, *secure_box_pub_key,
+      trusted_vault::AuthenticationFactorType::kPhysicalDevice,
+      /*authentication_factor_type_hint=*/absl::nullopt,
+      base::BindOnce(
+          [](base::WeakPtr<EnclaveManager> client,
+             trusted_vault::TrustedVaultRegistrationStatus status) {
+            if (!client) {
+              return;
+            }
+            client->Loop(JoinStatus(status));
+          },
+          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::DoJoiningDomain(Event event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  join_request_.reset();
+  store_keys_args_for_joining_.reset();
+
+  CHECK(absl::holds_alternative<JoinStatus>(event));
+  const trusted_vault::TrustedVaultRegistrationStatus status =
+      absl::get_if<JoinStatus>(&event)->value();
+
+  switch (status) {
+    case trusted_vault::TrustedVaultRegistrationStatus::kSuccess:
+    case trusted_vault::TrustedVaultRegistrationStatus::kAlreadyRegistered:
+      user_->set_joined(true);
+      break;
+    default:
+      user_->mutable_wrapped_security_domain_secrets()->clear();
+      break;
+  }
+
+  WriteState();
+  state_ = State::kNextAction;
+}
+
+void EnclaveManager::WriteState() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  for (const auto& it : local_state_->users()) {
+    std::optional<int> error_line = CheckInvariants(it.second);
+    CHECK(!error_line.has_value())
+        << "State invariant failed on line " << *error_line;
+  }
+
+  if (currently_writing_) {
+    need_write_ = true;
+    return;
+  }
+
+  DoWriteState();
+}
+
+void EnclaveManager::DoWriteState() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  std::string serialized;
+  serialized.reserve(1024);
+  local_state_->AppendToString(&serialized);
+  const std::array<uint8_t, crypto::kSHA256Length> digest =
+      crypto::SHA256Hash(base::as_bytes(base::make_span(serialized)));
+  serialized.append(digest.begin(), digest.end());
+
+  currently_writing_ = true;
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
+      base::BindOnce(
+          [](base::FilePath path, std::string contents) -> bool {
+            std::string encrypted;
+            return OSCrypt::EncryptString(contents, &encrypted) &&
+                   base::ImportantFileWriter::WriteFileAtomically(path,
+                                                                  contents);
+          },
+          file_path_, std::move(serialized)),
+      base::BindOnce(&EnclaveManager::WriteStateComplete,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void EnclaveManager::WriteStateComplete(bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  currently_writing_ = false;
+  if (!success) {
+    FIDO_LOG(ERROR) << "Failed to write enclave state";
+  }
+
+  if (need_write_) {
+    need_write_ = false;
+    DoWriteState();
+    return;
+  }
+
+  if (write_finished_callback_) {
+    std::move(write_finished_callback_).Run();
+  }
+}
+
+// static
+base::flat_map<int32_t, std::vector<uint8_t>>
+EnclaveManager::GetNewSecretsToStore(const EnclaveLocalState::User& user,
+                                     const StoreKeysArgs& args) {
+  const auto& existing = user.wrapped_security_domain_secrets();
+  base::flat_map<int32_t, std::vector<uint8_t>> new_secrets;
+  for (int32_t i = args.last_key_version - args.keys.size() + 1;
+       i <= args.last_key_version; i++) {
+    if (existing.find(i) == existing.end()) {
+      new_secrets.emplace(i, args.keys[args.last_key_version - i]);
+    }
+  }
+
+  return new_secrets;
+}
+
+void EnclaveManager::GetAccessToken() {
+  access_token_fetcher_ =
+      std::make_unique<signin::PrimaryAccountAccessTokenFetcher>(
+          "passkeys_enclave", identity_manager_,
+          signin::ScopeSet{GaiaConstants::kPasskeysEnclaveOAuth2Scope},
+          base::BindOnce(
+              [](base::WeakPtr<EnclaveManager> client,
+                 GoogleServiceAuthError error,
+                 signin::AccessTokenInfo access_token_info) {
+                if (!client) {
+                  return;
+                }
+                if (error.state() == GoogleServiceAuthError::NONE) {
+                  client->Loop(AccessToken(access_token_info.token));
+                } else {
+                  client->Loop(Failure());
+                }
+              },
+              weak_ptr_factory_.GetWeakPtr()),
+          signin::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable,
+          signin::ConsentLevel::kSignin);
+}
diff --git a/chrome/browser/webauthn/enclave_manager.h b/chrome/browser/webauthn/enclave_manager.h
new file mode 100644
index 0000000..f3cb640
--- /dev/null
+++ b/chrome/browser/webauthn/enclave_manager.h
@@ -0,0 +1,244 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_H_
+#define CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_H_
+
+#include <optional>
+#include <string>
+#include <variant>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/files/file_path.h"
+#include "base/functional/callback_forward.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/observer_list.h"
+#include "base/sequence_checker.h"
+#include "base/types/strong_alias.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/trusted_vault/trusted_vault_connection.h"
+#include "device/fido/enclave/types.h"
+#include "services/network/public/mojom/network_context.mojom-forward.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+
+namespace cbor {
+class Value;
+}
+
+namespace crypto {
+class UnexportableSigningKey;
+}  // namespace crypto
+
+namespace network {
+class SharedURLLoaderFactory;
+}  // namespace network
+
+namespace signin {
+class IdentityManager;
+class PrimaryAccountAccessTokenFetcher;
+}  // namespace signin
+
+namespace trusted_vault {
+enum class TrustedVaultRegistrationStatus;
+}
+
+namespace webauthn_pb {
+class EnclaveLocalState;
+class EnclaveLocalState_User;
+}  // namespace webauthn_pb
+
+// EnclaveManager stores and manages the passkey enclave state. One instance
+// exists per-profile, owned by `EnclaveManagerFactory`.
+//
+// The state exposed from this class is per-primary-account. This class watches
+// the `IdentityManager` and, when the primary account changes, the result of
+// functions like `is_registered` will suddenly change too. If an account is
+// removed from the cookie jar (and it's not primary) then state for that
+// account will be erased.
+//
+// Calling `Start` for the first time will cause the persisted state to be read
+// from the disk. Each time all requested operations have completed, the class
+// becomes "idle": `is_idle` will return true, and `OnEnclaveManagerIdle`
+// will be called for all observers.
+//
+// When `is_ready` is true then this class can produce wrapped security domain
+// secrets and signing callbacks to use to perform passkey operations with the
+// enclave, which is the ultimate point of this class.
+class EnclaveManager : public KeyedService {
+ public:
+  class Observer : public base::CheckedObserver {
+   public:
+    virtual void OnEnclaveManagerIdle() = 0;
+  };
+
+  EnclaveManager(
+      const base::FilePath& base_dir,
+      signin::IdentityManager* identity_manager,
+      raw_ptr<network::mojom::NetworkContext> network_context,
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+  ~EnclaveManager() override;
+  EnclaveManager(const EnclaveManager&) = delete;
+  EnclaveManager(const EnclaveManager&&) = delete;
+
+  // Returns true if there are no current operations pending.
+  bool is_idle() const;
+  // Returns true if the persistent state has been loaded from the disk. (Or
+  // else the loading failed and an empty state is being used.)
+  bool is_loaded() const;
+  // Returns true if the current user has been registered with the enclave.
+  bool is_registered() const;
+  // Returns true if the current user has joined the security domain and has one
+  // or more wrapped security domain secrets available. (This implies
+  // `is_registered`.)
+  bool is_ready() const;
+  // Returns the number of times that `StoreKeys` has been called.
+  unsigned store_keys_count() const;
+
+  // Start by loading the persisted state from disk. Harmless to call multiple
+  // times.
+  void Start();
+  // Register with the enclave if not already registered.
+  void RegisterIfNeeded();
+
+  // Get a callback to sign with the registered "hw" key. Only valid to call if
+  // `is_ready`.
+  device::enclave::SigningCallback HardwareKeySigningCallback();
+  // Fetch a wrapped security domain secret for the given epoch. Only valid to
+  // call if `is_ready`.
+  std::optional<std::vector<uint8_t>> GetWrappedKey(int32_t version);
+  // Fetch all wrapped security domain secrets, for when it's unknown which one
+  // a WebauthnCredentialSpecifics will need. Only valid to call if `is_ready`.
+  std::vector<std::vector<uint8_t>> GetWrappedKeys();
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  void StoreKeys(const std::string& gaia_id,
+                 std::vector<std::vector<uint8_t>> keys,
+                 int last_key_version);
+
+  // If background processes need to be stopped then return true and call
+  // `on_stop` when stopped. Otherwise return false.
+  bool RunWhenStoppedForTesting(base::OnceClosure on_stop);
+
+  const webauthn_pb::EnclaveLocalState& local_state_for_testing() const;
+
+ private:
+  struct StoreKeysArgs;
+  class IdentityObserver;
+
+  // The main part of this class is a state machine that uses the following
+  // states. It moves from state to state in response to `Event` values.
+  // Fields such as `want_registration_` and `identity_updated_` are set in
+  // order to record that the state machine needs to process those requests
+  // once the current processing has completed.
+  enum class State {
+    kInit,
+    kIdle,
+    kNextAction,
+    kLoading,
+    kGeneratingKey,
+    kWaitingForEnclaveTokenForRegistration,
+    kRegisteringWithEnclave,
+    kWaitingForEnclaveTokenForWrapping,
+    kWrappingSecrets,
+    kJoiningDomain,
+  };
+  static std::string ToString(State);
+
+  using None = base::StrongAlias<class None, absl::monostate>;
+  using Failure =
+      base::StrongAlias<class KeyGenerationFailure, absl::monostate>;
+  using FileContents = base::StrongAlias<class FileContents, std::string>;
+  using KeyReady =
+      base::StrongAlias<class KeyGenerated,
+                        std::unique_ptr<crypto::UnexportableSigningKey>>;
+  using EnclaveResponse = base::StrongAlias<class EnclaveResponse, cbor::Value>;
+  using JoinStatus =
+      base::StrongAlias<class JoinStatus,
+                        trusted_vault::TrustedVaultRegistrationStatus>;
+  using AccessToken = base::StrongAlias<class AccessToken, std::string>;
+  using Event = absl::variant<None,
+                              Failure,
+                              FileContents,
+                              KeyReady,
+                              EnclaveResponse,
+                              AccessToken,
+                              JoinStatus>;
+  static std::string ToString(const Event&);
+
+  // Moves to `kNextAction` if currently `kIdle`, which will trigger the next
+  // requested action.
+  void ActIfIdle();
+
+  // The main event loop function, and split out functions to handle each state.
+  void Loop(Event);
+  void ResetActionState();
+  void DoNextAction(Event);
+  void StartLoadingState();
+  void HandleIdentityChange();
+  void StartEnclaveRegistration();
+  void DoLoading(Event event);
+  void DoGeneratingKey(Event event);
+  void DoWaitingForEnclaveTokenForRegistration(Event event);
+  void DoRegisteringWithEnclave(Event event);
+  void DoWaitingForEnclaveTokenForWrapping(Event event);
+  void DoWrappingSecrets(Event event);
+  void JoinDomain();
+  void DoJoiningDomain(Event event);
+
+  // Can be called at any point to serialise the current value of `local_state_`
+  // to disk. Only a single write happens at a time. If a write is already
+  // happening, the request will be queued. If a request is already queued, this
+  // call will be ignored.
+  void WriteState();
+  void DoWriteState();
+  void WriteStateComplete(bool success);
+
+  void GetAccessToken();
+  static base::flat_map<int32_t, std::vector<uint8_t>> GetNewSecretsToStore(
+      const webauthn_pb::EnclaveLocalState_User& user,
+      const StoreKeysArgs& args);
+
+  const base::FilePath file_path_;
+  const raw_ptr<signin::IdentityManager> identity_manager_;
+  const raw_ptr<network::mojom::NetworkContext> network_context_;
+  const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+  const std::unique_ptr<trusted_vault::TrustedVaultConnection>
+      trusted_vault_conn_;
+
+  State state_ = State::kInit;
+  std::unique_ptr<webauthn_pb::EnclaveLocalState> local_state_;
+  raw_ptr<webauthn_pb::EnclaveLocalState_User> user_ = nullptr;
+  std::unique_ptr<CoreAccountInfo> primary_account_info_;
+  std::unique_ptr<IdentityObserver> identity_observer_;
+
+  bool need_write_ = false;
+  bool currently_writing_ = false;
+  base::OnceClosure write_finished_callback_;
+  std::unique_ptr<StoreKeysArgs> store_keys_args_;
+
+  // These members hold state that only exists for the duration of a sequence of
+  // non-idle states. Every time the state machine idles, all these members are
+  // reset.
+  std::unique_ptr<StoreKeysArgs> store_keys_args_for_joining_;
+  std::unique_ptr<crypto::UnexportableSigningKey> hardware_key_;
+  base::flat_map<int32_t, std::vector<uint8_t>> new_security_domain_secrets_;
+  std::unique_ptr<trusted_vault::TrustedVaultConnection::Request> join_request_;
+  std::unique_ptr<signin::PrimaryAccountAccessTokenFetcher>
+      access_token_fetcher_;
+
+  unsigned store_keys_count_ = 0;
+  bool want_registration_ = false;
+  bool identity_updated_ = true;
+
+  base::ObserverList<Observer> observer_list_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+  base::WeakPtrFactory<EnclaveManager> weak_ptr_factory_{this};
+};
+
+#endif  // CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_H_
diff --git a/chrome/browser/webauthn/enclave_manager_factory.cc b/chrome/browser/webauthn/enclave_manager_factory.cc
new file mode 100644
index 0000000..35ef0b3
--- /dev/null
+++ b/chrome/browser/webauthn/enclave_manager_factory.cc
@@ -0,0 +1,48 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webauthn/enclave_manager_factory.h"
+
+#include "chrome/browser/net/system_network_context_manager.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/webauthn/enclave_manager.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+#include "content/public/browser/storage_partition.h"
+
+// static
+EnclaveManager* EnclaveManagerFactory::GetForProfile(Profile* profile) {
+  return static_cast<EnclaveManager*>(
+      GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true));
+}
+
+// static
+EnclaveManagerFactory* EnclaveManagerFactory::GetInstance() {
+  static base::NoDestructor<EnclaveManagerFactory> instance;
+  return instance.get();
+}
+
+EnclaveManagerFactory::EnclaveManagerFactory()
+    : ProfileKeyedServiceFactory(
+          "EnclaveManager",
+          ProfileSelections::Builder()
+              .WithRegular(ProfileSelection::kRedirectedToOriginal)
+              .WithGuest(ProfileSelection::kNone)
+              .Build()) {
+  DependsOn(IdentityManagerFactory::GetInstance());
+}
+
+EnclaveManagerFactory::~EnclaveManagerFactory() = default;
+
+std::unique_ptr<KeyedService>
+EnclaveManagerFactory::BuildServiceInstanceForBrowserContext(
+    content::BrowserContext* context) const {
+  Profile* const profile = Profile::FromBrowserContext(context);
+  return std::make_unique<EnclaveManager>(
+      /*base_dir=*/profile->GetPath(),
+      IdentityManagerFactory::GetForProfile(profile),
+      SystemNetworkContextManager::GetInstance()->GetContext(),
+      profile->GetDefaultStoragePartition()
+          ->GetURLLoaderFactoryForBrowserProcess());
+}
diff --git a/chrome/browser/webauthn/enclave_manager_factory.h b/chrome/browser/webauthn/enclave_manager_factory.h
new file mode 100644
index 0000000..ce5fc13b
--- /dev/null
+++ b/chrome/browser/webauthn/enclave_manager_factory.h
@@ -0,0 +1,30 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_FACTORY_H_
+#define CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+
+class EnclaveManager;
+class Profile;
+
+class EnclaveManagerFactory : public ProfileKeyedServiceFactory {
+ public:
+  static EnclaveManager* GetForProfile(Profile* profile);
+  static EnclaveManagerFactory* GetInstance();
+
+ private:
+  friend base::NoDestructor<EnclaveManagerFactory>;
+
+  EnclaveManagerFactory();
+  ~EnclaveManagerFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
+      content::BrowserContext* context) const override;
+};
+
+#endif  // CHROME_BROWSER_WEBAUTHN_ENCLAVE_MANAGER_FACTORY_H_
diff --git a/chrome/browser/webauthn/enclave_manager_unittest.cc b/chrome/browser/webauthn/enclave_manager_unittest.cc
new file mode 100644
index 0000000..b82ae49
--- /dev/null
+++ b/chrome/browser/webauthn/enclave_manager_unittest.cc
@@ -0,0 +1,436 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webauthn/enclave_manager.h"
+
+#include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/functional/callback.h"
+#include "base/json/json_reader.h"
+#include "base/path_service.h"
+#include "base/process/launch.h"
+#include "base/process/process.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "chrome/browser/webauthn/proto/enclave_local_state.pb.h"
+#include "components/os_crypt/sync/os_crypt_mocker.h"
+#include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
+#include "components/trusted_vault/command_line_switches.h"
+#include "components/trusted_vault/proto/vault.pb.h"
+#include "components/trusted_vault/trusted_vault_server_constants.h"
+#include "device/fido/ctap_get_assertion_request.h"
+#include "device/fido/enclave/constants.h"
+#include "device/fido/enclave/enclave_authenticator.h"
+#include "device/fido/enclave/types.h"
+#include "net/base/port_util.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/test/fake_test_cert_verifier_params_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// The communication with the enclave process would need to be ported to Windows
+// for these tests to run there.
+#if BUILDFLAG(IS_POSIX)
+
+namespace enclave = device::enclave;
+
+namespace {
+
+constexpr std::array<uint8_t, 32> kTestKey = {
+    0xc4, 0xdf, 0xa4, 0xed, 0xfc, 0xf9, 0x7c, 0xc0, 0x3a, 0xb1, 0xcb,
+    0x3c, 0x03, 0x02, 0x9b, 0x5a, 0x05, 0xec, 0x88, 0x48, 0x54, 0x42,
+    0xf1, 0x20, 0xb4, 0x75, 0x01, 0xde, 0x61, 0xf1, 0x39, 0x5d,
+};
+constexpr uint8_t kTestProtobuf[] = {
+    0x0a, 0x10, 0x71, 0xfd, 0xf9, 0x65, 0xa8, 0x7c, 0x61, 0xe2, 0xff, 0x27,
+    0x0c, 0x76, 0x25, 0x23, 0xe0, 0xa4, 0x12, 0x10, 0x77, 0xf2, 0x3c, 0x31,
+    0x3c, 0xe8, 0x94, 0x9a, 0x9f, 0xbc, 0xdf, 0x44, 0xfc, 0xf5, 0x41, 0x97,
+    0x1a, 0x0b, 0x77, 0x65, 0x62, 0x61, 0x75, 0x74, 0x68, 0x6e, 0x2e, 0x69,
+    0x6f, 0x22, 0x06, 0x56, 0x47, 0x56, 0x7a, 0x64, 0x41, 0x2a, 0x10, 0x60,
+    0x07, 0x19, 0x5b, 0x4e, 0x19, 0xf9, 0x6e, 0xc1, 0xfc, 0xfd, 0x0a, 0xf6,
+    0x0c, 0x00, 0x7e, 0x30, 0xf9, 0xa0, 0xea, 0xf3, 0xc8, 0x31, 0x3a, 0x04,
+    0x54, 0x65, 0x73, 0x74, 0x42, 0x04, 0x54, 0x65, 0x73, 0x74, 0x4a, 0xa6,
+    0x01, 0xdc, 0xc5, 0x16, 0x15, 0x91, 0x24, 0xd2, 0x31, 0xfc, 0x85, 0x8b,
+    0xe2, 0xec, 0x22, 0x09, 0x8f, 0x8d, 0x0f, 0xbe, 0x9b, 0x59, 0x71, 0x04,
+    0xcd, 0xaa, 0x3d, 0x32, 0x23, 0xbd, 0x25, 0x46, 0x14, 0x86, 0x9c, 0xfe,
+    0x74, 0xc8, 0xd3, 0x37, 0x70, 0xed, 0xb0, 0x25, 0xd4, 0x1b, 0xdd, 0xa4,
+    0x3c, 0x02, 0x13, 0x8c, 0x69, 0x03, 0xff, 0xd1, 0xb0, 0x72, 0x00, 0x29,
+    0xcf, 0x5f, 0x06, 0xb3, 0x94, 0xe2, 0xea, 0xca, 0x68, 0xdd, 0x0b, 0x07,
+    0x98, 0x7a, 0x2c, 0x8f, 0x08, 0xee, 0x7d, 0xad, 0x16, 0x35, 0xc7, 0x10,
+    0xf3, 0xa4, 0x90, 0x84, 0xd1, 0x8e, 0x2e, 0xdb, 0xb9, 0xfa, 0x72, 0x9a,
+    0xcf, 0x12, 0x1b, 0x3c, 0xca, 0xfa, 0x79, 0x4a, 0x1e, 0x1b, 0xe1, 0x15,
+    0xdf, 0xab, 0xee, 0x75, 0xbb, 0x5c, 0x5a, 0x94, 0x14, 0xeb, 0x72, 0xae,
+    0x37, 0x97, 0x03, 0xa8, 0xe7, 0x62, 0x9d, 0x2e, 0xfd, 0x28, 0xce, 0x03,
+    0x34, 0x20, 0xa7, 0xa2, 0x7b, 0x00, 0xc8, 0x12, 0x62, 0x12, 0x7f, 0x54,
+    0x73, 0x8c, 0x21, 0xc8, 0x85, 0x15, 0xce, 0x36, 0x14, 0xd9, 0x41, 0x22,
+    0xe8, 0xbf, 0x88, 0xf9, 0x45, 0xe4, 0x1c, 0x89, 0x7d, 0xa4, 0x23, 0x58,
+    0x00, 0x68, 0x98, 0xf5, 0x81, 0xef, 0xad, 0xf4, 0xda, 0x17, 0x70, 0xab,
+    0x03,
+};
+
+std::unique_ptr<sync_pb::WebauthnCredentialSpecifics> GetTestEntity() {
+  auto ret = std::make_unique<sync_pb::WebauthnCredentialSpecifics>();
+  CHECK(ret->ParseFromArray(kTestProtobuf, sizeof(kTestProtobuf)));
+  return ret;
+}
+
+struct TempDir {
+ public:
+  TempDir() { CHECK(dir_.CreateUniqueTempDir()); }
+
+  base::FilePath GetPath() const { return dir_.GetPath(); }
+
+ private:
+  base::ScopedTempDir dir_;
+};
+
+std::pair<base::Process, uint16_t> StartEnclave(base::FilePath cwd) {
+  base::FilePath data_root;
+  CHECK(base::PathService::Get(base::DIR_OUT_TEST_DATA_ROOT, &data_root));
+  const base::FilePath enclave_bin_path =
+      data_root.AppendASCII("cloud_authenticator_test_service");
+  base::LaunchOptions subprocess_opts;
+  subprocess_opts.current_directory = cwd;
+
+  std::optional<base::Process> enclave_process;
+  uint16_t port;
+
+  for (int i = 0; i < 10; i++) {
+    int fds[2];
+    CHECK(!pipe(fds));
+    subprocess_opts.fds_to_remap.emplace_back(fds[1], 1);
+    enclave_process = base::LaunchProcess(base::CommandLine(enclave_bin_path),
+                                          subprocess_opts);
+    CHECK(enclave_process->IsValid());
+    close(fds[1]);
+
+    char port_str[6];
+    const ssize_t read_bytes =
+        HANDLE_EINTR(read(fds[0], port_str, sizeof(port_str)));
+    CHECK(read_bytes > 0);
+    port_str[read_bytes - 1] = 0;
+    unsigned u_port;
+    CHECK(base::StringToUint(port_str, &u_port)) << port_str;
+    port = base::checked_cast<uint16_t>(u_port);
+    close(fds[0]);
+
+    if (net::IsPortAllowedForScheme(port, "wss")) {
+      break;
+    }
+    LOG(INFO) << "Port " << port << " not allowed. Trying again.";
+
+    // The kernel randomly picked a port that Chromium will refuse to connect
+    // to. Try again.
+    enclave_process->Terminate(/*exit_code=*/1, /*wait=*/false);
+  }
+
+  return std::make_pair(std::move(*enclave_process), port);
+}
+
+enclave::ScopedEnclaveOverride TestEnclaveIdentity(uint16_t port) {
+  constexpr std::array<uint8_t, device::kP256X962Length> kTestPublicKey = {
+      0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
+      0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
+      0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
+      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
+      0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
+      0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+  };
+  const std::string url = "ws://127.0.0.1:" + base::NumberToString(port);
+  enclave::EnclaveIdentity identity;
+  identity.url = GURL(url);
+  identity.public_key = kTestPublicKey;
+
+  return enclave::ScopedEnclaveOverride(std::move(identity));
+}
+
+trusted_vault_pb::JoinSecurityDomainsResponse MakeJoinSecurityDomainsResponse(
+    int current_epoch) {
+  trusted_vault_pb::JoinSecurityDomainsResponse response;
+  trusted_vault_pb::SecurityDomain* security_domain =
+      response.mutable_security_domain();
+  security_domain->set_name(
+      GetSecurityDomainName(trusted_vault::SecurityDomainId::kPasskeys));
+  security_domain->set_current_epoch(current_epoch);
+  return response;
+}
+
+std::unique_ptr<network::NetworkService> CreateNetwork(
+    mojo::Remote<network::mojom::NetworkContext>* network_context) {
+  network::mojom::NetworkContextParamsPtr params =
+      network::mojom::NetworkContextParams::New();
+  params->cert_verifier_params =
+      network::FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
+
+  auto service = network::NetworkService::CreateForTesting();
+  service->CreateNetworkContext(network_context->BindNewPipeAndPassReceiver(),
+                                std::move(params));
+
+  return service;
+}
+
+class EnclaveManagerTest : public testing::Test, EnclaveManager::Observer {
+ public:
+  EnclaveManagerTest()
+      // `IdentityTestEnvironment` wants to run on an IO thread.
+      : task_env_(base::test::TaskEnvironment::MainThreadType::IO),
+        temp_dir_(),
+        process_and_port_(StartEnclave(temp_dir_.GetPath())),
+        enclave_override_(TestEnclaveIdentity(process_and_port_.second)),
+        network_service_(CreateNetwork(&network_context_)),
+        manager_(temp_dir_.GetPath(),
+                 identity_test_env_.identity_manager(),
+                 network_context_.get(),
+                 url_loader_factory_.GetSafeWeakWrapper()) {
+    OSCryptMocker::SetUp();
+
+    identity_test_env_.MakePrimaryAccountAvailable(
+        "test@gmail.com", signin::ConsentLevel::kSignin);
+    gaia_id_ = identity_test_env_.identity_manager()
+                   ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+                   .gaia;
+    identity_test_env_.SetAutomaticIssueOfAccessTokens(true);
+    manager_.AddObserver(this);
+  }
+
+  ~EnclaveManagerTest() override {
+    if (manager_.RunWhenStoppedForTesting(task_env_.QuitClosure())) {
+      task_env_.RunUntilQuit();
+    }
+    CHECK(process_and_port_.first.Terminate(/*exit_code=*/1, /*wait=*/true));
+    OSCryptMocker::TearDown();
+  }
+
+ protected:
+  void RunUntilIdle() {
+    quit_closure_ = task_env_.QuitClosure();
+    task_env_.RunUntilQuit();
+  }
+
+  base::flat_set<std::string> GaiaAccountsInState() const {
+    const webauthn_pb::EnclaveLocalState& state =
+        manager_.local_state_for_testing();
+    base::flat_set<std::string> ret;
+    for (const auto& it : state.users()) {
+      ret.insert(it.first);
+    }
+    return ret;
+  }
+
+  void OnEnclaveManagerIdle() override {
+    if (manager_.is_idle() && quit_closure_.has_value()) {
+      auto quit_closure = std::move(quit_closure_.value());
+      quit_closure_.reset();
+      quit_closure.Run();
+    }
+  }
+
+  base::test::TaskEnvironment task_env_;
+  std::optional<base::RepeatingClosure> quit_closure_;
+  const TempDir temp_dir_;
+  const std::pair<base::Process, uint16_t> process_and_port_;
+  const enclave::ScopedEnclaveOverride enclave_override_;
+  network::TestURLLoaderFactory url_loader_factory_;
+  mojo::Remote<network::mojom::NetworkContext> network_context_;
+  std::unique_ptr<network::NetworkService> network_service_;
+  signin::IdentityTestEnvironment identity_test_env_;
+  std::string gaia_id_;
+  EnclaveManager manager_;
+};
+
+TEST_F(EnclaveManagerTest, TestInfrastructure) {
+  // Tests that the enclave starts up.
+}
+
+TEST_F(EnclaveManagerTest, Basic) {
+  ASSERT_FALSE(manager_.is_loaded());
+  ASSERT_FALSE(manager_.is_registered());
+  ASSERT_FALSE(manager_.is_ready());
+
+  manager_.Start();
+  ASSERT_FALSE(manager_.is_idle());
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_idle());
+  ASSERT_TRUE(manager_.is_loaded());
+  ASSERT_FALSE(manager_.is_registered());
+  ASSERT_FALSE(manager_.is_ready());
+
+  manager_.RegisterIfNeeded();
+  ASSERT_FALSE(manager_.is_idle());
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_idle());
+  ASSERT_TRUE(manager_.is_loaded());
+  ASSERT_TRUE(manager_.is_registered());
+  ASSERT_FALSE(manager_.is_ready());
+
+  url_loader_factory_.AddResponse(
+      GetFullJoinSecurityDomainsURLForTesting(
+          trusted_vault::ExtractTrustedVaultServiceURLFromCommandLine(),
+          trusted_vault::SecurityDomainId::kPasskeys)
+          .spec(),
+      MakeJoinSecurityDomainsResponse(/*current_epoch=*/1).SerializeAsString());
+  std::vector<uint8_t> key(kTestKey.begin(), kTestKey.end());
+  manager_.StoreKeys(gaia_id_, {std::move(key)}, /*last_key_version=*/417);
+  ASSERT_FALSE(manager_.is_idle());
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_idle());
+  ASSERT_TRUE(manager_.is_loaded());
+  ASSERT_TRUE(manager_.is_registered());
+  ASSERT_TRUE(manager_.is_ready());
+
+  auto ui_request = std::make_unique<enclave::CredentialRequest>();
+  ui_request->signing_callback = manager_.HardwareKeySigningCallback();
+  ui_request->wrapped_keys = {*manager_.GetWrappedKey(/*version=*/417)};
+  ui_request->entity = GetTestEntity();
+
+  enclave::EnclaveAuthenticator authenticator(
+      std::move(ui_request), /*save_passkey_callback=*/
+      base::BindRepeating(
+          [](sync_pb::WebauthnCredentialSpecifics) { NOTREACHED(); }),
+      network_context_.get());
+  device::CtapGetAssertionRequest ctap_request("test.com", R"({"foo": "bar"})");
+  ctap_request.allow_list.emplace_back(device::PublicKeyCredentialDescriptor(
+      device::CredentialType::kPublicKey, /*id=*/{1, 2, 3, 4}));
+
+  const base::StringPiece json_request_str =
+      R"({
+           "allowCredentials": [ ],
+           "challenge": "CYO8B30gOPIOVFAaU61J7PvoETG_sCZQ38Gzpu",
+           "rpId": "webauthn.io",
+           "userVerification": "preferred"
+         })";
+  base::Value json_request = base::JSONReader::Read(json_request_str).value();
+  device::CtapGetAssertionOptions ctap_options;
+  ctap_options.json =
+      base::MakeRefCounted<device::JSONRequest>(std::move(json_request));
+
+  auto quit_closure = task_env_.QuitClosure();
+  device::CtapDeviceResponseCode status;
+  std::vector<device::AuthenticatorGetAssertionResponse> responses;
+  authenticator.GetAssertion(
+      std::move(ctap_request), std::move(ctap_options),
+      base::BindLambdaForTesting(
+          [&quit_closure, &status, &responses](
+              device::CtapDeviceResponseCode in_status,
+              std::vector<device::AuthenticatorGetAssertionResponse>
+                  in_responses) {
+            status = in_status;
+            responses = std::move(in_responses);
+            quit_closure.Run();
+          }));
+  task_env_.RunUntilQuit();
+
+  ASSERT_EQ(status, device::CtapDeviceResponseCode::kSuccess);
+  ASSERT_EQ(responses.size(), 1u);
+}
+
+TEST_F(EnclaveManagerTest, SecretsArriveBeforeRegistration) {
+  manager_.Start();
+  manager_.RegisterIfNeeded();
+  ASSERT_FALSE(manager_.is_registered());
+
+  // Provide the domain secrets before the registration has completed. The
+  // system should still end up in the correct state.
+  url_loader_factory_.AddResponse(
+      GetFullJoinSecurityDomainsURLForTesting(
+          trusted_vault::ExtractTrustedVaultServiceURLFromCommandLine(),
+          trusted_vault::SecurityDomainId::kPasskeys)
+          .spec(),
+      MakeJoinSecurityDomainsResponse(/*current_epoch=*/1).SerializeAsString());
+  std::vector<uint8_t> key(kTestKey.begin(), kTestKey.end());
+  manager_.StoreKeys(gaia_id_, {std::move(key)}, /*last_key_version=*/417);
+  RunUntilIdle();
+
+  ASSERT_TRUE(manager_.is_idle());
+  ASSERT_TRUE(manager_.is_loaded());
+  ASSERT_TRUE(manager_.is_registered());
+  ASSERT_TRUE(manager_.is_ready());
+}
+
+TEST_F(EnclaveManagerTest, RegistrationFailureAndRetry) {
+  const std::string gaia =
+      identity_test_env_.identity_manager()
+          ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+          .gaia;
+
+  // Override the enclave with port=100, which will cause connection failures.
+  {
+    device::enclave::ScopedEnclaveOverride override(
+        TestEnclaveIdentity(/*port=*/100));
+    manager_.Start();
+    manager_.RegisterIfNeeded();
+    RunUntilIdle();
+  }
+  ASSERT_FALSE(manager_.is_registered());
+  const std::string public_key = manager_.local_state_for_testing()
+                                     .users()
+                                     .find(gaia)
+                                     ->second.hardware_public_key();
+  ASSERT_FALSE(public_key.empty());
+
+  manager_.RegisterIfNeeded();
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_registered());
+
+  // The public key should not have changed because re-registration attempts
+  // must try the same public key again in case they actually worked the first
+  // time.
+  ASSERT_TRUE(public_key == manager_.local_state_for_testing()
+                                .users()
+                                .find(gaia)
+                                ->second.hardware_public_key());
+}
+
+TEST_F(EnclaveManagerTest, PrimaryUserChange) {
+  const std::string gaia1 =
+      identity_test_env_.identity_manager()
+          ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+          .gaia;
+
+  manager_.Start();
+  manager_.RegisterIfNeeded();
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_registered());
+  EXPECT_THAT(GaiaAccountsInState(), testing::UnorderedElementsAre(gaia1));
+
+  identity_test_env_.MakePrimaryAccountAvailable("test2@gmail.com",
+                                                 signin::ConsentLevel::kSignin);
+  const std::string gaia2 =
+      identity_test_env_.identity_manager()
+          ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+          .gaia;
+  ASSERT_FALSE(manager_.is_registered());
+  manager_.RegisterIfNeeded();
+  RunUntilIdle();
+  ASSERT_TRUE(manager_.is_registered());
+  EXPECT_THAT(GaiaAccountsInState(),
+              testing::UnorderedElementsAre(gaia1, gaia2));
+
+  // Remove all accounts from the cookie jar. The primary account should be
+  // retained.
+  identity_test_env_.SetCookieAccounts({});
+  EXPECT_THAT(GaiaAccountsInState(), testing::UnorderedElementsAre(gaia2));
+
+  // When the primary account changes, the second account should be dropped
+  // because it was removed from the cookie jar.
+  identity_test_env_.MakePrimaryAccountAvailable("test3@gmail.com",
+                                                 signin::ConsentLevel::kSignin);
+  const std::string gaia3 =
+      identity_test_env_.identity_manager()
+          ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
+          .gaia;
+  EXPECT_THAT(GaiaAccountsInState(), testing::UnorderedElementsAre(gaia3));
+}
+
+}  // namespace
+
+#endif  // IS_POSIX
diff --git a/chrome/browser/webauthn/proto/BUILD.gn b/chrome/browser/webauthn/proto/BUILD.gn
new file mode 100644
index 0000000..e815f42
--- /dev/null
+++ b/chrome/browser/webauthn/proto/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/protobuf/proto_library.gni")
+
+proto_library("proto") {
+  sources = [ "enclave_local_state.proto" ]
+
+  extra_configs = [ "//build/config/compiler:wexit_time_destructors" ]
+}
diff --git a/chrome/browser/webauthn/proto/enclave_local_state.proto b/chrome/browser/webauthn/proto/enclave_local_state.proto
new file mode 100644
index 0000000..f425119f
--- /dev/null
+++ b/chrome/browser/webauthn/proto/enclave_local_state.proto
@@ -0,0 +1,53 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto3";
+
+option optimize_for = LITE_RUNTIME;
+
+package webauthn_pb;
+
+message EnclaveLocalState {
+  // User contains state for a specific GAIA ID.
+  message User {
+    // The hardware-bound, not-user-verification-interlocked device key:
+    //
+    // These three members are either all empty or all non-empty.
+    bytes wrapped_hardware_private_key = 1;
+    // If non-empty, this contains a valid SubjectPublicKeyInfo.
+    bytes hardware_public_key = 2;
+    // This is currently SHA-256(hardware_public_key) but need not be.
+    bytes device_id = 5;
+
+    // The hardware-bound, user-verification-interlocked device key.
+    // (This is optional and might not be present if the device doesn't
+    // support UV-interlocked keys.)
+    //
+    // These two members are either both empty or both non-empty.
+    bytes wrapped_uv_private_key = 3;
+    bytes uv_public_key = 4;
+
+    // Whether this device has been registered with the enclave. If this is
+    // true then `hardware_public_key` and `member_public_key` must be
+    // non-empty.
+    bool registered = 6;
+
+    // The enclave-wrapped, security domain physical member key.
+    //
+    // These two members are either both empty or both non-empty.
+    bytes wrapped_member_private_key = 7;
+    // If non-empty, contains a P-256 point in uncompressed X9.62 format.
+    bytes member_public_key = 8;
+
+    // Whether this device has joined the hw_protected security domain. If this
+    // is true then `wrapped_security_domain_secrets` must be non-empty.
+    bool joined = 9;
+
+    // A map from security domain epoch to the enclave-wrapped security domain
+    // secret for that epoch.
+    map<int32, bytes> wrapped_security_domain_secrets = 10;
+  }
+
+  map<string, User> users = 1;
+}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 2bf7a86..9177bad7 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -8095,6 +8095,7 @@
         "../browser/webauthn/authenticator_request_scheduler_unittest.cc",
         "../browser/webauthn/cablev2_devices_unittest.cc",
         "../browser/webauthn/chrome_authenticator_request_delegate_unittest.cc",
+        "../browser/webauthn/enclave_manager_unittest.cc",
         "../common/importer/mock_importer_bridge.cc",
         "../common/importer/mock_importer_bridge.h",
         "../renderer/media/webrtc_logging_agent_impl_unittest.cc",
@@ -8304,6 +8305,7 @@
         "//chrome/browser/ui/webui/side_panel/performance_controls:mojo_bindings",
         "//chrome/browser/ui/webui/side_panel/user_notes:mojo_bindings",
         "//chrome/browser/web_applications:web_applications_test_support",
+        "//chrome/browser/webauthn/proto",
         "//components/app_constants",
         "//components/color",
         "//components/commerce/core:cart_db_content_proto",
@@ -8361,6 +8363,12 @@
 
       data += [ "//ash/components/arc/test/data/icons/" ]
 
+      data_deps += [
+        # enclave_manager_unittest.cc runs this binary as part of its testing
+        # process.
+        "//third_party/cloud_authenticator/test/local_service:cloud_authenticator_test_service",
+      ]
+
       if (include_js2gtest_tests && is_chromeos_ash) {
         data += js2gtest_js_libraries
         deps += [
diff --git a/device/fido/enclave/enclave_websocket_client.cc b/device/fido/enclave/enclave_websocket_client.cc
index ff6316a..7485af2 100644
--- a/device/fido/enclave/enclave_websocket_client.cc
+++ b/device/fido/enclave/enclave_websocket_client.cc
@@ -279,10 +279,13 @@
 }
 
 void EnclaveWebSocketClient::ProcessCompletedResponse() {
-  on_response_.Run(SocketStatus::kOk, pending_read_data_);
+  std::vector<uint8_t> pending_read_data;
+  pending_read_data.swap(pending_read_data_);
   pending_read_data_index_ = 0;
   pending_read_finished_ = false;
-  pending_read_data_.clear();
+
+  on_response_.Run(SocketStatus::kOk, std::move(pending_read_data));
+  // `this` may have been deleted at this point.
 }
 
 void EnclaveWebSocketClient::ClosePipe(SocketStatus status) {
@@ -296,6 +299,7 @@
   pending_read_finished_ = false;
   pending_read_data_.clear();
   on_response_.Run(status, std::vector<uint8_t>());
+  // `this` may have been deleted at this point.
 }
 
 void EnclaveWebSocketClient::OnMojoPipeDisconnect() {
