Skip to main content

SealedField

@webda/core


Class: SealedField<T>

Defined in: packages/core/src/models/sealed.model.ts:84

A model field sealed end-to-end to a user public key

The server writes the value with the recipient public key (ECDH-ES P-256 + HKDF-SHA-256 + AES-256-GCM, see src/sealed/) and can never read it: there is no get()/open() here, only the recipient devices open it with their private key. The stored data is the envelope { v, kid, epk, iv, ct }, a public output, bound by the AAD modelType|uuid|field|kid to its record, attribute and recipient key.

A client opens it with openValue(envelope, recipient, fieldAad(modelType, uuid, field, envelope.kid)) where:

  • modelType is the model identifier (useModelId(model), e.g. "Webda/Note")
  • uuid is String(model.getPrimaryKey()) (composite keys are joined with the model separator, _ by default)
  • field is the attribute name (e.g. "content")
  • kid is the envelope kid

The recipient is seal(value, { user }), else the model getSealedRecipient(field) (the owner for an OwnerModel), else the model getOwner().

A client can also seal the value itself (KeyVault.seal) and store the envelope with the set action (<Model>.<Field>.Set, PUT <model>/{uuid}/<field>.set), authorised by the model canAct("<field>.set"): the server checks the envelope shape and that it is sealed to the recipient active key, it cannot check the content.

class Note extends OwnerModel {
content: SealedField<{ title: string; body: string }>;
}
await note.content.seal({ title, body }); // sealed to the owner
await note.save();

The size of a client-sealed envelope is capped by SealedFieldParameters.maxSize (1 MiB by default), configured per attribute: models.<Model>.behaviors.<attribute>.maxSize.

Webda Behavior​

Webda/Sealed

Type Parameters​

T​

T = any

Constructors​

Constructor​

new SealedField<T>(): SealedField<T>

Returns​

SealedField<T>

Properties​

ct?​

optional ct?: string

Defined in: packages/core/src/models/sealed.model.ts:99

AES-GCM ciphertext, base64url


epk?​

optional epk?: JsonWebKey

Defined in: packages/core/src/models/sealed.model.ts:95

Ephemeral public key


iv?​

optional iv?: string

Defined in: packages/core/src/models/sealed.model.ts:97

AES-GCM IV, base64url


kid?​

optional kid?: string

Defined in: packages/core/src/models/sealed.model.ts:93

Recipient key id


v?​

optional v?: 1

Defined in: packages/core/src/models/sealed.model.ts:91

Envelope version


Parameters​

static Parameters: typeof SealedFieldParameters = SealedFieldParameters

Defined in: packages/core/src/models/sealed.model.ts:88

Parameters

Methods​

clear()​

clear(): void

Defined in: packages/core/src/models/sealed.model.ts:247

Remove the stored value (does not save the model)

Returns​

void


getParameters()​

getParameters(): SealedFieldParameters

Defined in: packages/core/src/models/sealed.model.ts:175

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

Returns​

SealedFieldParameters

the parameters


getParent()​

protected getParent(): object

Defined in: packages/core/src/models/sealed.model.ts:270

Get the model holding this field and its attribute name

Returns​

object

the model holding this field and its attribute name

attribute​

attribute: string

instance​

instance: any

Throws​

Error when the field is not attached to a model


isSet()​

isSet(): boolean

Defined in: packages/core/src/models/sealed.model.ts:105

Check whether set

Returns​

boolean

true when a complete envelope is stored


seal()​

seal(value, opts?): Promise<void>

Defined in: packages/core/src/models/sealed.model.ts:128

Seal a value to the recipient public key and store the envelope (does not save the model)

The plaintext is never kept on the instance.

Parameters​

value​

T

JSON-serialisable value

opts?​

sealing options

user?​

string

recipient user id, instead of the model default

Returns​

Promise<void>

Throws​

SealedKeyMissingError when the recipient is unknown or has no public key

Throws​

SealedFormatError when the recipient public key is malformed

Throws​

BadRequest when the model has no primary key yet


set()​

set(envelope): Promise<void>

Defined in: packages/core/src/models/sealed.model.ts:159

Store an envelope sealed by a client (KeyVault.seal) and save this field only (a patch of the attribute)

Exposed as <Model>.<Field>.Set, authorised by the model canAct("<field>.set"). The envelope must be well formed, at most SealedFieldParameters.maxSize ciphertext characters, and sealed to the active key of the recipient (resolved as for SealedField.seal); the server cannot check that it opens, the AAD the client used (modelType|uuid|field|kid) is only verified by the recipient.

Parameters​

envelope​

SealedEnvelope

sealed envelope { v: 1, kid, epk, iv, ct }

Returns​

Promise<void>

Throws​

SealedFormatError when the envelope is malformed, too large or not sealed to the recipient active key

Throws​

SealedKeyMissingError when the recipient is unknown or has no public key


toJSON()​

toJSON(): SealedEnvelope | Partial<SealedEnvelope>

Defined in: packages/core/src/models/sealed.model.ts:256

Serialize this instance to a JSON-compatible value

Returns​

SealedEnvelope | Partial<SealedEnvelope>

the envelope, undefined when no field is stored, the partial fields as-is when the envelope is incomplete (corrupted data is kept, not silently dropped)


checkEnvelope()​

protected static checkEnvelope(envelope, maxSize): Promise<SealedEnvelope>

Defined in: packages/core/src/models/sealed.model.ts:189

Check the shape of a client envelope

Parameters​

envelope​

unknown

submitted envelope

maxSize​

number

upper bound of the ciphertext, base64url characters

Returns​

Promise<SealedEnvelope>

the normalised envelope

Throws​

SealedFormatError when it is malformed or too large


defaultRecipient()​

protected static defaultRecipient(instance, attribute): Promise<string>

Defined in: packages/core/src/models/sealed.model.ts:300

Default recipient: the model getSealedRecipient(field), else its owner

Parameters​

instance​

any

model holding the field

attribute​

string

field name

Returns​

Promise<string>

the recipient user id


modelIdOf()​

protected static modelIdOf(instance, attribute): string

Defined in: packages/core/src/models/sealed.model.ts:236

Return the model identifier, part of the AAD

Parameters​

instance​

any

model holding the field

attribute​

string

field name

Returns​

string

the model identifier, part of the AAD


primaryKeyOf()​

protected static primaryKeyOf(instance): string

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

Primary key of the record for the AAD

Parameters​

instance​

any

model holding the field

Returns​

string

String(getPrimaryKey())

Throws​

BadRequest when the key, or a part of a composite key, is not assigned


recipientKey()​

protected static recipientKey(instance, attribute, user?): Promise<{ key: PublicKeyEntry; userId: string; }>

Defined in: packages/core/src/models/sealed.model.ts:214

Recipient of the field and its active public key

Parameters​

instance​

any

model holding the field

attribute​

string

field name

user?​

string

explicit recipient user id

Returns​

Promise<{ key: PublicKeyEntry; userId: string; }>

the recipient id and active key

Throws​

SealedKeyMissingError when the recipient is unknown or has no public key