Skip to main content

UserKeys

@webda/core


Class: UserKeys

Defined in: packages/core/src/models/userkeys.model.ts:271

End-to-end encryption keys of a user (User.keys): public keys in clear, the encrypted keyring holding every private key and its escrows, and the devices holding the keyring

The private keys never reach the server in clear: the keyring (PKCS#8 keys by kid) is encrypted on the client with a random keyring key, itself wrapped by KEKs the server never sees (escrows: Argon2id/PBKDF2 of the password or of a recovery code; devices: WebAuthn PRF, OS keystore or passcode, kept locally). See src/sealed/ for the formats.

Actions, exposed as User.Keys.<Action>, are authorised by the owner canAct(context, "keys.<action>") (the user only, for User). __keyring and __escrows are server-only: getEscrow is the only way out of an escrow, to the owner, throttled on the owner attempts _escrowAttempts/_lastEscrowAttemptAt and audited by the operation events (Webda.OperationSuccess/Webda.OperationFailure). Opening an escrow happens on the client, so a fetch cannot be known to have succeeded: every fetch counts and nothing resets the counter, the lockout decays after escrowLockout. getKeyring serves the encrypted keyring alone, unthrottled: it opens nothing without the keyring key.

Every action requires a recent authentication (session authAt younger than reauthMaxAge) and, when the user has MFA enabled, a verified MFA login (session mfa: "verified").

Only the keys attribute is written (a patch): a whole-document save would overwrite the attempts counter incremented concurrently by getEscrow.

Webda Behavior​

Webda/UserKeys

Constructors​

Constructor​

new UserKeys(data?): UserKeys

Defined in: packages/core/src/models/userkeys.model.ts:289

Parameters​

data?​

any

initial or stored data

Returns​

UserKeys

Properties​

__escrows?​

optional __escrows?: Escrows

Defined in: packages/core/src/models/userkeys.model.ts:281

Escrows of the keyring key by kind, server-only


__keyring?​

optional __keyring?: KeyringBlob

Defined in: packages/core/src/models/userkeys.model.ts:278

Encrypted keyring, server-only


devices​

devices: UserDevice[] = []

Defined in: packages/core/src/models/userkeys.model.ts:284

Devices holding the keyring (metadata only)


publicKeys​

publicKeys: UserPublicKey[] = []

Defined in: packages/core/src/models/userkeys.model.ts:275

Public keys, oldest first: the newest non-retired one is active


Parameters​

static Parameters: typeof UserKeysParameters = UserKeysParameters

Defined in: packages/core/src/models/userkeys.model.ts:272

Methods​

getActivePublicKey()​

getActivePublicKey(): PublicKeyEntry

Defined in: packages/core/src/models/userkeys.model.ts:301

Active public key, the recipient of new sealed values

Returns​

PublicKeyEntry

the newest non-retired key, undefined before setup


getEscrow()​

getEscrow(kind): Promise<{ escrow: EscrowBlob; keyring: KeyringBlob; publicKeys: UserPublicKey[]; }>

Defined in: packages/core/src/models/userkeys.model.ts:404

Fetch an escrow to open the keyring on a new device. Throttled: every fetch counts until a device registers

Parameters​

kind​

"password" | "recovery"

escrow kind

Returns​

Promise<{ escrow: EscrowBlob; keyring: KeyringBlob; publicKeys: UserPublicKey[]; }>

the escrow, the encrypted keyring and the public keys to check it against


getKeyring()​

getKeyring(): Promise<{ keyring: KeyringBlob; publicKeys: UserPublicKey[]; }>

Defined in: packages/core/src/models/userkeys.model.ts:434

Fetch the encrypted keyring, for a device holding the keyring key whose local copy is stale (a rotation by another device). Not throttled: without the keyring key (kept on the devices and in the escrows) it opens nothing

Returns​

Promise<{ keyring: KeyringBlob; publicKeys: UserPublicKey[]; }>

the encrypted keyring and the public keys to check it against


getOwner()​

protected getOwner(): any

Defined in: packages/core/src/models/userkeys.model.ts:328

Owning model (set by behavior hydration)

Returns​

any

the owner or undefined when detached


getParameters()​

getParameters(): UserKeysParameters

Defined in: packages/core/src/models/userkeys.model.ts:317

Resolve the policy of this attribute; a detached behavior uses defaults

Returns​

UserKeysParameters

the parameters


isSetup()​

isSetup(): boolean

Defined in: packages/core/src/models/userkeys.model.ts:309

Returns​

boolean

true once the keys are set up


registerDevice()​

registerDevice(name): Promise<{ id: string; }>

Defined in: packages/core/src/models/userkeys.model.ts:506

Register a device that opened the keyring (at most MAX_DEVICES, 409 beyond)

Parameters​

name​

string

device name

Returns​

Promise<{ id: string; }>

the device id


removeEscrow()​

removeEscrow(kind): Promise<void>

Defined in: packages/core/src/models/userkeys.model.ts:458

Remove an escrow; the last one cannot be removed while no device holds the keyring (409)

Parameters​

kind​

"password" | "recovery"

escrow kind

Returns​

Promise<void>


revokeDevice()​

revokeDevice(id): Promise<void>

Defined in: packages/core/src/models/userkeys.model.ts:527

Forget a device (its local blob stays usable until the keyring key is rotated); the last device cannot go while no escrow exists (409)

Parameters​

id​

string

device id

Returns​

Promise<void>


rotate()​

rotate(publicKey, keyring, escrows?): Promise<void>

Defined in: packages/core/src/models/userkeys.model.ts:481

Add a new active public key and retire the previous one; the keyring is re-encrypted for it. The escrows are replaced when given (new keyring key), kept otherwise

Parameters​

publicKey​

UserPublicKeyInput

new public key { kid, jwk }

keyring​

KeyringBlob

keyring holding every private key, encrypted for the new key

escrows?​

Escrows

escrows of a new keyring key

Returns​

Promise<void>


setEscrow()​

setEscrow(kind, escrow): Promise<void>

Defined in: packages/core/src/models/userkeys.model.ts:446

Create or replace an escrow, from a device holding the keyring key

Parameters​

kind​

"password" | "recovery"

escrow kind

escrow​

EscrowBlob

escrow blob of this kind

Returns​

Promise<void>


setup()​

setup(publicKey, keyring, escrows): Promise<void>

Defined in: packages/core/src/models/userkeys.model.ts:386

First enrollment: the first public key, its keyring and at least one escrow (409 when already set up)

Parameters​

publicKey​

UserPublicKeyInput

public key { kid, jwk }

keyring​

KeyringBlob

keyring encrypted for this key

escrows​

Escrows

escrows of the keyring key by kind

Returns​

Promise<void>