Skip to content

Keychain

Defined in: packages/core/src/keychain.ts:104

A keychain contains a PeerborneDocument’s encryption keys.

Keys are identified by a fixed-width binary key ID. Both provisioning paths (add(), which generates random per-key identifiers, and addEpochKey(), which installs BeeKEM-derived epoch IDs from deriveEpochIdFromRootSecret) use the SAME byte width — 32 bytes in the shipped Yjs / Automerge providers, surfaced via KeychainProvider.keyIDLength. The matching width means the wire-format encrypted-block key-ID prefix is a single fixed size for any key the keychain has installed, regardless of how it was provisioned: there is no truncation step, and getKey() never has to disambiguate between key-ID encodings.

KeychainChange

Type of a block of change(s) describing edits made to the document keychain.

DocumentKey

Type of a document encryption key.

add(): Promise<[Uint8Array<ArrayBufferLike>, DocumentKey, KeychainChange]>

Defined in: packages/core/src/keychain.ts:110

Generates and adds a new document encryption key to the keychain.

Promise<[Uint8Array<ArrayBufferLike>, DocumentKey, KeychainChange]>

The new document key ID, key, and a block of change(s) describing the keychain addition.


addEpochKey(epochId, key): Promise<KeychainChange>

Defined in: packages/core/src/keychain.ts:200

Add an encryption key for a specific epoch. The epoch ID is the full HKDF output from deriveEpochIdFromRootSecret — the KeychainProvider.keyIDLength-wide identifier (32 bytes in the shipped providers) that also becomes the wire-format key-ID prefix on subsequent encrypted blocks. No truncation: the byte width is uniform across provisioning, storage, and the wire.

Uint8Array

The epoch ID, exactly KeychainProvider.keyIDLength bytes wide. Implementations MUST reject a mismatched width instead of truncating or padding it. The shipped providers require exactly 32 bytes and store those validated bytes verbatim.

DocumentKey

The encryption key for this epoch.

Promise<KeychainChange>

A block of change(s) describing the keychain addition.


current(): Promise<[Uint8Array<ArrayBufferLike>, DocumentKey]>

Defined in: packages/core/src/keychain.ts:152

Gets the current encryption key that should be used to encrypt new changes.

Promise<[Uint8Array<ArrayBufferLike>, DocumentKey]>


currentKeyChange(): Promise<KeychainChange>

Defined in: packages/core/src/keychain.ts:183

Gets a block of change(s) describing only the current (most recent) key. Used for current_only key distribution where new members receive the current encryption key, not the full key history. This does not itself redact retained CRDT operations encrypted during that epoch.

The returned value MUST be safe to regenerate and replay without creating a second logical keychain entry, and byte-stable for the same logical key tuple across repeated calls, restored instances, and equivalent replicas. Implementations may synthesize a standalone projection only with stable, content-derived CRDT operation identity; otherwise they MUST reject. A one-key keychain MUST export its live history so receivers share the author’s lineage and can merge the author’s next add() delta. Receivers of a projected later key hold an independent lineage and cannot merge rotation deltas authored on the full history.

Promise<KeychainChange>

A replay-safe block of change(s) containing only the current key.


getKey(keyID): DocumentKey | undefined

Defined in: packages/core/src/keychain.ts:163

Looks up a document key by its ID.

Uint8Array

An identifier for a document key. Provider implementations define the width via KeychainProvider.keyIDLength and both provisioning paths (add() and addEpochKey()) emit IDs of that exact width.

DocumentKey | undefined

The requested document key.


history(): KeychainChange

Defined in: packages/core/src/keychain.ts:126

Gets a block of change(s) describing the whole state of the keychain.

KeychainChange

A block of change(s) describing the keychain.


historySince(keyID): Promise<KeychainChange>

Defined in: packages/core/src/keychain.ts:275

Gets a block of change(s) describing only the keys at or after the given key ID. Used for the since_invited history visibility mode where a new member receives every key from the moment they were invited onward, but no earlier epoch keys. It does not itself redact retained CRDT operations.

The returned value MUST be safe to regenerate and replay: repeated calls for the same boundary and keychain state must not create fresh CRDT actor/client operations that duplicate keys or change the visible window. Implementations MUST reject when their CRDT cannot project the requested suffix from stable existing operation history without including keys before the boundary. In particular, an unknown, stale, or attacker-controlled keyID MUST reject unless the implementation can derive a replay-safe current-key-only change from existing operation history. Returning full history would disclose every pre-invitation epoch.

Uint8Array

The key ID marking the start of the visible window.

Promise<KeychainChange>

A block of change(s) containing only keys at or after keyID.


keys(): Promise<[Uint8Array<ArrayBufferLike>, DocumentKey][]>

Defined in: packages/core/src/keychain.ts:147

Gets the all document encryption keys in the keychain.

Promise<[Uint8Array<ArrayBufferLike>, DocumentKey][]>

all document encryption keys.


merge(change): void

Defined in: packages/core/src/keychain.ts:140

Merges in a block of change(s) to the keychain.

KeychainChange

A block of change(s) to apply.

void


prepareAppend(change, intent): PreparedKeychainMerge<KeychainChange, DocumentKey>

Defined in: packages/core/src/keychain.ts:251

Stage an authenticated, predecessor-bound standalone key append. This is distinct from prepareMerge() because append authority must be validated explicitly. Implementations MUST require a canonical one-key projection matching expectedNewKeyId. They may append only when the live current key matches expectedPreviousKeyId, or return an unchanged exact replay when the live sequence already ends with the expected previous/new pair and material.

KeychainChange

KeychainAppendIntent

PreparedKeychainMerge<KeychainChange, DocumentKey>


prepareEpochKey(epochId, key): Promise<PreparedKeychainEpoch<KeychainChange>>

Defined in: packages/core/src/keychain.ts:226

Stage an epoch-key insertion without mutating live keychain state. BeeKEM membership transitions finish all fallible signing, sealing, serialization, and block preparation before a synchronous keychain/tree commit.

commit() MUST either apply the staged state completely or throw before mutation. It is called at most once, after every asynchronous preparation step has succeeded.

Core transaction wrappers inspect both this capability and the returned claimCommit capability without invoking accessors. Implement them as ordinary prototype methods or own data-property functions.

The epochId width contract is identical to addEpochKey(): it must equal KeychainProvider.keyIDLength, exactly 32 bytes in the shipped providers, and a mismatch must be rejected before any state is staged or mutated. The current BeeKEM wire protocols derive and authenticate fixed 32-byte epoch IDs, so a custom provider with another key-ID width cannot implement those transitions.

Uint8Array

The full-width epoch identifier.

DocumentKey

The encryption key for this epoch.

Promise<PreparedKeychainEpoch<KeychainChange>>


prepareKey(): Promise<PreparedKeychainAddition<KeychainChange, DocumentKey>>

Defined in: packages/core/src/keychain.ts:117

Stage generation and insertion of a random document key without mutating live state. Callers can finish fallible wire preparation before invoking the synchronous commit.

Promise<PreparedKeychainAddition<KeychainChange, DocumentKey>>


prepareMerge(change): PreparedKeychainMerge<KeychainChange, DocumentKey>

Defined in: packages/core/src/keychain.ts:238

Stage a remote keychain merge for an atomic Welcome state commit. Core transaction wrappers inspect this capability and the prepared hydrateKeys, getKey, and claimCommit capabilities without invoking accessors. Implement them as ordinary prototype methods or own data-property functions.

KeychainChange

PreparedKeychainMerge<KeychainChange, DocumentKey>


stateCommitment(): Promise<Uint8Array<ArrayBufferLike>>

Defined in: packages/core/src/keychain.ts:133

Commit to the validated ordered logical key sequence independently of provider-specific CRDT operation identities. Implementations MUST use computeKeychainStateCommitment.

Promise<Uint8Array<ArrayBufferLike>>