@emilia-protocol/gate 0.10.0 → 0.13.0
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/CHANGELOG.md +91 -0
- package/README.md +272 -0
- package/action-control-manifest.js +3 -268
- package/action-escrow-custodian.js +4 -0
- package/action-escrow-evidence.js +4 -0
- package/action-escrow-package.js +4 -0
- package/action-escrow-postgres.js +4 -0
- package/action-escrow-state.js +4 -0
- package/action-escrow-verifiers.js +4 -0
- package/action-escrow.js +4 -0
- package/action-packs.js +3 -140
- package/adapters/_kit.js +3 -104
- package/adapters/aws.js +3 -108
- package/adapters/cloudflare.js +3 -54
- package/adapters/gcp.js +3 -70
- package/adapters/github.js +3 -109
- package/adapters/jira.js +3 -55
- package/adapters/k8s.js +3 -70
- package/adapters/linear.js +3 -55
- package/adapters/salesforce.js +3 -55
- package/adapters/stripe.js +3 -81
- package/adapters/supabase.js +3 -121
- package/adapters/terraform.js +3 -59
- package/adapters/vercel.js +3 -84
- package/aec-execution.js +3 -312
- package/breakglass.js +3 -582
- package/capability-receipt.js +4 -0
- package/cf1-conformance.js +3 -106
- package/challenge-store.js +3 -69
- package/control-plane.js +3 -340
- package/coverage.js +3 -721
- package/demo.mjs +1 -1
- package/deployment-attestation.js +3 -247
- package/dist/action-control-manifest.d.ts +82 -0
- package/dist/action-control-manifest.d.ts.map +1 -0
- package/dist/action-control-manifest.js +422 -0
- package/dist/action-control-manifest.js.map +1 -0
- package/dist/action-escrow-custodian.d.ts +74 -0
- package/dist/action-escrow-custodian.d.ts.map +1 -0
- package/dist/action-escrow-custodian.js +363 -0
- package/dist/action-escrow-custodian.js.map +1 -0
- package/dist/action-escrow-evidence.d.ts +130 -0
- package/dist/action-escrow-evidence.d.ts.map +1 -0
- package/dist/action-escrow-evidence.js +1012 -0
- package/dist/action-escrow-evidence.js.map +1 -0
- package/dist/action-escrow-package.d.ts +10 -0
- package/dist/action-escrow-package.d.ts.map +1 -0
- package/dist/action-escrow-package.js +1583 -0
- package/dist/action-escrow-package.js.map +1 -0
- package/dist/action-escrow-postgres.d.ts +62 -0
- package/dist/action-escrow-postgres.d.ts.map +1 -0
- package/dist/action-escrow-postgres.js +339 -0
- package/dist/action-escrow-postgres.js.map +1 -0
- package/dist/action-escrow-state.d.ts +141 -0
- package/dist/action-escrow-state.d.ts.map +1 -0
- package/dist/action-escrow-state.js +413 -0
- package/dist/action-escrow-state.js.map +1 -0
- package/dist/action-escrow-verifiers.d.ts +65 -0
- package/dist/action-escrow-verifiers.d.ts.map +1 -0
- package/dist/action-escrow-verifiers.js +421 -0
- package/dist/action-escrow-verifiers.js.map +1 -0
- package/dist/action-escrow.d.ts +112 -0
- package/dist/action-escrow.d.ts.map +1 -0
- package/dist/action-escrow.js +2661 -0
- package/dist/action-escrow.js.map +1 -0
- package/dist/action-packs.d.ts +54 -0
- package/dist/action-packs.d.ts.map +1 -0
- package/dist/action-packs.js +143 -0
- package/dist/action-packs.js.map +1 -0
- package/dist/adapters/_kit.d.ts +50 -0
- package/dist/adapters/_kit.d.ts.map +1 -0
- package/dist/adapters/_kit.js +98 -0
- package/dist/adapters/_kit.js.map +1 -0
- package/dist/adapters/aws.d.ts +158 -0
- package/dist/adapters/aws.d.ts.map +1 -0
- package/dist/adapters/aws.js +136 -0
- package/dist/adapters/aws.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +116 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -0
- package/dist/adapters/cloudflare.js +75 -0
- package/dist/adapters/cloudflare.js.map +1 -0
- package/dist/adapters/gcp.d.ts +139 -0
- package/dist/adapters/gcp.d.ts.map +1 -0
- package/dist/adapters/gcp.js +69 -0
- package/dist/adapters/gcp.js.map +1 -0
- package/dist/adapters/github.d.ts +123 -0
- package/dist/adapters/github.d.ts.map +1 -0
- package/dist/adapters/github.js +105 -0
- package/dist/adapters/github.js.map +1 -0
- package/dist/adapters/jira.d.ts +109 -0
- package/dist/adapters/jira.d.ts.map +1 -0
- package/dist/adapters/jira.js +54 -0
- package/dist/adapters/jira.js.map +1 -0
- package/dist/adapters/k8s.d.ts +139 -0
- package/dist/adapters/k8s.d.ts.map +1 -0
- package/dist/adapters/k8s.js +69 -0
- package/dist/adapters/k8s.js.map +1 -0
- package/dist/adapters/linear.d.ts +109 -0
- package/dist/adapters/linear.d.ts.map +1 -0
- package/dist/adapters/linear.js +54 -0
- package/dist/adapters/linear.js.map +1 -0
- package/dist/adapters/salesforce.d.ts +109 -0
- package/dist/adapters/salesforce.d.ts.map +1 -0
- package/dist/adapters/salesforce.js +54 -0
- package/dist/adapters/salesforce.js.map +1 -0
- package/dist/adapters/stripe.d.ts +116 -0
- package/dist/adapters/stripe.d.ts.map +1 -0
- package/dist/adapters/stripe.js +77 -0
- package/dist/adapters/stripe.js.map +1 -0
- package/dist/adapters/supabase.d.ts +127 -0
- package/dist/adapters/supabase.d.ts.map +1 -0
- package/dist/adapters/supabase.js +112 -0
- package/dist/adapters/supabase.js.map +1 -0
- package/dist/adapters/terraform.d.ts +109 -0
- package/dist/adapters/terraform.d.ts.map +1 -0
- package/dist/adapters/terraform.js +58 -0
- package/dist/adapters/terraform.js.map +1 -0
- package/dist/adapters/vercel.d.ts +114 -0
- package/dist/adapters/vercel.d.ts.map +1 -0
- package/dist/adapters/vercel.js +81 -0
- package/dist/adapters/vercel.js.map +1 -0
- package/dist/aec-execution.d.ts +107 -0
- package/dist/aec-execution.d.ts.map +1 -0
- package/dist/aec-execution.js +334 -0
- package/dist/aec-execution.js.map +1 -0
- package/dist/breakglass.d.ts +205 -0
- package/dist/breakglass.d.ts.map +1 -0
- package/dist/breakglass.js +627 -0
- package/dist/breakglass.js.map +1 -0
- package/dist/capability-receipt.d.ts +601 -0
- package/dist/capability-receipt.d.ts.map +1 -0
- package/dist/capability-receipt.js +1177 -0
- package/dist/capability-receipt.js.map +1 -0
- package/dist/cf1-conformance.d.ts +83 -0
- package/dist/cf1-conformance.d.ts.map +1 -0
- package/dist/cf1-conformance.js +94 -0
- package/dist/cf1-conformance.js.map +1 -0
- package/dist/challenge-store.d.ts +20 -0
- package/dist/challenge-store.d.ts.map +1 -0
- package/dist/challenge-store.js +62 -0
- package/dist/challenge-store.js.map +1 -0
- package/dist/control-plane.d.ts +136 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +349 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/coverage.d.ts +156 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +768 -0
- package/dist/coverage.js.map +1 -0
- package/dist/deployment-attestation.d.ts +93 -0
- package/dist/deployment-attestation.d.ts.map +1 -0
- package/dist/deployment-attestation.js +262 -0
- package/dist/deployment-attestation.js.map +1 -0
- package/dist/eg1-conformance.d.ts +286 -0
- package/dist/eg1-conformance.d.ts.map +1 -0
- package/dist/eg1-conformance.js +379 -0
- package/dist/eg1-conformance.js.map +1 -0
- package/dist/enterprise.d.ts +88 -0
- package/dist/enterprise.d.ts.map +1 -0
- package/dist/enterprise.js +194 -0
- package/dist/enterprise.js.map +1 -0
- package/dist/evidence-postgres.d.ts +123 -0
- package/dist/evidence-postgres.d.ts.map +1 -0
- package/dist/evidence-postgres.js +343 -0
- package/dist/evidence-postgres.js.map +1 -0
- package/dist/evidence.d.ts +113 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +369 -0
- package/dist/evidence.js.map +1 -0
- package/dist/execution-binding.d.ts +49 -0
- package/dist/execution-binding.d.ts.map +1 -0
- package/dist/execution-binding.js +243 -0
- package/dist/execution-binding.js.map +1 -0
- package/dist/formal-runtime-map.d.ts +42 -0
- package/dist/formal-runtime-map.d.ts.map +1 -0
- package/dist/formal-runtime-map.js +23 -0
- package/dist/formal-runtime-map.js.map +1 -0
- package/dist/index.d.ts +1002 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1736 -0
- package/dist/index.js.map +1 -0
- package/dist/key-registry.d.ts +60 -0
- package/dist/key-registry.d.ts.map +1 -0
- package/dist/key-registry.js +144 -0
- package/dist/key-registry.js.map +1 -0
- package/dist/mcp.d.ts +53 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +112 -0
- package/dist/mcp.js.map +1 -0
- package/dist/metering.d.ts +80 -0
- package/dist/metering.d.ts.map +1 -0
- package/dist/metering.js +227 -0
- package/dist/metering.js.map +1 -0
- package/dist/metrics.d.ts +68 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +242 -0
- package/dist/metrics.js.map +1 -0
- package/dist/network-witness.d.ts +167 -0
- package/dist/network-witness.d.ts.map +1 -0
- package/dist/network-witness.js +520 -0
- package/dist/network-witness.js.map +1 -0
- package/dist/protocol-state.d.ts +141 -0
- package/dist/protocol-state.d.ts.map +1 -0
- package/dist/protocol-state.js +106 -0
- package/dist/protocol-state.js.map +1 -0
- package/dist/receipt-program.d.ts +59 -0
- package/dist/receipt-program.d.ts.map +1 -0
- package/dist/receipt-program.js +1053 -0
- package/dist/receipt-program.js.map +1 -0
- package/dist/reliance-kernel.d.ts +66 -0
- package/dist/reliance-kernel.d.ts.map +1 -0
- package/dist/reliance-kernel.js +103 -0
- package/dist/reliance-kernel.js.map +1 -0
- package/dist/reliance-packet.d.ts +67 -0
- package/dist/reliance-packet.d.ts.map +1 -0
- package/dist/reliance-packet.js +176 -0
- package/dist/reliance-packet.js.map +1 -0
- package/dist/remedy-program-postgres.d.ts +37 -0
- package/dist/remedy-program-postgres.d.ts.map +1 -0
- package/dist/remedy-program-postgres.js +291 -0
- package/dist/remedy-program-postgres.js.map +1 -0
- package/dist/remedy-program-receipt.d.ts +97 -0
- package/dist/remedy-program-receipt.d.ts.map +1 -0
- package/dist/remedy-program-receipt.js +817 -0
- package/dist/remedy-program-receipt.js.map +1 -0
- package/dist/remedy-program.d.ts +76 -0
- package/dist/remedy-program.d.ts.map +1 -0
- package/dist/remedy-program.js +1346 -0
- package/dist/remedy-program.js.map +1 -0
- package/dist/reports/art14.d.ts +101 -0
- package/dist/reports/art14.d.ts.map +1 -0
- package/dist/reports/art14.js +340 -0
- package/dist/reports/art14.js.map +1 -0
- package/dist/reports/assurance-package.d.ts +197 -0
- package/dist/reports/assurance-package.d.ts.map +1 -0
- package/dist/reports/assurance-package.js +313 -0
- package/dist/reports/assurance-package.js.map +1 -0
- package/dist/reports/auditor-workpaper.d.ts +194 -0
- package/dist/reports/auditor-workpaper.d.ts.map +1 -0
- package/dist/reports/auditor-workpaper.js +545 -0
- package/dist/reports/auditor-workpaper.js.map +1 -0
- package/dist/reports/external-verification.d.ts +76 -0
- package/dist/reports/external-verification.d.ts.map +1 -0
- package/dist/reports/external-verification.js +209 -0
- package/dist/reports/external-verification.js.map +1 -0
- package/dist/reports/reperform.d.ts +122 -0
- package/dist/reports/reperform.d.ts.map +1 -0
- package/dist/reports/reperform.js +432 -0
- package/dist/reports/reperform.js.map +1 -0
- package/dist/reports/underwriter.d.ts +127 -0
- package/dist/reports/underwriter.d.ts.map +1 -0
- package/dist/reports/underwriter.js +348 -0
- package/dist/reports/underwriter.js.map +1 -0
- package/dist/retention.d.ts +88 -0
- package/dist/retention.d.ts.map +1 -0
- package/dist/retention.js +90 -0
- package/dist/retention.js.map +1 -0
- package/dist/roster.d.ts +113 -0
- package/dist/roster.d.ts.map +1 -0
- package/dist/roster.js +261 -0
- package/dist/roster.js.map +1 -0
- package/dist/runtime-monitor.d.ts +132 -0
- package/dist/runtime-monitor.d.ts.map +1 -0
- package/dist/runtime-monitor.js +197 -0
- package/dist/runtime-monitor.js.map +1 -0
- package/dist/settlement.d.ts +68 -0
- package/dist/settlement.d.ts.map +1 -0
- package/dist/settlement.js +306 -0
- package/dist/settlement.js.map +1 -0
- package/dist/siem.d.ts +261 -0
- package/dist/siem.d.ts.map +1 -0
- package/dist/siem.js +247 -0
- package/dist/siem.js.map +1 -0
- package/dist/store-postgres.d.ts +107 -0
- package/dist/store-postgres.d.ts.map +1 -0
- package/dist/store-postgres.js +152 -0
- package/dist/store-postgres.js.map +1 -0
- package/dist/store.d.ts +95 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +202 -0
- package/dist/store.js.map +1 -0
- package/dist/strict-json.d.ts +14 -0
- package/dist/strict-json.d.ts.map +1 -0
- package/dist/strict-json.js +132 -0
- package/dist/strict-json.js.map +1 -0
- package/dist/trust-program-adapters.d.ts +122 -0
- package/dist/trust-program-adapters.d.ts.map +1 -0
- package/dist/trust-program-adapters.js +802 -0
- package/dist/trust-program-adapters.js.map +1 -0
- package/dist/trust-program-postgres.d.ts +41 -0
- package/dist/trust-program-postgres.d.ts.map +1 -0
- package/dist/trust-program-postgres.js +346 -0
- package/dist/trust-program-postgres.js.map +1 -0
- package/dist/trust-program-revocation.d.ts +206 -0
- package/dist/trust-program-revocation.d.ts.map +1 -0
- package/dist/trust-program-revocation.js +600 -0
- package/dist/trust-program-revocation.js.map +1 -0
- package/dist/trust-program.d.ts +197 -0
- package/dist/trust-program.d.ts.map +1 -0
- package/dist/trust-program.js +1351 -0
- package/dist/trust-program.js.map +1 -0
- package/dist/witness-postgres.d.ts +43 -0
- package/dist/witness-postgres.d.ts.map +1 -0
- package/dist/witness-postgres.js +92 -0
- package/dist/witness-postgres.js.map +1 -0
- package/dist/zk-range-proof.d.ts +78 -0
- package/dist/zk-range-proof.d.ts.map +1 -0
- package/dist/zk-range-proof.js +228 -0
- package/dist/zk-range-proof.js.map +1 -0
- package/eg1-conformance.js +3 -404
- package/enterprise.js +3 -180
- package/ep-assure.mjs +1 -0
- package/evidence-postgres.js +3 -356
- package/evidence.js +4 -360
- package/execution-binding.js +3 -212
- package/formal-runtime-map.js +4 -0
- package/index.js +4 -1249
- package/key-registry.js +3 -134
- package/mcp.js +3 -109
- package/metering.js +3 -226
- package/metrics.js +3 -231
- package/network-witness.js +3 -499
- package/package.json +47 -4
- package/receipt-program.js +4 -0
- package/reliance-kernel.js +3 -112
- package/reliance-packet.js +3 -175
- package/remedy-program-postgres.js +4 -0
- package/remedy-program-receipt.js +4 -0
- package/remedy-program.js +4 -0
- package/reports/art14.js +0 -0
- package/reports/assurance-package.js +2 -312
- package/reports/auditor-workpaper.js +3 -537
- package/reports/external-verification.js +3 -222
- package/reports/reperform.js +3 -424
- package/reports/underwriter.js +3 -339
- package/retention.js +3 -84
- package/roster.js +3 -264
- package/runtime-monitor.js +4 -0
- package/settlement.js +3 -299
- package/siem.js +3 -235
- package/src/action-control-manifest.ts +424 -0
- package/src/action-escrow-custodian.ts +427 -0
- package/src/action-escrow-evidence.ts +1178 -0
- package/src/action-escrow-package.ts +1821 -0
- package/src/action-escrow-postgres.ts +366 -0
- package/src/action-escrow-state.ts +498 -0
- package/src/action-escrow-verifiers.ts +484 -0
- package/src/action-escrow.ts +3039 -0
- package/src/action-packs.ts +170 -0
- package/src/adapters/_kit.ts +117 -0
- package/src/adapters/aws.ts +142 -0
- package/src/adapters/cloudflare.ts +78 -0
- package/src/adapters/gcp.ts +71 -0
- package/src/adapters/github.ts +110 -0
- package/src/adapters/jira.ts +56 -0
- package/src/adapters/k8s.ts +71 -0
- package/src/adapters/linear.ts +56 -0
- package/src/adapters/salesforce.ts +56 -0
- package/src/adapters/stripe.ts +82 -0
- package/src/adapters/supabase.ts +122 -0
- package/src/adapters/terraform.ts +60 -0
- package/src/adapters/vercel.ts +85 -0
- package/src/aec-execution.ts +354 -0
- package/src/breakglass.ts +647 -0
- package/src/capability-receipt.ts +1258 -0
- package/src/cf1-conformance.ts +120 -0
- package/src/challenge-store.ts +70 -0
- package/src/control-plane.ts +374 -0
- package/src/coverage.ts +832 -0
- package/src/deployment-attestation.ts +259 -0
- package/src/eg1-conformance.ts +471 -0
- package/src/enterprise.ts +195 -0
- package/src/evidence-postgres.ts +374 -0
- package/src/evidence.ts +367 -0
- package/src/execution-binding.ts +236 -0
- package/src/formal-runtime-map.ts +24 -0
- package/src/index.ts +2122 -0
- package/src/key-registry.ts +150 -0
- package/src/mcp.ts +120 -0
- package/src/metering.ts +237 -0
- package/src/metrics.ts +232 -0
- package/src/network-witness.ts +585 -0
- package/src/protocol-state.ts +143 -0
- package/src/protocol-state.typecheck.ts +94 -0
- package/src/receipt-program.ts +1105 -0
- package/src/reliance-kernel.ts +119 -0
- package/src/reliance-packet.ts +206 -0
- package/src/remedy-program-postgres.ts +367 -0
- package/src/remedy-program-receipt.ts +891 -0
- package/src/remedy-program.ts +1388 -0
- package/src/reports/art14.ts +361 -0
- package/src/reports/assurance-package.ts +330 -0
- package/src/reports/auditor-workpaper.ts +558 -0
- package/src/reports/external-verification.ts +232 -0
- package/src/reports/reperform.ts +441 -0
- package/src/reports/underwriter.ts +356 -0
- package/src/retention.ts +100 -0
- package/src/roster.ts +273 -0
- package/src/runtime-monitor.ts +217 -0
- package/src/settlement.ts +313 -0
- package/src/siem.ts +247 -0
- package/src/store-postgres.ts +167 -0
- package/src/store.ts +214 -0
- package/src/strict-json.ts +115 -0
- package/src/trust-program-adapters.ts +847 -0
- package/src/trust-program-postgres.ts +429 -0
- package/src/trust-program-revocation.ts +751 -0
- package/src/trust-program.ts +1460 -0
- package/src/witness-postgres.ts +106 -0
- package/src/zk-range-proof.ts +250 -0
- package/store-postgres.js +3 -161
- package/store.js +4 -198
- package/strict-json.js +3 -85
- package/trust-program-adapters.js +4 -0
- package/trust-program-postgres.js +4 -0
- package/trust-program-revocation.js +4 -0
- package/trust-program.js +4 -0
- package/witness-postgres.js +3 -96
- package/zk-range-proof.js +4 -0
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* EMILIA Gate — break-glass as EVIDENCE, never a bypass (EP-GATE-BREAKGLASS-v1).
|
|
5
|
+
*
|
|
6
|
+
* An emergency override is a FIRST-CLASS SIGNED ARTIFACT, not a config flag.
|
|
7
|
+
* There is no "disable the gate" switch anywhere in this module: to act outside
|
|
8
|
+
* the normal receipt path, operators mint a break-glass authorization — an
|
|
9
|
+
* M-of-N Ed25519 multi-signature over canonical JSON (sorted keys, same idiom
|
|
10
|
+
* as receipts/entitlements/evidence) of ONE shared grant:
|
|
11
|
+
*
|
|
12
|
+
* { grant_id, scope: { action_types[] }, window: { not_before, expires_at },
|
|
13
|
+
* reason, incident_ref, threshold }
|
|
14
|
+
*
|
|
15
|
+
* Every signer signs the SAME payload, so the artifact proves that `threshold`
|
|
16
|
+
* DISTINCT pinned principals authorized exactly this scope, for exactly this
|
|
17
|
+
* window, for exactly this incident. The grant is:
|
|
18
|
+
* - SCOPED — valid only for the listed action_types; anything else refuses;
|
|
19
|
+
* - BOUNDED — valid only inside [not_before, expires_at];
|
|
20
|
+
* - ATTRIBUTED — reason + incident_ref are REQUIRED; an override with no
|
|
21
|
+
* stated cause is refused, not logged-and-allowed;
|
|
22
|
+
* - SINGLE-USE — consumed through the same consumption-store contract as
|
|
23
|
+
* receipts (store.js); consumption is committed BEFORE use, so
|
|
24
|
+
* a crash mid-override burns the grant instead of leaving it
|
|
25
|
+
* replayable (fail direction: unusable, never reusable);
|
|
26
|
+
* - LOGGED — `buildBreakGlassEvidence` shapes a kind:'breakglass' entry
|
|
27
|
+
* for the tamper-evident evidence log.
|
|
28
|
+
*
|
|
29
|
+
* THE MODULE'S EXECUTION CONTRACT: use `runBreakGlass`. It is the one high-level
|
|
30
|
+
* path that enforces pinned-policy verification, permanent fleet-safe
|
|
31
|
+
* consumption, strict evidence acknowledgement, and only then effect invocation.
|
|
32
|
+
* The lower-level verify/consume/evidence helpers are composable primitives; no
|
|
33
|
+
* one of them alone authorizes or executes an override.
|
|
34
|
+
*
|
|
35
|
+
* Verification FAILS CLOSED with machine-readable reasons: threshold unmet,
|
|
36
|
+
* non-distinct signer kids, expired, not-yet-valid, out-of-scope action_type,
|
|
37
|
+
* tampered payload, unknown kid, malformed anything → { valid:false, reason }.
|
|
38
|
+
* A grant carrying ANY signature that does not verify is refused outright —
|
|
39
|
+
* we never "count the good ones" past a bad one.
|
|
40
|
+
*
|
|
41
|
+
* Pure functions: inputs in, verdict out. Time is injected (`now`), never read
|
|
42
|
+
* from the wall clock implicitly, so verification is deterministic.
|
|
43
|
+
*/
|
|
44
|
+
import crypto from 'node:crypto';
|
|
45
|
+
import { strictJsonGate } from './strict-json.js';
|
|
46
|
+
import { canonicalize as canonical } from './execution-binding.js';
|
|
47
|
+
import { verifyEvidenceRecord } from './evidence.js';
|
|
48
|
+
import { isSecureConsumptionStore } from './store.js';
|
|
49
|
+
export const BREAKGLASS_VERSION = 'EP-GATE-BREAKGLASS-v1';
|
|
50
|
+
export const BREAKGLASS_EVIDENCE_KIND = 'breakglass';
|
|
51
|
+
function sha256hex(s) {
|
|
52
|
+
return crypto.createHash('sha256').update(s).digest('hex');
|
|
53
|
+
}
|
|
54
|
+
function toMs(t) {
|
|
55
|
+
if (t == null)
|
|
56
|
+
return null;
|
|
57
|
+
const ms = typeof t === 'number' ? t : Date.parse(t);
|
|
58
|
+
return Number.isFinite(ms) ? ms : null;
|
|
59
|
+
}
|
|
60
|
+
/** Every refusal shape is identical and machine-readable. Fail closed. */
|
|
61
|
+
function refuse(reason, extra = {}) {
|
|
62
|
+
return { valid: false, reason, ...extra };
|
|
63
|
+
}
|
|
64
|
+
function isNonEmptyString(s) {
|
|
65
|
+
return typeof s === 'string' && s.length > 0;
|
|
66
|
+
}
|
|
67
|
+
function isActionTypeList(a) {
|
|
68
|
+
return Array.isArray(a) && a.length > 0 && a.every(isNonEmptyString);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mint a break-glass authorization: every signer signs the canonical JSON of
|
|
72
|
+
* the SAME grant payload. Throws on invalid fields — a malformed grant must
|
|
73
|
+
* never be issued, only refused. Signer kids must already be distinct at mint
|
|
74
|
+
* time: one key can never pre-fill two threshold slots. Relying-party principal
|
|
75
|
+
* uniqueness is enforced at verification through the pinned policy roster.
|
|
76
|
+
*
|
|
77
|
+
* grant_id is CONTENT-DERIVED (sha-256 of the canonical grant fields), so the
|
|
78
|
+
* id is deterministic and re-minting the identical grant yields the identical
|
|
79
|
+
* single-use consumption key — the same emergency authorization cannot be
|
|
80
|
+
* "refreshed" into extra uses by minting it twice.
|
|
81
|
+
*
|
|
82
|
+
* @param {Array<{ privateKey: crypto.KeyObject, kid: string }>} signers
|
|
83
|
+
* @param {object} fields { scope: { action_types: string[] }, window: { not_before, expires_at }, reason, incident_ref, threshold }
|
|
84
|
+
* @returns {{ '@version': string, payload: object, signatures: Array<{ kid: string, algorithm: 'Ed25519', value: string }> }}
|
|
85
|
+
*/
|
|
86
|
+
export function mintBreakGlassAuthorization(signers, { scope, window: win, reason, incident_ref, threshold, } = {}) {
|
|
87
|
+
if (!Array.isArray(signers) || signers.length === 0) {
|
|
88
|
+
throw new Error('breakglass: signers must be a non-empty array of { privateKey, kid }');
|
|
89
|
+
}
|
|
90
|
+
for (const s of signers) {
|
|
91
|
+
if (!s || !s.privateKey || !isNonEmptyString(s.kid)) {
|
|
92
|
+
throw new Error('breakglass: each signer needs a privateKey and a kid');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const kids = signers.map((s) => s.kid);
|
|
96
|
+
if (new Set(kids).size !== kids.length) {
|
|
97
|
+
throw new Error('breakglass: signer kids must be distinct — one principal cannot fill two threshold slots');
|
|
98
|
+
}
|
|
99
|
+
let signerFingerprints;
|
|
100
|
+
try {
|
|
101
|
+
signerFingerprints = signers.map((s) => {
|
|
102
|
+
// @types/node's createPublicKey overloads omit KeyObject input even
|
|
103
|
+
// though Node derives a public key from a private KeyObject at runtime.
|
|
104
|
+
const publicKey = crypto.createPublicKey(/** @type {any} */ (s.privateKey));
|
|
105
|
+
if (publicKey.asymmetricKeyType !== 'ed25519')
|
|
106
|
+
throw new Error('not Ed25519');
|
|
107
|
+
const spki = publicKey.export({ type: 'spki', format: 'der' });
|
|
108
|
+
return sha256hex(spki);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new Error('breakglass: every signer privateKey must be an Ed25519 key');
|
|
113
|
+
}
|
|
114
|
+
if (new Set(signerFingerprints).size !== signerFingerprints.length) {
|
|
115
|
+
throw new Error('breakglass: signer SPKI keys must be distinct — one key cannot fill two threshold slots');
|
|
116
|
+
}
|
|
117
|
+
if (!scope || !isActionTypeList(scope.action_types)) {
|
|
118
|
+
throw new Error('breakglass: scope.action_types must be a non-empty array of action-type strings');
|
|
119
|
+
}
|
|
120
|
+
if (typeof threshold !== 'number' || !Number.isInteger(threshold) || threshold < 2) {
|
|
121
|
+
throw new Error('breakglass: threshold must be an integer >= 2');
|
|
122
|
+
}
|
|
123
|
+
if (threshold > signers.length) {
|
|
124
|
+
throw new Error(`breakglass: threshold ${threshold} exceeds signer count ${signers.length} — the grant could never verify`);
|
|
125
|
+
}
|
|
126
|
+
const nbf = toMs(win?.not_before);
|
|
127
|
+
const exp = toMs(win?.expires_at);
|
|
128
|
+
if (nbf == null || exp == null) {
|
|
129
|
+
throw new Error('breakglass: window.not_before and window.expires_at are required (ISO or ms)');
|
|
130
|
+
}
|
|
131
|
+
if (exp <= nbf)
|
|
132
|
+
throw new Error('breakglass: window.expires_at must be after window.not_before');
|
|
133
|
+
// An override with no stated cause must never exist — attribution is the deal.
|
|
134
|
+
if (!isNonEmptyString(reason))
|
|
135
|
+
throw new Error('breakglass: reason is required');
|
|
136
|
+
if (!isNonEmptyString(incident_ref))
|
|
137
|
+
throw new Error('breakglass: incident_ref is required');
|
|
138
|
+
const core = {
|
|
139
|
+
scope: { action_types: scope.action_types.slice() },
|
|
140
|
+
// win is guaranteed defined here: nbf/exp are non-null only when
|
|
141
|
+
// win?.not_before / win?.expires_at parsed successfully above.
|
|
142
|
+
window: { not_before: win.not_before, expires_at: win.expires_at },
|
|
143
|
+
reason,
|
|
144
|
+
incident_ref,
|
|
145
|
+
threshold,
|
|
146
|
+
};
|
|
147
|
+
const grant_id = `bg_${sha256hex(canonical(core))}`;
|
|
148
|
+
const payload = { grant_id, ...core };
|
|
149
|
+
const msg = Buffer.from(canonical(payload), 'utf8');
|
|
150
|
+
const signatures = signers.map(({ privateKey, kid }) => ({
|
|
151
|
+
kid,
|
|
152
|
+
algorithm: /** @type {'Ed25519'} */ ('Ed25519'),
|
|
153
|
+
value: crypto.sign(null, msg, privateKey).toString('base64url'),
|
|
154
|
+
}));
|
|
155
|
+
return { '@version': BREAKGLASS_VERSION, payload, signatures };
|
|
156
|
+
}
|
|
157
|
+
/** Resolve a base64url SPKI-DER key for `kid` from a map or an entry list. */
|
|
158
|
+
function issuerKeyFor(issuerKeys, kid) {
|
|
159
|
+
if (!issuerKeys)
|
|
160
|
+
return null;
|
|
161
|
+
if (Array.isArray(issuerKeys)) {
|
|
162
|
+
const e = issuerKeys.find((x) => x && x.kid === kid && typeof x.key === 'string');
|
|
163
|
+
return e ? e.key : null;
|
|
164
|
+
}
|
|
165
|
+
const k = issuerKeys[kid];
|
|
166
|
+
return typeof k === 'string' ? k : null;
|
|
167
|
+
}
|
|
168
|
+
function isPlainObject(value) {
|
|
169
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
170
|
+
return false;
|
|
171
|
+
const prototype = Object.getPrototypeOf(value);
|
|
172
|
+
return prototype === Object.prototype || prototype === null;
|
|
173
|
+
}
|
|
174
|
+
function pinnedKey(key) {
|
|
175
|
+
if (typeof key !== 'string' || !/^[A-Za-z0-9_-]+$/.test(key)) {
|
|
176
|
+
throw new Error('invalid pinned key encoding');
|
|
177
|
+
}
|
|
178
|
+
const bytes = Buffer.from(key, 'base64url');
|
|
179
|
+
if (bytes.length === 0 || bytes.toString('base64url') !== key) {
|
|
180
|
+
throw new Error('non-canonical pinned key encoding');
|
|
181
|
+
}
|
|
182
|
+
const publicKey = crypto.createPublicKey({ key: bytes, format: 'der', type: 'spki' });
|
|
183
|
+
if (publicKey.asymmetricKeyType !== 'ed25519')
|
|
184
|
+
throw new Error('pinned key is not Ed25519');
|
|
185
|
+
const canonicalSpki = publicKey.export({ type: 'spki', format: 'der' });
|
|
186
|
+
return {
|
|
187
|
+
publicKey,
|
|
188
|
+
fingerprint: `sha256:${sha256hex(canonicalSpki)}`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Normalize the relying-party trust policy; presenter material is never used.
|
|
193
|
+
* @returns {{ok:false, reason:string}|{ok:true, minimum_threshold:number, roster:Map<string,{kid:string, principal_id:string, publicKey:import('crypto').KeyObject, fingerprint:string}>}}
|
|
194
|
+
*/
|
|
195
|
+
function normalizePinnedPolicy(policy, issuerKeys) {
|
|
196
|
+
if (!isPlainObject(policy))
|
|
197
|
+
return { ok: false, reason: 'missing_policy' };
|
|
198
|
+
if (!Number.isSafeInteger(policy.minimum_threshold) || policy.minimum_threshold < 2
|
|
199
|
+
|| !Array.isArray(policy.roster)) {
|
|
200
|
+
return { ok: false, reason: 'invalid_policy' };
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const roster = new Map();
|
|
204
|
+
for (const entry of policy.roster) {
|
|
205
|
+
if (!isPlainObject(entry) || !isNonEmptyString(entry.kid)
|
|
206
|
+
|| !isNonEmptyString(entry.principal_id) || roster.has(entry.kid)) {
|
|
207
|
+
return { ok: false, reason: 'invalid_policy' };
|
|
208
|
+
}
|
|
209
|
+
const key = isNonEmptyString(entry.key) ? entry.key : issuerKeyFor(issuerKeys, entry.kid);
|
|
210
|
+
const keyInfo = pinnedKey(key);
|
|
211
|
+
roster.set(entry.kid, {
|
|
212
|
+
kid: entry.kid,
|
|
213
|
+
principal_id: entry.principal_id,
|
|
214
|
+
...keyInfo,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const members = [...roster.values()];
|
|
218
|
+
if (new Set(members.map((entry) => entry.principal_id)).size < policy.minimum_threshold
|
|
219
|
+
|| new Set(members.map((entry) => entry.fingerprint)).size < policy.minimum_threshold) {
|
|
220
|
+
return { ok: false, reason: 'invalid_policy' };
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
ok: true,
|
|
224
|
+
minimum_threshold: policy.minimum_threshold,
|
|
225
|
+
roster,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return { ok: false, reason: 'invalid_policy' };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Verify a break-glass grant against a relying-party-pinned policy. NEVER throws for a
|
|
234
|
+
* bad artifact — every failure resolves to { valid:false, reason } so the
|
|
235
|
+
* refusal itself is loggable. FAILS CLOSED on every path:
|
|
236
|
+
* no_grant | grant_unparseable | grant_malformed | unsupported_version |
|
|
237
|
+
* unsupported_algorithm | invalid_threshold | invalid_scope |
|
|
238
|
+
* missing_reason | missing_incident_ref | missing_policy | invalid_policy |
|
|
239
|
+
* duplicate_signer | duplicate_signer_principal | duplicate_signer_key |
|
|
240
|
+
* policy_threshold_unmet | threshold_unmet | signer_not_in_roster | bad_signature |
|
|
241
|
+
* invalid_validity_window | not_yet_valid | expired |
|
|
242
|
+
* action_type_required | out_of_scope
|
|
243
|
+
*
|
|
244
|
+
* A grant can never nominate its own threshold, roster, identities, or keys.
|
|
245
|
+
* EVERY listed signature must verify against its pinned roster entry — one
|
|
246
|
+
* tampered or unrostered signature refuses the whole grant. The validity window is checked
|
|
247
|
+
* only AFTER the signatures, so the timestamps themselves are authenticated.
|
|
248
|
+
*
|
|
249
|
+
* @param {object|string|null} grantJson the artifact (object or JSON string)
|
|
250
|
+
* @param {object} [o]
|
|
251
|
+
* @param {{minimum_threshold:number,roster:Array<{kid:string,principal_id:string,key?:string}>}} [o.policy] relying-party policy (a missing policy refuses, never throws)
|
|
252
|
+
* @param {object|Array<{kid:string,key:string}>} [o.issuerKeys] optional pinned keys when roster entries omit key
|
|
253
|
+
* @param {number|string|function} [o.now=Date.now] injected clock (ms, ISO, or () => ms)
|
|
254
|
+
* @param {string} [o.actionType] the action the caller wants to override (a missing actionType refuses, never throws)
|
|
255
|
+
* @returns {{ valid: boolean, reason: string, grant_id?: string, incident_ref?: string, scope?: object, window?: object, threshold?: number, required_threshold?: number, policy_minimum_threshold?: number, signer_kids?: string[], signer_principal_ids?: string[], signer_spki_fingerprints?: string[] }}
|
|
256
|
+
*/
|
|
257
|
+
function verifyBreakGlassInternal(grantJson, { policy, issuerKeys, now = Date.now, actionType, } = {}) {
|
|
258
|
+
if (grantJson == null || grantJson === '')
|
|
259
|
+
return refuse('no_grant');
|
|
260
|
+
let doc = grantJson;
|
|
261
|
+
if (typeof doc === 'string') {
|
|
262
|
+
try {
|
|
263
|
+
if (Buffer.byteLength(doc, 'utf8') > 1024 * 1024 || !strictJsonGate(doc).ok)
|
|
264
|
+
return refuse('grant_unparseable');
|
|
265
|
+
doc = JSON.parse(doc);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return refuse('grant_unparseable');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (!doc || typeof doc !== 'object' || Array.isArray(doc))
|
|
272
|
+
return refuse('grant_malformed');
|
|
273
|
+
if (doc['@version'] !== BREAKGLASS_VERSION)
|
|
274
|
+
return refuse('unsupported_version');
|
|
275
|
+
const p = doc.payload;
|
|
276
|
+
const sigs = doc.signatures;
|
|
277
|
+
if (!p || typeof p !== 'object' || !Array.isArray(sigs) || sigs.length === 0) {
|
|
278
|
+
return refuse('grant_malformed');
|
|
279
|
+
}
|
|
280
|
+
if (!isNonEmptyString(p.grant_id))
|
|
281
|
+
return refuse('grant_malformed');
|
|
282
|
+
if (!Number.isInteger(p.threshold) || p.threshold < 1)
|
|
283
|
+
return refuse('invalid_threshold');
|
|
284
|
+
if (!p.scope || !isActionTypeList(p.scope.action_types))
|
|
285
|
+
return refuse('invalid_scope');
|
|
286
|
+
// Attribution is non-optional: an anonymous or causeless override is refused.
|
|
287
|
+
if (!isNonEmptyString(p.reason))
|
|
288
|
+
return refuse('missing_reason');
|
|
289
|
+
if (!isNonEmptyString(p.incident_ref))
|
|
290
|
+
return refuse('missing_incident_ref');
|
|
291
|
+
const pinned = normalizePinnedPolicy(policy, issuerKeys);
|
|
292
|
+
if (!pinned.ok)
|
|
293
|
+
return refuse(pinned.reason);
|
|
294
|
+
for (const s of sigs) {
|
|
295
|
+
if (!s || typeof s !== 'object' || !isNonEmptyString(s.kid) || typeof s.value !== 'string') {
|
|
296
|
+
return refuse('grant_malformed');
|
|
297
|
+
}
|
|
298
|
+
if (s.algorithm !== 'Ed25519')
|
|
299
|
+
return refuse('unsupported_algorithm', { kid: s.kid });
|
|
300
|
+
}
|
|
301
|
+
// Distinct roster slots, pinned human principals, and canonical SPKI keys are
|
|
302
|
+
// independent predicates. Aliases cannot satisfy separation of duties.
|
|
303
|
+
const kids = sigs.map((s) => s.kid);
|
|
304
|
+
if (new Set(kids).size !== kids.length) {
|
|
305
|
+
const dup = kids.find((k, i) => kids.indexOf(k) !== i);
|
|
306
|
+
return refuse('duplicate_signer', { kid: dup });
|
|
307
|
+
}
|
|
308
|
+
const signerEntries = [];
|
|
309
|
+
for (const kid of kids) {
|
|
310
|
+
const entry = pinned.roster.get(kid);
|
|
311
|
+
if (!entry)
|
|
312
|
+
return refuse('signer_not_in_roster', { kid });
|
|
313
|
+
signerEntries.push(entry);
|
|
314
|
+
}
|
|
315
|
+
const principalIds = signerEntries.map((entry) => entry.principal_id);
|
|
316
|
+
if (new Set(principalIds).size !== principalIds.length) {
|
|
317
|
+
const principalId = principalIds.find((id, i) => principalIds.indexOf(id) !== i);
|
|
318
|
+
return refuse('duplicate_signer_principal', { principal_id: principalId });
|
|
319
|
+
}
|
|
320
|
+
const fingerprints = signerEntries.map((entry) => entry.fingerprint);
|
|
321
|
+
if (new Set(fingerprints).size !== fingerprints.length) {
|
|
322
|
+
const fingerprint = fingerprints.find((value, i) => fingerprints.indexOf(value) !== i);
|
|
323
|
+
return refuse('duplicate_signer_key', { spki_fingerprint: fingerprint });
|
|
324
|
+
}
|
|
325
|
+
if (sigs.length < p.threshold) {
|
|
326
|
+
return refuse('threshold_unmet', { threshold: p.threshold, signatures: sigs.length });
|
|
327
|
+
}
|
|
328
|
+
if (sigs.length < pinned.minimum_threshold) {
|
|
329
|
+
return refuse('policy_threshold_unmet', {
|
|
330
|
+
required_threshold: pinned.minimum_threshold,
|
|
331
|
+
presented_threshold: p.threshold,
|
|
332
|
+
signatures: sigs.length,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
// Every listed signature must verify against its pinned roster key. Never
|
|
336
|
+
// count past one failure.
|
|
337
|
+
let msg;
|
|
338
|
+
try {
|
|
339
|
+
msg = Buffer.from(canonical(p), 'utf8');
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
return refuse('grant_malformed');
|
|
343
|
+
}
|
|
344
|
+
for (let i = 0; i < sigs.length; i++) {
|
|
345
|
+
const s = sigs[i];
|
|
346
|
+
let ok;
|
|
347
|
+
try {
|
|
348
|
+
ok = crypto.verify(null, msg, signerEntries[i].publicKey, Buffer.from(s.value, 'base64url'));
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
return refuse('bad_signature', { kid: s.kid });
|
|
352
|
+
}
|
|
353
|
+
if (ok !== true)
|
|
354
|
+
return refuse('bad_signature', { kid: s.kid });
|
|
355
|
+
}
|
|
356
|
+
// Validity window — checked only AFTER the signatures, so the timestamps
|
|
357
|
+
// themselves are authenticated. Both bounds are required; unparseable fails closed.
|
|
358
|
+
let nowMs;
|
|
359
|
+
try {
|
|
360
|
+
nowMs = typeof now === 'function' ? toMs(now()) : toMs(now);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
nowMs = null;
|
|
364
|
+
}
|
|
365
|
+
const nbf = toMs(p.window?.not_before);
|
|
366
|
+
const exp = toMs(p.window?.expires_at);
|
|
367
|
+
if (nbf == null || exp == null || nowMs == null)
|
|
368
|
+
return refuse('invalid_validity_window');
|
|
369
|
+
if (nowMs < nbf)
|
|
370
|
+
return refuse('not_yet_valid', { not_before: p.window.not_before });
|
|
371
|
+
if (nowMs > exp)
|
|
372
|
+
return refuse('expired', { expires_at: p.window.expires_at });
|
|
373
|
+
// Scope: without knowing the action there is nothing to authorize — refuse.
|
|
374
|
+
if (!isNonEmptyString(actionType))
|
|
375
|
+
return refuse('action_type_required');
|
|
376
|
+
if (!p.scope.action_types.includes(actionType)) {
|
|
377
|
+
return refuse('out_of_scope', { action_type: actionType, scope: p.scope.action_types.slice() });
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
valid: true,
|
|
381
|
+
reason: 'breakglass_verified',
|
|
382
|
+
grant_id: p.grant_id,
|
|
383
|
+
incident_ref: p.incident_ref,
|
|
384
|
+
scope: { action_types: p.scope.action_types.slice() },
|
|
385
|
+
window: { not_before: p.window.not_before, expires_at: p.window.expires_at },
|
|
386
|
+
threshold: p.threshold,
|
|
387
|
+
required_threshold: Math.max(p.threshold, pinned.minimum_threshold),
|
|
388
|
+
policy_minimum_threshold: pinned.minimum_threshold,
|
|
389
|
+
signer_kids: kids.slice(),
|
|
390
|
+
signer_principal_ids: principalIds.slice(),
|
|
391
|
+
signer_spki_fingerprints: fingerprints.slice(),
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
export function verifyBreakGlass(grantJson, options = {}) {
|
|
395
|
+
try {
|
|
396
|
+
return verifyBreakGlassInternal(grantJson, options);
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
return refuse('grant_malformed');
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* SINGLE-USE consumption via the consumption-store contract (store.js):
|
|
404
|
+
* `consume(key)` returns true the FIRST time, false on every replay, and marks
|
|
405
|
+
* the key seen BEFORE the caller acts — consumption is committed before use.
|
|
406
|
+
* If the process crashes after consume() and before the override, the grant is
|
|
407
|
+
* burned, not replayable: the fail direction is unusable, never reusable.
|
|
408
|
+
*
|
|
409
|
+
* Accepts the grant document ({ payload: { grant_id } }) or a verified result
|
|
410
|
+
* ({ grant_id }). NEVER throws — a missing store, missing grant_id, or a store
|
|
411
|
+
* error all refuse with a machine-readable reason. This is a low-level primitive;
|
|
412
|
+
* only runBreakGlass also enforces store capabilities, evidence, and execution order.
|
|
413
|
+
*
|
|
414
|
+
* @param {object} grant break-glass grant document or verifyBreakGlass result
|
|
415
|
+
* @param {{ consume(key: string): Promise<boolean> }} store consumption store (store.js contract)
|
|
416
|
+
* @returns {Promise<{ consumed: boolean, reason: string, key?: string }>}
|
|
417
|
+
*/
|
|
418
|
+
export async function consumeBreakGlass(grant, store) {
|
|
419
|
+
const grantId = grant?.payload?.grant_id ?? grant?.grant_id;
|
|
420
|
+
if (!isNonEmptyString(grantId))
|
|
421
|
+
return { consumed: false, reason: 'missing_grant_id' };
|
|
422
|
+
if (!store || typeof store.consume !== 'function') {
|
|
423
|
+
return { consumed: false, reason: 'no_consumption_store' };
|
|
424
|
+
}
|
|
425
|
+
const key = `breakglass:${grantId}`;
|
|
426
|
+
let first = false;
|
|
427
|
+
try {
|
|
428
|
+
first = (await store.consume(key)) === true;
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
// The store could not commit the consumption — fail CLOSED: we cannot
|
|
432
|
+
// prove single-use, so the override must not run.
|
|
433
|
+
return { consumed: false, reason: 'store_error', key };
|
|
434
|
+
}
|
|
435
|
+
if (!first)
|
|
436
|
+
return { consumed: false, reason: 'already_consumed', key };
|
|
437
|
+
return { consumed: true, reason: 'consumed', key };
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Shape an evidence-log entry (kind 'breakglass') committing to the EXACT
|
|
441
|
+
* grant artifact (grant_hash = sha-256 of canonical grant) and the decision
|
|
442
|
+
* taken under it. Append it via the hash-chained evidence log — with
|
|
443
|
+
* { strict: true } so a sink failure refuses the override.
|
|
444
|
+
*
|
|
445
|
+
* This builder does not execute or authorize anything. runBreakGlass is the
|
|
446
|
+
* enforcing path that requires a strict, independently validated record
|
|
447
|
+
* acknowledgement before invoking an effect. This function never throws, even
|
|
448
|
+
* for a malformed grant or missing decision; an uncanonicalizable artifact has
|
|
449
|
+
* a null grant_hash and cannot pass runBreakGlass verification.
|
|
450
|
+
*
|
|
451
|
+
* @param {object} grant the break-glass grant document as presented (even if invalid)
|
|
452
|
+
* @param {object} decision e.g. { allow, reason, action_type } from verify/consume
|
|
453
|
+
* @param {object} [o]
|
|
454
|
+
* @param {number|string|function} [o.now=Date.now] injected clock for the entry timestamp
|
|
455
|
+
* @returns {object} entry ready for createEvidenceLog().record()
|
|
456
|
+
*/
|
|
457
|
+
function buildBreakGlassEvidenceInternal(grant, decision, { now = Date.now } = {}) {
|
|
458
|
+
let nowMs;
|
|
459
|
+
try {
|
|
460
|
+
nowMs = typeof now === 'function' ? toMs(now()) : toMs(now);
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
nowMs = null;
|
|
464
|
+
}
|
|
465
|
+
const p = (grant && typeof grant === 'object' && grant.payload && typeof grant.payload === 'object')
|
|
466
|
+
? grant.payload : null;
|
|
467
|
+
const sigs = (grant && Array.isArray(grant.signatures)) ? grant.signatures : [];
|
|
468
|
+
const d = (decision && typeof decision === 'object') ? decision : {};
|
|
469
|
+
let grantHash = null;
|
|
470
|
+
try {
|
|
471
|
+
grantHash = sha256hex(canonical(grant ?? null));
|
|
472
|
+
}
|
|
473
|
+
catch { /* uncanonicalizable artifacts stay unbound */ }
|
|
474
|
+
const principalIds = Array.isArray(d.signer_principal_ids)
|
|
475
|
+
&& d.signer_principal_ids.every(isNonEmptyString) ? d.signer_principal_ids.slice() : null;
|
|
476
|
+
const fingerprints = Array.isArray(d.signer_spki_fingerprints)
|
|
477
|
+
&& d.signer_spki_fingerprints.every(isNonEmptyString) ? d.signer_spki_fingerprints.slice() : null;
|
|
478
|
+
return {
|
|
479
|
+
kind: BREAKGLASS_EVIDENCE_KIND,
|
|
480
|
+
'@version': BREAKGLASS_VERSION,
|
|
481
|
+
at: new Date(nowMs ?? 0).toISOString(),
|
|
482
|
+
grant_id: p?.grant_id ?? null,
|
|
483
|
+
incident_ref: p?.incident_ref ?? null,
|
|
484
|
+
grant_reason: p?.reason ?? null,
|
|
485
|
+
scope: p?.scope?.action_types?.slice?.() ?? null,
|
|
486
|
+
threshold: p?.threshold ?? null,
|
|
487
|
+
policy_minimum_threshold: Number.isSafeInteger(d.policy_minimum_threshold)
|
|
488
|
+
? d.policy_minimum_threshold : null,
|
|
489
|
+
required_threshold: Number.isSafeInteger(d.required_threshold) ? d.required_threshold : null,
|
|
490
|
+
signer_kids: sigs.map((s) => s?.kid ?? null),
|
|
491
|
+
signer_principal_ids: principalIds,
|
|
492
|
+
signer_spki_fingerprints: fingerprints,
|
|
493
|
+
// Commits the log entry to the exact artifact presented — a later dispute
|
|
494
|
+
// can prove which grant (tampered or not) the decision was taken under.
|
|
495
|
+
grant_hash: grantHash,
|
|
496
|
+
decision: {
|
|
497
|
+
allow: d.allow === true, // fail closed: anything else records a refusal
|
|
498
|
+
reason: isNonEmptyString(d.reason) ? d.reason : 'unspecified',
|
|
499
|
+
action_type: d.action_type ?? null,
|
|
500
|
+
},
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
export function buildBreakGlassEvidence(grant, decision, options = {}) {
|
|
504
|
+
try {
|
|
505
|
+
return buildBreakGlassEvidenceInternal(grant, decision, options);
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
return {
|
|
509
|
+
kind: BREAKGLASS_EVIDENCE_KIND,
|
|
510
|
+
'@version': BREAKGLASS_VERSION,
|
|
511
|
+
at: new Date(0).toISOString(),
|
|
512
|
+
grant_id: null,
|
|
513
|
+
incident_ref: null,
|
|
514
|
+
grant_reason: null,
|
|
515
|
+
scope: null,
|
|
516
|
+
threshold: null,
|
|
517
|
+
policy_minimum_threshold: null,
|
|
518
|
+
required_threshold: null,
|
|
519
|
+
signer_kids: [],
|
|
520
|
+
signer_principal_ids: null,
|
|
521
|
+
signer_spki_fingerprints: null,
|
|
522
|
+
grant_hash: null,
|
|
523
|
+
decision: { allow: false, reason: 'unspecified', action_type: null },
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* The sole high-level break-glass execution path. It snapshots the presented
|
|
529
|
+
* artifact, verifies it against relying-party policy, atomically consumes the
|
|
530
|
+
* grant in a capability-marked permanent store, validates a strict evidence
|
|
531
|
+
* acknowledgement, and only then invokes `effect`.
|
|
532
|
+
*
|
|
533
|
+
* @param {object} [args]
|
|
534
|
+
* @param {object|string} [args.grant] the presented break-glass artifact
|
|
535
|
+
* @param {{minimum_threshold:number,roster:Array<{kid:string,principal_id:string,key?:string}>}} [args.policy]
|
|
536
|
+
* @param {object|Array<{kid:string,key:string}>} [args.issuerKeys]
|
|
537
|
+
* @param {string} [args.actionType]
|
|
538
|
+
* @param {{ consume(key: string): Promise<boolean> }} [args.store]
|
|
539
|
+
* @param {{ strict?: boolean, atomicAppend?: boolean, record?: Function }} [args.evidence]
|
|
540
|
+
* @param {number|string|function} [args.now=Date.now]
|
|
541
|
+
* @param {Function} [effect] required at runtime; a missing effect throws
|
|
542
|
+
*/
|
|
543
|
+
export async function runBreakGlass({ grant, policy, issuerKeys, actionType, store, evidence, now = Date.now, } = {}, effect) {
|
|
544
|
+
if (typeof effect !== 'function')
|
|
545
|
+
throw new Error('runBreakGlass: effect function is required');
|
|
546
|
+
let snapshot;
|
|
547
|
+
try {
|
|
548
|
+
const parsed = typeof grant === 'string' ? JSON.parse(grant) : grant;
|
|
549
|
+
snapshot = JSON.parse(canonical(parsed));
|
|
550
|
+
}
|
|
551
|
+
catch {
|
|
552
|
+
const verification = verifyBreakGlass(grant, { policy, issuerKeys, actionType, now });
|
|
553
|
+
return { ok: false, reason: verification.reason, verification, consumption: null, evidence: null };
|
|
554
|
+
}
|
|
555
|
+
const verification = verifyBreakGlass(snapshot, { policy, issuerKeys, actionType, now });
|
|
556
|
+
if (!verification.valid) {
|
|
557
|
+
return { ok: false, reason: verification.reason, verification, consumption: null, evidence: null };
|
|
558
|
+
}
|
|
559
|
+
if (!isSecureConsumptionStore(store)) {
|
|
560
|
+
return {
|
|
561
|
+
ok: false,
|
|
562
|
+
reason: 'secure_consumption_store_required',
|
|
563
|
+
verification,
|
|
564
|
+
consumption: null,
|
|
565
|
+
evidence: null,
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
if (!evidence || evidence.strict !== true || typeof evidence.record !== 'function') {
|
|
569
|
+
return {
|
|
570
|
+
ok: false,
|
|
571
|
+
reason: 'strict_evidence_required',
|
|
572
|
+
verification,
|
|
573
|
+
consumption: null,
|
|
574
|
+
evidence: null,
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
// store is guaranteed defined here: isSecureConsumptionStore(store) returned
|
|
578
|
+
// true above, which only holds for a store with a callable consume().
|
|
579
|
+
const consume = store.consume.bind(store);
|
|
580
|
+
const record = evidence.record.bind(evidence);
|
|
581
|
+
const consumption = await consumeBreakGlass(verification, { consume });
|
|
582
|
+
if (!consumption.consumed) {
|
|
583
|
+
return { ok: false, reason: consumption.reason, verification, consumption, evidence: null };
|
|
584
|
+
}
|
|
585
|
+
const entry = buildBreakGlassEvidence(snapshot, {
|
|
586
|
+
...verification,
|
|
587
|
+
allow: true,
|
|
588
|
+
action_type: actionType,
|
|
589
|
+
}, { now });
|
|
590
|
+
let evidenceRecord;
|
|
591
|
+
try {
|
|
592
|
+
evidenceRecord = await record(entry);
|
|
593
|
+
if (!verifyEvidenceRecord(evidenceRecord, /** @type {{atomicRequired?: boolean, expectedEntry?: object}} */ ({
|
|
594
|
+
atomicRequired: evidence.atomicAppend === true,
|
|
595
|
+
expectedEntry: entry,
|
|
596
|
+
})))
|
|
597
|
+
throw new Error('malformed evidence acknowledgement');
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
return {
|
|
601
|
+
ok: false,
|
|
602
|
+
reason: 'evidence_record_failed',
|
|
603
|
+
verification,
|
|
604
|
+
consumption,
|
|
605
|
+
evidence: null,
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
const result = await effect({ verification, consumption, evidence: evidenceRecord });
|
|
609
|
+
return {
|
|
610
|
+
ok: true,
|
|
611
|
+
reason: 'breakglass_executed',
|
|
612
|
+
result,
|
|
613
|
+
verification,
|
|
614
|
+
consumption,
|
|
615
|
+
evidence: evidenceRecord,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
export default {
|
|
619
|
+
mintBreakGlassAuthorization,
|
|
620
|
+
verifyBreakGlass,
|
|
621
|
+
consumeBreakGlass,
|
|
622
|
+
buildBreakGlassEvidence,
|
|
623
|
+
runBreakGlass,
|
|
624
|
+
BREAKGLASS_VERSION,
|
|
625
|
+
BREAKGLASS_EVIDENCE_KIND,
|
|
626
|
+
};
|
|
627
|
+
//# sourceMappingURL=breakglass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakglass.js","sourceRoot":"","sources":["../src/breakglass.ts"],"names":[],"mappings":"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"}
|