@coffre/vault 0.1.15 → 0.1.17

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.
@@ -1,5 +1,5 @@
1
1
  import { a as verifyCheckpoint, i as checkpointMessage, n as KekUnavailableError, o as derivedSigningKey, r as awsKms, s as resolveVaultConfig, t as KekBadClaimError } from "./src-1yVV2L0_.js";
2
- import { n as prepareVault, t as openVault } from "./vault-BmEa1SIQ.js";
2
+ import { n as prepareVault, t as openVault } from "./vault-BexBMpZL.js";
3
3
  import { createDatabase } from "@coffre/db";
4
4
  import { HyperdrivePool, postgres } from "@coffre/db/hyperdrive";
5
5
  import { WorkerEntrypoint } from "cloudflare:workers";
package/dist/node.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as verifyCheckpoint, i as checkpointMessage, n as KekUnavailableError, o as derivedSigningKey, r as awsKms, s as resolveVaultConfig, t as KekBadClaimError } from "./src-1yVV2L0_.js";
2
- import { n as prepareVault, t as openVault } from "./vault-BmEa1SIQ.js";
2
+ import { n as prepareVault, t as openVault } from "./vault-BexBMpZL.js";
3
3
  import { chmodSync, existsSync, lstatSync, rmSync } from "node:fs";
4
4
  import { Agent, createServer, request } from "node:http";
5
5
  import { openDatabase } from "@coffre/db/connect";
@@ -914,6 +914,10 @@ const MESSAGES = {
914
914
  wrong_kek: "this vault's key does not open the data it holds",
915
915
  tampered: "this member's record failed the vault's integrity check"
916
916
  };
917
+ /** The credential a CI run's request came in on, as its entries record it: copied, never decided on. */
918
+ function traced(correlation) {
919
+ return correlation.credentialId == null ? {} : { credentialId: correlation.credentialId };
920
+ }
917
921
  /**
918
922
  * The one implementation of `Vault`. Every decision is one transaction on
919
923
  * the shared database: it locks the rows of the members it is about, reads
@@ -1335,7 +1339,8 @@ var VaultService = class {
1335
1339
  requestId: input.requestId,
1336
1340
  metadata: JSON.stringify({
1337
1341
  ...detail,
1338
- secretVersionId: id
1342
+ secretVersionId: id,
1343
+ ...traced(input)
1339
1344
  })
1340
1345
  };
1341
1346
  return {
@@ -1424,6 +1429,7 @@ var VaultService = class {
1424
1429
  operation: action,
1425
1430
  expiresAt: at + this.#prepared.options.keyBudgetMs + 2 * LOCK_TIMEOUT_MS,
1426
1431
  ...call.input.purpose === void 0 ? {} : { purpose: call.input.purpose },
1432
+ ...traced(call.input),
1427
1433
  keys: secrets.map((secret, item) => ({
1428
1434
  item,
1429
1435
  subject: secret.path,
@@ -2392,6 +2398,7 @@ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
2392
2398
  function validateCorrelation(input) {
2393
2399
  if (input.requestId != null) validateText(input.requestId);
2394
2400
  if (input.operationId != null && (typeof input.operationId !== "string" || !UUID.test(input.operationId))) throw new Error(`operationId must be a lowercase UUID, got: ${String(input.operationId)}`);
2401
+ if (input.credentialId != null && (typeof input.credentialId !== "string" || !UUID.test(input.credentialId))) throw new Error(`credentialId must be a lowercase UUID, got: ${String(input.credentialId)}`);
2395
2402
  }
2396
2403
  /** Validate the entire batch before any provider sees a key. */
2397
2404
  function validateItems(items, field) {
@@ -2452,7 +2459,8 @@ function keyEntry(action, principal, secret, decision, code, correlation, detail
2452
2459
  subject: secret.path,
2453
2460
  ...action === "key.wrap" ? { secretId: secret.secretId } : {},
2454
2461
  version: secret.version,
2455
- ...detail
2462
+ ...detail,
2463
+ ...traced(correlation)
2456
2464
  })
2457
2465
  };
2458
2466
  }
@@ -2470,9 +2478,13 @@ function accessEntry(actor, action, principal, decision, correlation, detail, co
2470
2478
  subjectPrincipal: PRINCIPAL.test(principal) ? principal : null,
2471
2479
  operationId: correlation.operationId ?? null,
2472
2480
  requestId: correlation.requestId ?? null,
2473
- metadata: JSON.stringify(PRINCIPAL.test(principal) ? detail : {
2481
+ metadata: JSON.stringify(PRINCIPAL.test(principal) ? {
2482
+ ...detail,
2483
+ ...traced(correlation)
2484
+ } : {
2474
2485
  subject: principal,
2475
- ...detail
2486
+ ...detail,
2487
+ ...traced(correlation)
2476
2488
  })
2477
2489
  };
2478
2490
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffre/vault",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "coffre's vault: keys, grants and members, in the database the app uses, as a Cloudflare Worker or on Node.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,8 +36,8 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "drizzle-orm": "0.45.2",
39
- "@coffre/core": "0.1.15",
40
- "@coffre/db": "0.1.15"
39
+ "@coffre/core": "0.1.17",
40
+ "@coffre/db": "0.1.17"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "26.1.1",
package/src/vault.ts CHANGED
@@ -265,7 +265,12 @@ type Decision = {
265
265
  type KeyAction = 'secret.read' | 'key.wrap' | 'key.rewrap';
266
266
 
267
267
  /** What ties an entry to the app's request, and to the one action it is part of. */
268
- type Correlation = { requestId?: string | null; operationId?: string | null };
268
+ type Correlation = { requestId?: string | null; operationId?: string | null; credentialId?: string | null };
269
+
270
+ /** The credential a CI run's request came in on, as its entries record it: copied, never decided on. */
271
+ function traced(correlation: Correlation): { credentialId?: string } {
272
+ return correlation.credentialId == null ? {} : { credentialId: correlation.credentialId };
273
+ }
269
274
 
270
275
  /** Why a member's row is not the one the vault last wrote; rows.ts. */
271
276
  type Fault = 'mac' | 'stale';
@@ -714,7 +719,7 @@ class VaultService implements Vault {
714
719
  if (version === undefined) return {
715
720
  actor: input.principal, action, decision: 'deny', code: 'bad_claim',
716
721
  operationId: input.operationId, requestId: input.requestId,
717
- metadata: JSON.stringify({ ...detail, secretVersionId: id }),
722
+ metadata: JSON.stringify({ ...detail, secretVersionId: id, ...traced(input) }),
718
723
  };
719
724
  return { ...keyEntry(action, input.principal, version.secret, 'deny', 'bad_claim', input, detail), secretVersionId: id };
720
725
  }));
@@ -824,6 +829,7 @@ class VaultService implements Vault {
824
829
  // Member and outcome locks can each wait before accounting is overdue.
825
830
  expiresAt: at + this.#prepared.options.keyBudgetMs + 2 * LOCK_TIMEOUT_MS,
826
831
  ...(call.input.purpose === undefined ? {} : { purpose: call.input.purpose }),
832
+ ...traced(call.input),
827
833
  keys: secrets.map((secret, item) => ({ item, subject: secret.path, secretId: secret.secretId, version: secret.version })),
828
834
  }),
829
835
  }]);
@@ -1712,6 +1718,9 @@ function validateCorrelation(input: Correlation): void {
1712
1718
  if (input.operationId != null && (typeof input.operationId !== 'string' || !UUID.test(input.operationId))) {
1713
1719
  throw new Error(`operationId must be a lowercase UUID, got: ${String(input.operationId)}`);
1714
1720
  }
1721
+ if (input.credentialId != null && (typeof input.credentialId !== 'string' || !UUID.test(input.credentialId))) {
1722
+ throw new Error(`credentialId must be a lowercase UUID, got: ${String(input.credentialId)}`);
1723
+ }
1715
1724
  }
1716
1725
 
1717
1726
  /** Validate the entire batch before any provider sees a key. */
@@ -1780,6 +1789,7 @@ function keyEntry(
1780
1789
  ...(action === 'key.wrap' ? { secretId: secret.secretId } : {}),
1781
1790
  version: secret.version,
1782
1791
  ...detail,
1792
+ ...traced(correlation),
1783
1793
  }),
1784
1794
  };
1785
1795
  }
@@ -1813,7 +1823,7 @@ function accessEntry(
1813
1823
  subjectPrincipal: PRINCIPAL.test(principal) ? principal : null,
1814
1824
  operationId: correlation.operationId ?? null,
1815
1825
  requestId: correlation.requestId ?? null,
1816
- metadata: JSON.stringify(PRINCIPAL.test(principal) ? detail : { subject: principal, ...detail }),
1826
+ metadata: JSON.stringify(PRINCIPAL.test(principal) ? { ...detail, ...traced(correlation) } : { subject: principal, ...detail, ...traced(correlation) }),
1817
1827
  };
1818
1828
  }
1819
1829