# PersonalData

Crypto-shredding for personal data. The log is append-only, so the personal fields of an event are encrypted with a key that belongs to the person they describe, the subject. Forgetting a subject destroys that key: the events stay where they are and keep their amounts, dates and ids, while their personal fields read as the replacement each field declares.

```ts
const AccountEvent = Schema.TaggedUnion({
  AccountOpened: {
    owner: PersonalData.field(Schema.String, { redacted: "[forgotten]" }),
    currency: Schema.Literals(["CHF", "EUR"])
  },
  TransferSent: {
    to: Schema.String,
    // Encrypted with the key of the receiver rather than the account holder.
    beneficiary: PersonalData.field(Schema.String, { redacted: "[forgotten]", subject: "to" }),
    amount: Schema.Number
  }
})
```

A field belongs to the aggregate id of its stream unless it names a sibling property that holds its subject. Schemas stay plain: encryption happens where `AggregateService` writes and reads the store, which then needs [Keys](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys).

Each subject has its own data key. The key store keeps it only wrapped by a [MasterKey](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey), which can live in a KMS, so the master key can change without touching events. [forget](https://effect-cqrs.dambox.ch/reference/api/personaldata/#forget-1) destroys the data key, refuses keys for that subject from then on and records the request in the log.

Encryption is AES-256-GCM through a [Cipher](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher-1): WebCrypto by default, which also runs in browsers, or `node:crypto` from `PersonalDataNode`.

## Classes

### Keys

Defined in: [src/PersonalData.ts:455](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L455)

The data keys of subjects, created on first use and cached for a while.

#### Extends

* `Shape`<`"effect-cqrs/PersonalData/Keys"`, { `cipher`: [`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher); `decryptionKey`(`subject`, `keyId`): `Effect`<`Option`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `encryptionKey`(`subject`): `Effect`<[`DataKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#datakey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>; `forget`(`subject`): `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `isForgotten`(`subject`): `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `rewrap`(`options?`): `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, `this`>

#### Constructors

##### Constructor

> **new Keys**(`_`): [`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys)

Defined in: node_modules/.pnpm/effect\@4.0.6/node_modules/effect/dist/Context.d.ts:121

###### Parameters

###### \_

`never`

###### Returns

[`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys)

###### Inherited from

Context.Service\<Keys, { /\*\* What encrypts and decrypts with the keys. \*/ readonly cipher: Cipher /\*\* The key to encrypt with, created when the subject has none. Fails for a forgotten subject. \*/ encryptionKey(subject: string): Effect.Effect\<DataKey, SubjectForgotten | PersonalDataError> /\*\* \* The key to decrypt with, \`None\` when the subject was forgotten. A subject \* without any key fails: losing the key store must not pass for forgetting. \*/ decryptionKey(subject: string, keyId: string): Effect.Effect\<Option.Option\<CipherKey>, PersonalDataError> isForgotten(subject: string): Effect.Effect\<boolean, PersonalDataError> /\*\* Destroys the key of a subject. Prefer {@link forget}, which also records it in the log. \*/ forget(subject: string): Effect.Effect\<void, PersonalDataError> /\*\* See {@link rewrap}. \*/ rewrap(options?: RewrapOptions): Effect.Effect\<RewrapResult, PersonalDataError> }>()(“effect-cqrs/PersonalData/Keys”).constructor

***

### MasterKey

Defined in: [src/PersonalData.ts:376](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L376)

Wraps the data keys of subjects, so the key store only ever holds them encrypted. Implement it on top of a KMS to keep the master key out of the process, or use [layerMasterKey](https://effect-cqrs.dambox.ch/reference/api/personaldata/#layermasterkey) with a key from configuration.

#### Extends

* `Shape`<`"effect-cqrs/PersonalData/MasterKey"`, { `keyId`: `string`; `unwrap`(`wrapped`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `wrap`(`dataKey`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, `this`>

#### Constructors

##### Constructor

> **new MasterKey**(`_`): [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)

Defined in: node_modules/.pnpm/effect\@4.0.6/node_modules/effect/dist/Context.d.ts:121

###### Parameters

###### \_

`never`

###### Returns

[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)

###### Inherited from

``Context.Service<MasterKey, { /** The key new data keys are wrapped with. */ readonly keyId: string wrap( dataKey: Uint8Array<ArrayBuffer>, context: { readonly subject: string; readonly keyId: string } ): Effect.Effect<Uint8Array<ArrayBuffer>, PersonalDataError> /** Unwraps a key wrapped by `masterKeyId`, which may be an earlier master key. */ unwrap( wrapped: Uint8Array<ArrayBuffer>, context: { readonly subject: string; readonly keyId: string; readonly masterKeyId: string } ): Effect.Effect<Uint8Array<ArrayBuffer>, PersonalDataError> }>()("effect-cqrs/PersonalData/MasterKey").constructor``

***

### PersonalDataError

Defined in: [src/PersonalData.ts:68](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L68)

A key that couldn’t be read, created or used, or a field that didn’t decrypt.

#### Extends

* `object` & `YieldableError`<`this`>

#### Constructors

##### Constructor

> **new PersonalDataError**(…`args`): [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)

Defined in: node_modules/.pnpm/effect\@4.0.6/node_modules/effect/dist/Schema.d.ts:10979

###### Parameters

###### args

…\[`props`: `object`, `options?`: `MakeOptions`]

###### Returns

[`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)

###### Inherited from

`Schema.TaggedError<PersonalDataError>()("PersonalDataError", { operation: Schema.String, subject: Schema.String, message: Schema.String, cause: Schema.optional(Schema.Defect()) }).constructor`

#### Properties

##### cause?

> `optional` **cause?**: `unknown`

Defined in: [src/PersonalData.ts:72](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L72)

###### Inherited from

`Schema.TaggedError<PersonalDataError>()("PersonalDataError", { operation: Schema.String, subject: Schema.String, message: Schema.String, cause: Schema.optional(Schema.Defect()) }).cause`

##### message

> **message**: `string` = `Schema.String`

Defined in: [src/PersonalData.ts:71](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L71)

###### Inherited from

`Schema.TaggedError<PersonalDataError>()("PersonalDataError", { operation: Schema.String, subject: Schema.String, message: Schema.String, cause: Schema.optional(Schema.Defect()) }).message`

##### operation

> `readonly` **operation**: `string` = `Schema.String`

Defined in: [src/PersonalData.ts:69](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L69)

###### Inherited from

`Schema.TaggedError<PersonalDataError>()("PersonalDataError", { operation: Schema.String, subject: Schema.String, message: Schema.String, cause: Schema.optional(Schema.Defect()) }).operation`

##### subject

> `readonly` **subject**: `string` = `Schema.String`

Defined in: [src/PersonalData.ts:70](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L70)

###### Inherited from

`Schema.TaggedError<PersonalDataError>()("PersonalDataError", { operation: Schema.String, subject: Schema.String, message: Schema.String, cause: Schema.optional(Schema.Defect()) }).subject`

***

### SubjectForgotten

Defined in: [src/PersonalData.ts:63](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L63)

#### Extends

* `object` & `YieldableError`<`this`>

#### Constructors

##### Constructor

> **new SubjectForgotten**(…`args`): [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)

Defined in: node_modules/.pnpm/effect\@4.0.6/node_modules/effect/dist/Schema.d.ts:10979

###### Parameters

###### args

…\[`props`: `object`, `options?`: `MakeOptions`]

###### Returns

[`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)

###### Inherited from

`Schema.TaggedError<SubjectForgotten>()("SubjectForgotten", { subject: Schema.String }).constructor`

#### Properties

##### subject

> `readonly` **subject**: `string` = `Schema.String`

Defined in: [src/PersonalData.ts:64](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L64)

###### Inherited from

`Schema.TaggedError<SubjectForgotten>()("SubjectForgotten", { subject: Schema.String }).subject`

## Interfaces

### Backend

Defined in: [src/PersonalData.ts:402](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L402)

Where keys are kept. Keep it apart from the events, with backups that expire.

#### Properties

##### afterCommit?

> `readonly` `optional` **afterCommit?**: <`R`>(`effect`) => `Effect`<`void`, `never`, `R`>

Defined in: [src/PersonalData.ts:420](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L420)

Runs an effect when the caller’s transaction commits, or at once outside one.

###### Type Parameters

###### R

`R`

###### Parameters

###### effect

`Effect`<`void`, `never`, `R`>

###### Returns

`Effect`<`void`, `never`, `R`>

##### create

> `readonly` **create**: (`subject`, `key`) => `Effect`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:408](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L408)

Stores a key unless the subject already has a record, and returns the record the subject has afterwards: a racing writer’s key, or `Forgotten`.

###### Parameters

###### subject

`string`

###### key

###### \_tag

`"Active"`

###### keyId

`string`

###### masterKeyId

`string`

###### wrapped

`Uint8Array`<`ArrayBuffer`>

The data key, wrapped by the master key.

###### Returns

`Effect`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

##### forget

> `readonly` **forget**: (`subject`, `forgottenAt`) => `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:413](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L413)

Deletes the key and records that the subject is forgotten, in one step.

###### Parameters

###### subject

`string`

###### forgottenAt

`number`

###### Returns

`Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

##### get

> `readonly` **get**: (`subject`) => `Effect`<`Option`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:403](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L403)

###### Parameters

###### subject

`string`

###### Returns

`Effect`<`Option`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

##### inTransaction?

> `readonly` `optional` **inTransaction?**: `Effect`<`boolean`, `never`, `never`>

Defined in: [src/PersonalData.ts:418](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L418)

Whether a call now joins a transaction of the caller, whose writes a rollback can still undo. What is read or created there is cached only once it commits.

##### replaceWrapped?

> `readonly` `optional` **replaceWrapped?**: (`subject`, `from`, `to`) => `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:440](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L440)

Stores a key wrapped anew, if the subject still has the key `from`: not forgotten, nor wrapped again meanwhile. Returns whether it did.

###### Parameters

###### subject

`string`

###### from

###### keyId

`string`

###### masterKeyId

`string`

###### to

###### masterKeyId

`string`

###### wrapped

`Uint8Array`<`ArrayBuffer`>

###### Returns

`Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

##### wrappedByOthers?

> `readonly` `optional` **wrappedByOthers?**: (`masterKeyId`, `afterSubject`, `limit`) => `Effect`\<readonly `object`\[], [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:426](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L426)

Up to `limit` subjects after `afterSubject`, in order, whose key is wrapped by another master key than `masterKeyId`. With [Backend.replaceWrapped](https://effect-cqrs.dambox.ch/reference/api/personaldata/#backend), what [rewrap](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrap) needs.

###### Parameters

###### masterKeyId

`string`

###### afterSubject

`string`

###### limit

`number`

###### Returns

`Effect`\<readonly `object`\[], [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

***

### Cipher

Defined in: [src/PersonalData.ts:296](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L296)

AES-256-GCM, which encrypts personal fields and wraps data keys. What it produces is a random IV of [ivLength](https://effect-cqrs.dambox.ch/reference/api/personaldata/#ivlength) bytes, the ciphertext and a tag of [tagLength](https://effect-cqrs.dambox.ch/reference/api/personaldata/#taglength) bytes, so data written by one implementation reads with any other.

The default, [webCrypto](https://effect-cqrs.dambox.ch/reference/api/personaldata/#webcrypto), works in Node and in browsers but is asynchronous. `PersonalDataNode.layerCipher` runs on `node:crypto` synchronously, which costs a fraction per field.

#### Properties

##### asynchronous

> `readonly` **asynchronous**: `boolean`

Defined in: [src/PersonalData.ts:301](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L301)

Whether an operation waits on something outside the fiber, as WebCrypto does. Events of a stream then decrypt several at a time.

#### Methods

##### decrypt()

> **decrypt**(`key`, `sealed`, `additionalData`): `Effect`<`Uint8Array`<`ArrayBuffer`>, `UnknownError`>

Defined in: [src/PersonalData.ts:310](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L310)

Fails when the data was altered, or belongs to another key or other additional data.

###### Parameters

###### key

[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)

###### sealed

`Uint8Array`<`ArrayBuffer`>

###### additionalData

`Uint8Array`<`ArrayBuffer`>

###### Returns

`Effect`<`Uint8Array`<`ArrayBuffer`>, `UnknownError`>

##### encrypt()

> **encrypt**(`key`, `plaintext`, `additionalData`): `Effect`<`Uint8Array`<`ArrayBuffer`>, `UnknownError`>

Defined in: [src/PersonalData.ts:304](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L304)

###### Parameters

###### key

[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)

###### plaintext

`Uint8Array`<`ArrayBuffer`>

###### additionalData

`Uint8Array`<`ArrayBuffer`>

###### Returns

`Effect`<`Uint8Array`<`ArrayBuffer`>, `UnknownError`>

##### importKey()

> **importKey**(`bytes`): `Effect`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey), `UnknownError`>

Defined in: [src/PersonalData.ts:303](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L303)

Imports a key of 32 bytes. The caller zeroes the bytes afterwards.

###### Parameters

###### bytes

`Uint8Array`<`ArrayBuffer`>

###### Returns

`Effect`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey), `UnknownError`>

***

### CipherKey

Defined in: [src/PersonalData.ts:282](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L282)

A key imported by a [Cipher](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher-1), which only that cipher can use.

#### Properties

##### \[CipherKeyTypeId]

> `readonly` **\[CipherKeyTypeId]**: *typeof* `CipherKeyTypeId`

Defined in: [src/PersonalData.ts:283](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L283)

***

### DataKey

Defined in: [src/PersonalData.ts:449](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L449)

#### Properties

##### key

> `readonly` **key**: [`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)

Defined in: [src/PersonalData.ts:451](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L451)

##### keyId

> `readonly` **keyId**: `string`

Defined in: [src/PersonalData.ts:450](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L450)

***

### Field

Defined in: [src/PersonalData.ts:113](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L113)

Where a personal field sits in an encoded payload, and how to find its subject.

#### Properties

##### path

> `readonly` **path**: readonly `string`\[]

Defined in: [src/PersonalData.ts:114](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L114)

##### redacted

> `readonly` **redacted**: `Json`

Defined in: [src/PersonalData.ts:117](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L117)

##### subject

> `readonly` **subject**: `string` | `undefined`

Defined in: [src/PersonalData.ts:116](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L116)

The sibling property holding the subject, or `undefined` for the aggregate id.

***

### KeysOptions

Defined in: [src/PersonalData.ts:482](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L482)

#### Properties

##### cacheSize?

> `readonly` `optional` **cacheSize?**: `number`

Defined in: [src/PersonalData.ts:484](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L484)

How many subjects to keep in memory, with their unwrapped keys. Defaults to 10,000.

##### cacheTtl?

> `readonly` `optional` **cacheTtl?**: `Input`

Defined in: [src/PersonalData.ts:490](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L490)

How long what the store said about a subject is used before it is asked again. It bounds how long another process keeps using the key of a subject forgotten here. Defaults to one minute.

***

### Location

Defined in: [src/PersonalData.ts:1087](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1087)

Where a payload is stored, which the ciphertext of its fields is bound to.

#### Properties

##### aggregateId

> `readonly` **aggregateId**: `string`

Defined in: [src/PersonalData.ts:1089](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1089)

##### aggregateName

> `readonly` **aggregateName**: `string`

Defined in: [src/PersonalData.ts:1088](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1088)

##### type

> `readonly` **type**: `string`

Defined in: [src/PersonalData.ts:1090](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1090)

***

### RewrapOptions

Defined in: [src/PersonalData.ts:472](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L472)

#### Properties

##### batchSize?

> `readonly` `optional` **batchSize?**: `number`

Defined in: [src/PersonalData.ts:474](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L474)

How many keys are read from the store at a time. Defaults to 100.

***

### RewrapResult

Defined in: [src/PersonalData.ts:477](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L477)

#### Properties

##### rewrapped

> `readonly` **rewrapped**: `number`

Defined in: [src/PersonalData.ts:479](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L479)

The keys now wrapped by the current master key.

***

### SqlOptions

Defined in: [src/PersonalData.ts:864](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L864)

#### Properties

##### migrate?

> `readonly` `optional` **migrate?**: `boolean`

Defined in: [src/PersonalData.ts:871](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L871)

Creates the table on startup when it doesn’t exist. Defaults to `true`. Turn it off to run [migrations](https://effect-cqrs.dambox.ch/reference/api/personaldata/#migrations) with your own tooling instead.

##### table?

> `readonly` `optional` **table?**: `string`

Defined in: [src/PersonalData.ts:866](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L866)

Defaults to `cqrs_personal_data_keys`.

***

### WithSubjects

Defined in: [src/PersonalData.ts:1174](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1174)

A payload, with the subjects whose personal data it holds.

#### Properties

##### payload

> `readonly` **payload**: `Json`

Defined in: [src/PersonalData.ts:1175](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1175)

##### subjects

> `readonly` **subjects**: readonly `string`\[]

Defined in: [src/PersonalData.ts:1176](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1176)

## Type Aliases

### KeyRecord

> **KeyRecord** = { `_tag`: `"Active"`; `keyId`: `string`; `masterKeyId`: `string`; `wrapped`: `Uint8Array`<`ArrayBuffer`>; } | { `_tag`: `"Forgotten"`; `forgottenAt`: `number`; }

Defined in: [src/PersonalData.ts:391](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L391)

What the key store holds for a subject.

#### Union Members

##### Type Literal

{ `_tag`: `"Active"`; `keyId`: `string`; `masterKeyId`: `string`; `wrapped`: `Uint8Array`<`ArrayBuffer`>; }

###### \_tag

> `readonly` **\_tag**: `"Active"`

###### keyId

> `readonly` **keyId**: `string`

###### masterKeyId

> `readonly` **masterKeyId**: `string`

###### wrapped

> `readonly` **wrapped**: `Uint8Array`<`ArrayBuffer`>

The data key, wrapped by the master key.

***

##### Type Literal

{ `_tag`: `"Forgotten"`; `forgottenAt`: `number`; }

***

### Sealed

> **Sealed** = *typeof* `Sealed.Type`

Defined in: [src/PersonalData.ts:1247](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1247)

Text encrypted once with the key of each subject, so destroying any one of the keys makes it unreadable.

## Variables

### Cipher

> **Cipher**: `Reference`<[`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher)>

Defined in: [src/PersonalData.ts:296](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L296)

The cipher that keys, master keys and fields use, [webCrypto](https://effect-cqrs.dambox.ch/reference/api/personaldata/#webcrypto) unless another is provided.

***

### forget

> `const` **forget**: (…`args`) => `Effect`<`void`, [`EventStoreError`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#eventstoreerror) | [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), [`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys) | [`EventStore`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#eventstore)>

Defined in: [src/PersonalData.ts:1045](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1045)

Forgets a subject: destroys its key, so its personal fields read as their replacements everywhere, and records a `SubjectForgotten` event in the stream of the subject, with the current causation and metadata as the audit trail. Running it again records nothing new.

The key goes first, so that no event says a subject is forgotten while its key still exists. A store that can’t be reached is tried a few more times; when it still fails, the subject is forgotten but the event is missing, and `onForget` handlers haven’t run. Call `forget` again until it succeeds.

Other processes stop using the key once their cache expires, see [KeysOptions.cacheTtl](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keysoptions).

#### Parameters

##### args

…\[`subject`: `string`]

#### Returns

`Effect`<`void`, [`EventStoreError`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#eventstoreerror) | [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), [`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys) | [`EventStore`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#eventstore)>

***

### ivLength

> `const` **ivLength**: `12` = `12`

Defined in: [src/PersonalData.ts:317](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L317)

***

### keyLength

> `const` **keyLength**: `32` = `32`

Defined in: [src/PersonalData.ts:319](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L319)

***

### layerMasterKeyEphemeral

> `const` **layerMasterKeyEphemeral**: `Layer.Layer`<[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

Defined in: [src/PersonalData.ts:642](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L642)

A random master key that lasts as long as the layer. Keys it wrapped can’t be read by another process or after a restart, so it suits tests and demos.

***

### make

> `const` **make**: (…`args`) => `Effect`<{ `cipher`: [`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher); `decryptionKey`(`subject`, `keyId`): `Effect`<`Option`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `encryptionKey`(`subject`): `Effect`<[`DataKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#datakey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>; `forget`(`subject`): `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `isForgotten`(`subject`): `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `rewrap`(`options?`): `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, `never`, [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

Defined in: [src/PersonalData.ts:664](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L664)

Builds [Keys](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys) on a key store. Reads of the store are cached per subject, and concurrent misses for one subject share a single read, unwrap and, for a new subject, a single key creation.

#### Parameters

##### args

…\[`backend`: [`Backend`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#backend), `options?`: [`KeysOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keysoptions)]

#### Returns

`Effect`<{ `cipher`: [`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher); `decryptionKey`(`subject`, `keyId`): `Effect`<`Option`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `encryptionKey`(`subject`): `Effect`<[`DataKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#datakey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>; `forget`(`subject`): `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `isForgotten`(`subject`): `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `rewrap`(`options?`): `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, `never`, [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

***

### makeMasterKey

> `const` **makeMasterKey**: (…`args`) => `Effect`<{ `keyId`: `string`; `unwrap`(`wrapped`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `wrap`(`dataKey`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>

Defined in: [src/PersonalData.ts:543](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L543)

A master key held by the process, given as 32 bytes. Keys wrapped by earlier master keys stay readable while those are listed in `previous`. The bytes are copied, so the caller can zero its own.

#### Parameters

##### args

…\[`options`: `object`]

#### Returns

`Effect`<{ `keyId`: `string`; `unwrap`(`wrapped`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; `wrap`(`dataKey`, `context`): `Effect`<`Uint8Array`<`ArrayBuffer`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>

***

### makeSqlBackend

> `const` **makeSqlBackend**: (…`args`) => `Effect`<{ `afterCommit`: <`R`>(`effect`) => `Effect`<`void`, `never`, `R`>; `create`: (`subject`, `key`) => `Effect`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `forget`: (`subject`, `forgottenAt`) => `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `get`: (`subject`) => `Effect`<`Option`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `inTransaction`: `Effect`<`boolean`, `never`, `never`>; `replaceWrapped`: (`subject`, `from`, `to`) => `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `wrappedByOthers`: (`masterKeyId`, `afterSubject`, `limit`) => `Effect`<`object`\[], [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `SqlClient`>

Defined in: [src/PersonalData.ts:918](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L918)

A key store in a SQL table, on SQLite or PostgreSQL. The table is created on startup unless `migrate` is `false`. Provide it a client of its own to keep keys in another database than the events, with other permissions and backups.

Forgetting overwrites the row. The database may keep the old bytes for a while, in free pages, dead rows or its write-ahead log, and backups keep them as long as they are kept: let backups of this table expire.

#### Parameters

##### args

…\[`options?`: [`SqlOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#sqloptions)]

#### Returns

`Effect`<{ `afterCommit`: <`R`>(`effect`) => `Effect`<`void`, `never`, `R`>; `create`: (`subject`, `key`) => `Effect`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `forget`: (`subject`, `forgottenAt`) => `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `get`: (`subject`) => `Effect`<`Option`<[`KeyRecord`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keyrecord)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `inTransaction`: `Effect`<`boolean`, `never`, `never`>; `replaceWrapped`: (`subject`, `from`, `to`) => `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; `wrappedByOthers`: (`masterKeyId`, `afterSubject`, `limit`) => `Effect`<`object`\[], [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `SqlClient`>

***

### openText

> `const` **openText**: (…`args`) => `Effect`<`Option`<`string`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>

Defined in: [src/PersonalData.ts:1271](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1271)

Opens text from [sealText](https://effect-cqrs.dambox.ch/reference/api/personaldata/#sealtext), `None` when one of its subjects was forgotten.

#### Parameters

##### args

…\[`keys`: `object`, `sealed`: `object`, `purpose`: `string`]

#### Returns

`Effect`<`Option`<`string`>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `never`>

***

### Sealed

> `const` **Sealed**: `Struct`<{ `data`: `String`; `subjects`: `$Array`<`Struct`<{ `keyId`: `String`; `subject`: `String`; }>>; }>

Defined in: [src/PersonalData.ts:1247](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1247)

Text encrypted once with the key of each subject, so destroying any one of the keys makes it unreadable.

***

### sealText

> `const` **sealText**: (…`args`) => `Effect`<{ `data`: `string`; `subjects`: `object`\[]; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten), `never`>

Defined in: [src/PersonalData.ts:1254](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1254)

Seals text such as a snapshot of a state that holds the personal data of `subjects`.

#### Parameters

##### args

…\[`keys`: `object`, `subjects`: readonly `string`\[], `text`: `string`, `purpose`: `string`]

#### Returns

`Effect`<{ `data`: `string`; `subjects`: `object`\[]; }, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten), `never`>

***

### streamName

> `const` **streamName**: `"effect-cqrs/personal-data"` = `"effect-cqrs/personal-data"`

Defined in: [src/PersonalData.ts:1026](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1026)

The stream that records forgotten subjects, one stream per subject.

***

### subjectForgottenType

> `const` **subjectForgottenType**: `"SubjectForgotten"` = `"SubjectForgotten"`

Defined in: [src/PersonalData.ts:1029](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1029)

The type of the event [forget](https://effect-cqrs.dambox.ch/reference/api/personaldata/#forget-1) records. Its payload is empty.

***

### tagLength

> `const` **tagLength**: `16` = `16`

Defined in: [src/PersonalData.ts:318](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L318)

***

### webCrypto

> `const` **webCrypto**: [`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher)

Defined in: [src/PersonalData.ts:329](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L329)

AES-256-GCM on WebCrypto.

## Functions

### field()

> **field**<`S`>(`schema`, `options`): `S`

Defined in: [src/PersonalData.ts:95](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L95)

Marks a field as personal data. `redacted` is what the field reads as once its subject is forgotten, and has to be a valid value of the field. `subject` names a property next to the field that holds the id of the person it describes, by default the aggregate id of the stream.

#### Type Parameters

##### S

`S` *extends* `PlainSchema`

#### Parameters

##### schema

`S`

##### options

###### redacted

`S`\[`"Type"`]

###### subject?

`string`

#### Returns

`S`

***

### fieldsByTag()

> **fieldsByTag**(`schema`, `where`): `ReadonlyMap`<`string`, readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]>

Defined in: [src/PersonalData.ts:259](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L259)

The personal fields of each event in a union of tagged events. Events without any are left out.

#### Parameters

##### schema

`Top`

##### where

`string`

#### Returns

`ReadonlyMap`<`string`, readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]>

***

### fieldsOf()

> **fieldsOf**(`schema`, `where`): readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]

Defined in: [src/PersonalData.ts:252](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L252)

The personal fields of one schema, such as an old version of an event.

#### Parameters

##### schema

`Top`

##### where

`string`

#### Returns

readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]

***

### layerMasterKey()

> **layerMasterKey**(`options`): `Layer`<[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:587](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L587)

#### Parameters

##### options

###### key

`Redacted`<`Uint8Array`<`ArrayBufferLike`>>

###### keyId

`string`

###### previous?

readonly `object`\[]

#### Returns

`Layer`<[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

***

### layerMasterKeyConfig()

> **layerMasterKeyConfig**(`options?`): `Layer`<[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | `ConfigError`>

Defined in: [src/PersonalData.ts:600](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L600)

A master key from configuration: an id, and 32 bytes in base64. By default `PERSONAL_DATA_MASTER_KEY_ID` and `PERSONAL_DATA_MASTER_KEY`.

Earlier master keys, which keys created before a rotation are still wrapped by, come from `PERSONAL_DATA_MASTER_KEY_PREVIOUS` by default, as `id:base64` pairs separated by commas. Leave it unset when there are none, and empty it once [rewrap](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrap) has moved every key to the current master key.

#### Parameters

##### options?

###### key?

`Config`<`Redacted`<`string`>>

###### keyId?

`Config`<`string`>

###### previous?

`Config`<`Redacted`<`string`>>

#### Returns

`Layer`<[`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | `ConfigError`>

***

### layerMemory()

> **layerMemory**(`options?`): `Layer`<[`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys), `never`, [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

Defined in: [src/PersonalData.ts:861](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L861)

Keys kept in process memory, for tests and demos.

#### Parameters

##### options?

[`KeysOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keysoptions)

#### Returns

`Layer`<[`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys), `never`, [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

***

### layerSql()

> **layerSql**(`options?`): `Layer`<[`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `SqlClient` | [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

Defined in: [src/PersonalData.ts:1007](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1007)

Keys in a SQL table, see [makeSqlBackend](https://effect-cqrs.dambox.ch/reference/api/personaldata/#makesqlbackend).

#### Parameters

##### options?

[`SqlOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#sqloptions) & [`KeysOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keysoptions)

#### Returns

`Layer`<[`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), `SqlClient` | [`MasterKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#masterkey)>

***

### makeMemoryBackend()

> **makeMemoryBackend**(): [`Backend`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#backend)

Defined in: [src/PersonalData.ts:823](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L823)

A key store in process memory, gone after a restart along with access to everything it encrypted.

#### Returns

[`Backend`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#backend)

***

### migrations()

> **migrations**(`options?`): readonly [`Migration`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#migration)\[]

Defined in: [src/PersonalData.ts:883](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L883)

The migrations of the key table of [makeSqlBackend](https://effect-cqrs.dambox.ch/reference/api/personaldata/#makesqlbackend), the same on SQLite and PostgreSQL, for teams that run migrations themselves. They are safe to run again.

#### Parameters

##### options?

###### table?

`string`

#### Returns

readonly [`Migration`](https://effect-cqrs.dambox.ch/reference/api/eventstore/#migration)\[]

***

### open()

> **open**(`keys`, `fields`, `location`, `payload`): `Effect`<[`WithSubjects`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#withsubjects), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Defined in: [src/PersonalData.ts:1186](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1186)

Decrypts the personal fields of a stored payload, putting the replacement in place of the fields of forgotten subjects. A field stored in plaintext, from before it was marked personal, is left as it is. A field has to be encrypted for the subject it would be sealed for now: the aggregate id, or the sibling it names.

#### Parameters

##### keys

###### cipher

[`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher)

What encrypts and decrypts with the keys.

###### decryptionKey

(`subject`, `keyId`) => `Effect`<`Option`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

The key to decrypt with, `None` when the subject was forgotten. A subject without any key fails: losing the key store must not pass for forgetting.

###### encryptionKey

(`subject`) => `Effect`<[`DataKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#datakey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>

The key to encrypt with, created when the subject has none. Fails for a forgotten subject.

###### forget

(`subject`) => `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Destroys the key of a subject. Prefer [forget](https://effect-cqrs.dambox.ch/reference/api/personaldata/#forget-1), which also records it in the log.

###### isForgotten

(`subject`) => `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

###### rewrap

(`options?`) => `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

See [rewrap](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrap).

##### fields

readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]

##### location

[`Location`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#location)

##### payload

`Json`

#### Returns

`Effect`<[`WithSubjects`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#withsubjects), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

***

### rewrap()

> **rewrap**(`options?`): `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), [`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys)>

Defined in: [src/PersonalData.ts:1022](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1022)

Wraps every subject key that an earlier master key wrapped with the current one, so the earlier one can be dropped from `previous`. Keys stay the same, so nothing encrypted with them changes, and running it again only rewraps what is left. Keys created meanwhile are wrapped by the current master key already.

#### Parameters

##### options?

[`RewrapOptions`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapoptions)

#### Returns

`Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror), [`Keys`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#keys)>

***

### seal()

> **seal**(`keys`, `fields`, `location`, `payload`): `Effect`<[`WithSubjects`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#withsubjects), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>

Defined in: [src/PersonalData.ts:1127](https://github.com/davidnussio/effect-cqrs/blob/9d66af7141782f3f89655e6868abe3f141c97632/src/PersonalData.ts#L1127)

Encrypts the personal fields of an encoded payload. Fields without a value are left alone. `aggregateId` is the subject of fields that don’t name one. Returns the subjects whose keys were used.

#### Parameters

##### keys

###### cipher

[`Cipher`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipher)

What encrypts and decrypts with the keys.

###### decryptionKey

(`subject`, `keyId`) => `Effect`<`Option`<[`CipherKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#cipherkey)>, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

The key to decrypt with, `None` when the subject was forgotten. A subject without any key fails: losing the key store must not pass for forgetting.

###### encryptionKey

(`subject`) => `Effect`<[`DataKey`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#datakey), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>

The key to encrypt with, created when the subject has none. Fails for a forgotten subject.

###### forget

(`subject`) => `Effect`<`void`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

Destroys the key of a subject. Prefer [forget](https://effect-cqrs.dambox.ch/reference/api/personaldata/#forget-1), which also records it in the log.

###### isForgotten

(`subject`) => `Effect`<`boolean`, [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

###### rewrap

(`options?`) => `Effect`<[`RewrapResult`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrapresult), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror)>

See [rewrap](https://effect-cqrs.dambox.ch/reference/api/personaldata/#rewrap).

##### fields

readonly [`Field`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#field)\[]

##### location

`Omit`<[`Location`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#location), `"aggregateId"`> & `object`

##### payload

`Json`

#### Returns

`Effect`<[`WithSubjects`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#withsubjects), [`PersonalDataError`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#personaldataerror) | [`SubjectForgotten`](https://effect-cqrs.dambox.ch/reference/api/personaldata/#subjectforgotten)>
