@coffre/core 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/kek.js CHANGED
@@ -67,7 +67,7 @@ var LocalKekProvider = class LocalKekProvider {
67
67
  keyVersion;
68
68
  #kek;
69
69
  constructor(kek, keyId, keyVersion = "1") {
70
- if (kek.length !== KEK_BYTES) throw new Error(`local KEK must be ${KEK_BYTES} bytes, got ${kek.length}`);
70
+ if (kek.length !== KEK_BYTES) throw new Error(`a local vault key must be ${KEK_BYTES} bytes, got ${kek.length}`);
71
71
  this.#kek = kek;
72
72
  this.keyId = keyId;
73
73
  this.keyVersion = keyVersion;
@@ -159,7 +159,7 @@ var KekRegistry = class {
159
159
  this.#primary = primary;
160
160
  for (const provider of [primary, ...additional]) {
161
161
  const ref = refOf(provider.provider, provider.keyId);
162
- if (this.#byRef.has(ref)) throw new Error(`duplicate KEK in registry: ${ref}`);
162
+ if (this.#byRef.has(ref)) throw new Error(`duplicate vault key in registry: ${ref}`);
163
163
  this.#byRef.set(ref, provider);
164
164
  }
165
165
  }
@@ -182,7 +182,7 @@ var KekRegistry = class {
182
182
  unwrap(wrapped, ctx, operation) {
183
183
  const ref = refOf(wrapped.kekProvider, wrapped.kekId);
184
184
  const provider = this.#byRef.get(ref);
185
- if (!provider) throw new Error(`no KEK configured for ${ref}; cannot unwrap`);
185
+ if (!provider) throw new Error(`no vault key configured for ${ref} (kek or previousKeks in the vault's config); cannot unwrap`);
186
186
  return provider.unwrap(wrapped, ctx, operation);
187
187
  }
188
188
  };
package/dist/vault.d.ts CHANGED
@@ -146,11 +146,13 @@ export interface Vault {
146
146
  checkpoint: Checkpoint;
147
147
  }>>;
148
148
  /**
149
- * What only the vault's configuration says, which the app shows: the key
150
- * its checkpoints verify under, and the root admins, as principals.
149
+ * What the vault's configuration says, which the app shows: the keys its
150
+ * checkpoints verify under, by the key id each checkpoint names (the one
151
+ * it signs with now, and those of the KEKs it replaced), and the root
152
+ * admins, as principals.
151
153
  */
152
154
  about(): Promise<{
153
- publicKey: string;
155
+ checkpointKeys: Record<string, CheckpointKey>;
154
156
  rootAdmins: string[];
155
157
  }>;
156
158
  /**
@@ -341,6 +343,16 @@ export type Checkpoint = {
341
343
  /** Ed25519 over `checkpointMessage(...)`, base64. */
342
344
  signature: string;
343
345
  };
346
+ /**
347
+ * A public key the vault's checkpoints verify under, base64. One it
348
+ * replaced vouches only for checkpoints whose prefix ends before `until`,
349
+ * its first entry under the key that replaced it; the one it signs with now
350
+ * has none.
351
+ */
352
+ export type CheckpointKey = {
353
+ publicKey: string;
354
+ until: number | null;
355
+ };
344
356
  /** An entry of the vault's log, and so the chain up to it. */
345
357
  export type LogHead = {
346
358
  seq: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffre/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "What coffre's packages share: roles, envelopes, identity, the audit chain and the vault's contract.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -68,7 +68,7 @@
68
68
  "@types/node": "26.1.1",
69
69
  "tsdown": "0.23.0",
70
70
  "typescript": "5.9.3",
71
- "@coffre/conformance": "0.1.1"
71
+ "@coffre/conformance": "0.1.3"
72
72
  },
73
73
  "scripts": {
74
74
  "build": "tsdown",
package/src/kek/local.ts CHANGED
@@ -25,7 +25,7 @@ export class LocalKekProvider implements KekProvider {
25
25
 
26
26
  constructor(kek: Buffer, keyId: string, keyVersion: string = '1') {
27
27
  if (kek.length !== KEK_BYTES) {
28
- throw new Error(`local KEK must be ${KEK_BYTES} bytes, got ${kek.length}`);
28
+ throw new Error(`a local vault key must be ${KEK_BYTES} bytes, got ${kek.length}`);
29
29
  }
30
30
  this.#kek = kek;
31
31
  this.keyId = keyId;
@@ -23,7 +23,7 @@ export class KekRegistry {
23
23
  for (const provider of [primary, ...additional]) {
24
24
  const ref = refOf(provider.provider, provider.keyId);
25
25
  if (this.#byRef.has(ref)) {
26
- throw new Error(`duplicate KEK in registry: ${ref}`);
26
+ throw new Error(`duplicate vault key in registry: ${ref}`);
27
27
  }
28
28
  this.#byRef.set(ref, provider);
29
29
  }
@@ -56,7 +56,7 @@ export class KekRegistry {
56
56
  // Operationally this means a KEK was removed from configuration while
57
57
  // rows still reference it. Fail loudly rather than returning a decrypt
58
58
  // error that looks like corruption.
59
- throw new Error(`no KEK configured for ${ref}; cannot unwrap`);
59
+ throw new Error(`no vault key configured for ${ref} (kek or previousKeks in the vault's config); cannot unwrap`);
60
60
  }
61
61
  return provider.unwrap(wrapped, ctx, operation);
62
62
  }
package/src/vault.ts CHANGED
@@ -64,10 +64,12 @@ export interface Vault {
64
64
  */
65
65
  checkpoint(): Promise<Outcome<{ checkpoint: Checkpoint }>>;
66
66
  /**
67
- * What only the vault's configuration says, which the app shows: the key
68
- * its checkpoints verify under, and the root admins, as principals.
67
+ * What the vault's configuration says, which the app shows: the keys its
68
+ * checkpoints verify under, by the key id each checkpoint names (the one
69
+ * it signs with now, and those of the KEKs it replaced), and the root
70
+ * admins, as principals.
69
71
  */
70
- about(): Promise<{ publicKey: string; rootAdmins: string[] }>;
72
+ about(): Promise<{ checkpointKeys: Record<string, CheckpointKey>; rootAdmins: string[] }>;
71
73
  /**
72
74
  * Check the whole log: rehash it from the first entry, the vault's
73
75
  * entries by their MACs, every checkpoint against the prefix it signed,
@@ -252,6 +254,14 @@ export type Checkpoint = {
252
254
  signature: string;
253
255
  };
254
256
 
257
+ /**
258
+ * A public key the vault's checkpoints verify under, base64. One it
259
+ * replaced vouches only for checkpoints whose prefix ends before `until`,
260
+ * its first entry under the key that replaced it; the one it signs with now
261
+ * has none.
262
+ */
263
+ export type CheckpointKey = { publicKey: string; until: number | null };
264
+
255
265
  /** An entry of the vault's log, and so the chain up to it. */
256
266
  export type LogHead = { seq: number; hash: string };
257
267