Skip to content

Browser: wrap relocated kernel identity secrets with a non-extractable CryptoKey #1037

Description

@sirtimid

Follow-on to #989, which relocates the kernel's identity secrets out of the kv store — on the browser, into IndexedDB, still plaintext. This issue wraps them.

Why the browser needs more than relocation

#989's relocation closes the kernel's own debug surface on both platforms: executeDBQuery (kernel-browser-runtime/src/kernel-worker/middleware/panel-message.ts:23) and getKVData (kernel-store/src/types.ts:23) reach the kernel DB, not IndexedDB.

It does not improve the position of a same-origin attacker, because anything that can read OPFS can read IndexedDB. On Node the equivalent gap is covered by unix modes on a 0600 file; a browser has no such thing.

What a browser does have is a non-extractable CryptoKey: generate with extractable: false, store the CryptoKey object itself in IndexedDB (structured clone preserves non-extractability), and use it to wrap the secrets. The key material then cannot be exported even by code running in the origin. That is a platform-enforced boundary rather than encryption-with-the-key-nearby, and it has no Node equivalent short of a TPM or HSM.

Deliberately not proposed for Node: an envelope wrapped by a machine-local KEK. With no separate trust anchor it is the same boundary as the 0600 file against a same-user process, and the disk-read case it covers is already covered better by full-disk encryption. Discussion on #989.

Scope

  • A keystore capability in @metamask/kernel-platforms, browser implementation, mirroring the existing fs capability layout (capabilities/fs/{types,shared,nodejs,browser}.ts, registry at capabilities/index.ts:9-19).
  • Wrap/unwrap over the secrets Kernel identity and ocap-URL keys are stored in the queryable kernel store #989 relocated, behind that issue's key-provider interface.
  • Envelope header carries a format version and, if a passphrase option is added later, the KDF id and parameters — so parameters can be raised without invalidating existing envelopes.
  • The kernel worker and the offscreen document are the same origin, so one shared keystore database with named entries. After Kernel identity and ocap-URL keys are stored in the queryable kernel store #989's proposal 3 the identity key is resolved in the offscreen document while the ocap-URL key stays in the worker.

Constraints carried over from #989

  • Non-extractability must be asserted in a testcrypto.subtle.exportKey on the retrieved key must reject. The whole guarantee rests on it and a regression to extractable: true would otherwise be invisible.
  • Distinguish first run from lost envelope via an initialization marker stored beside the KEK. OPFS can be unavailable, in which case the DB is ephemeral (kernel-store/src/sqlite/wasm.ts:39) and a persisted KEK with a vanished envelope looks exactly like a first run. On lost-envelope, fail loudly — never mint a fresh identity, which would silently change the peer ID and break every issued ocap URL.
  • Peer ID stability across extension reload and clearState, under test.

Follows: #989.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions