@coderifts/agent-guard 15.0.0 → 16.0.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/README.md +3 -1
- package/dist/cjs/adapters/crewai.d.ts +88 -0
- package/dist/cjs/adapters/crewai.d.ts.map +1 -0
- package/dist/cjs/adapters/crewai.js +99 -0
- package/dist/cjs/adapters/crewai.js.map +1 -0
- package/dist/cjs/adapters/langchain.d.ts +93 -0
- package/dist/cjs/adapters/langchain.d.ts.map +1 -0
- package/dist/cjs/adapters/langchain.js +99 -0
- package/dist/cjs/adapters/langchain.js.map +1 -0
- package/dist/cjs/deploy-gate.d.ts +18 -0
- package/dist/cjs/deploy-gate.d.ts.map +1 -1
- package/dist/cjs/deploy-gate.js +18 -6
- package/dist/cjs/deploy-gate.js.map +1 -1
- package/dist/cjs/deploy-receipt-token.d.ts +7 -0
- package/dist/cjs/deploy-receipt-token.d.ts.map +1 -1
- package/dist/cjs/deploy-receipt-token.js +6 -0
- package/dist/cjs/deploy-receipt-token.js.map +1 -1
- package/dist/cjs/execution-grant.d.ts +4 -2
- package/dist/cjs/execution-grant.d.ts.map +1 -1
- package/dist/cjs/execution-grant.js +6 -0
- package/dist/cjs/execution-grant.js.map +1 -1
- package/dist/cjs/guard.d.ts.map +1 -1
- package/dist/cjs/guard.js +63 -0
- package/dist/cjs/guard.js.map +1 -1
- package/dist/cjs/index.d.ts +10 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +33 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/next-agent-step.d.ts +50 -0
- package/dist/cjs/next-agent-step.d.ts.map +1 -0
- package/dist/cjs/next-agent-step.js +53 -0
- package/dist/cjs/next-agent-step.js.map +1 -0
- package/dist/cjs/offline-verify.d.ts +75 -0
- package/dist/cjs/offline-verify.d.ts.map +1 -0
- package/dist/cjs/offline-verify.js +74 -0
- package/dist/cjs/offline-verify.js.map +1 -0
- package/dist/cjs/policy.d.ts.map +1 -1
- package/dist/cjs/policy.js +1 -1
- package/dist/cjs/policy.js.map +1 -1
- package/dist/cjs/types.d.ts +64 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/unguarded-mutation.d.ts +76 -0
- package/dist/cjs/unguarded-mutation.d.ts.map +1 -0
- package/dist/cjs/unguarded-mutation.js +101 -0
- package/dist/cjs/unguarded-mutation.js.map +1 -0
- package/dist/cjs/vendor/VENDOR.sha256 +13 -0
- package/dist/cjs/vendor/arity.js +53 -0
- package/dist/cjs/vendor/verify.js +454 -0
- package/dist/cjs/with-coderifts.d.ts +21 -0
- package/dist/cjs/with-coderifts.d.ts.map +1 -1
- package/dist/cjs/with-coderifts.js +42 -1
- package/dist/cjs/with-coderifts.js.map +1 -1
- package/dist/esm/adapters/crewai.d.ts +88 -0
- package/dist/esm/adapters/crewai.d.ts.map +1 -0
- package/dist/esm/adapters/crewai.js +95 -0
- package/dist/esm/adapters/crewai.js.map +1 -0
- package/dist/esm/adapters/langchain.d.ts +93 -0
- package/dist/esm/adapters/langchain.d.ts.map +1 -0
- package/dist/esm/adapters/langchain.js +94 -0
- package/dist/esm/adapters/langchain.js.map +1 -0
- package/dist/esm/deploy-gate.d.ts +18 -0
- package/dist/esm/deploy-gate.d.ts.map +1 -1
- package/dist/esm/deploy-gate.js +18 -6
- package/dist/esm/deploy-gate.js.map +1 -1
- package/dist/esm/deploy-receipt-token.d.ts +7 -0
- package/dist/esm/deploy-receipt-token.d.ts.map +1 -1
- package/dist/esm/deploy-receipt-token.js +6 -0
- package/dist/esm/deploy-receipt-token.js.map +1 -1
- package/dist/esm/execution-grant.d.ts +4 -2
- package/dist/esm/execution-grant.d.ts.map +1 -1
- package/dist/esm/execution-grant.js +6 -0
- package/dist/esm/execution-grant.js.map +1 -1
- package/dist/esm/guard.d.ts.map +1 -1
- package/dist/esm/guard.js +63 -0
- package/dist/esm/guard.js.map +1 -1
- package/dist/esm/index.d.ts +10 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +18 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/next-agent-step.d.ts +50 -0
- package/dist/esm/next-agent-step.d.ts.map +1 -0
- package/dist/esm/next-agent-step.js +49 -0
- package/dist/esm/next-agent-step.js.map +1 -0
- package/dist/esm/offline-verify.d.ts +75 -0
- package/dist/esm/offline-verify.d.ts.map +1 -0
- package/dist/esm/offline-verify.js +70 -0
- package/dist/esm/offline-verify.js.map +1 -0
- package/dist/esm/policy.d.ts.map +1 -1
- package/dist/esm/policy.js +1 -1
- package/dist/esm/policy.js.map +1 -1
- package/dist/esm/types.d.ts +64 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/unguarded-mutation.d.ts +76 -0
- package/dist/esm/unguarded-mutation.d.ts.map +1 -0
- package/dist/esm/unguarded-mutation.js +97 -0
- package/dist/esm/unguarded-mutation.js.map +1 -0
- package/dist/esm/vendor/VENDOR.sha256 +13 -0
- package/dist/esm/vendor/arity.js +53 -0
- package/dist/esm/vendor/verify.js +454 -0
- package/dist/esm/with-coderifts.d.ts +21 -0
- package/dist/esm/with-coderifts.d.ts.map +1 -1
- package/dist/esm/with-coderifts.js +40 -0
- package/dist/esm/with-coderifts.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 1356 — the host is the FIRST gate in the inescapability order (host → model → registry → CI),
|
|
3
|
+
* and until now it was the only one of the four that let a mutating call through by default.
|
|
4
|
+
*
|
|
5
|
+
* ── WHAT WAS ALREADY FAIL-CLOSED, MEASURED 2026-09-04 ───────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* Three of the four cases in the brief were ALREADY blocked by default, and the flip must not be
|
|
8
|
+
* described as if it closed them:
|
|
9
|
+
*
|
|
10
|
+
* contract call + NO receipt UNAVAILABLE / RECEIPT_MISSING guard.ts:981,1067
|
|
11
|
+
* contract call + unknown key UNAVAILABLE / RECEIPT_UNVERIFIED guard.ts:813
|
|
12
|
+
* contract call + STOP BLOCK guard.ts:854
|
|
13
|
+
*
|
|
14
|
+
* `enforceable = receiptVerified && …` (guard.ts:981) is the invariant that does it: the guard
|
|
15
|
+
* never runs the factory as enforced without a bound receipt. `requireReceipt: 'fail-closed'`
|
|
16
|
+
* (1307) fires earlier on the same fact; it is not what stood between a stranger and execution.
|
|
17
|
+
*
|
|
18
|
+
* ── THE GAP THAT WAS REAL ───────────────────────────────────────────────────────────────────
|
|
19
|
+
*
|
|
20
|
+
* All three depend on the DETECTOR having triggered. The detector fires on contract artifacts —
|
|
21
|
+
* OpenAPI, GraphQL, protobuf, MCP manifests. A call it does not recognise takes the SKIPPED path
|
|
22
|
+
* (guard.ts:600) and executes with `preflighted:false, enforced:false`. Measured, by default:
|
|
23
|
+
*
|
|
24
|
+
* Read README.md SKIPPED → executed (correct)
|
|
25
|
+
* Edit src/app.py old_string/new_string SKIPPED → executed ← mutation, unguarded
|
|
26
|
+
* Write deploy.sh content: 'rm -rf /' SKIPPED → executed ← mutation, unguarded
|
|
27
|
+
*
|
|
28
|
+
* "Not a contract change" is a true statement about the ARTIFACT and it was being used as a
|
|
29
|
+
* decision about the ACTION. The host wrapped the tool, the guard saw the call, and the write
|
|
30
|
+
* happened anyway with nothing signed.
|
|
31
|
+
*
|
|
32
|
+
* ── THE FLIP ────────────────────────────────────────────────────────────────────────────────
|
|
33
|
+
*
|
|
34
|
+
* A mutating call that reaches the end of the guard with no verified receipt is BLOCKED by
|
|
35
|
+
* default. Advisory remains available and is now a NAMED choice — `CODERIFTS_ADVISORY=1`, or
|
|
36
|
+
* `requireGuardedMutation: 'advisory'` — and it WARNS every time. `verify_ssl=false` is the
|
|
37
|
+
* comparison: a real option, spelled out loud, never the silent default.
|
|
38
|
+
*
|
|
39
|
+
* ── WHAT THIS DELIBERATELY DOES NOT DO ──────────────────────────────────────────────────────
|
|
40
|
+
*
|
|
41
|
+
* It does not widen `isMutatingCall` (freshness.ts:433). That predicate is shared with the
|
|
42
|
+
* conditional-write policy (guard.ts:495), so widening it here would silently change a second,
|
|
43
|
+
* unrelated gate. The consequence is a MEASURED RESIDUAL, and it should be read as a limit of
|
|
44
|
+
* this change rather than a property of it: `Bash { command: 'kubectl apply -f prod.yaml' }` is
|
|
45
|
+
* NOT classified mutating — the predicate reads contents/content/new_string/old_string/patch/
|
|
46
|
+
* edits, and `command` is not among them. A shell command that mutates production still takes the
|
|
47
|
+
* SKIPPED path. Closing that needs the predicate widened WITH the conditional-write blast radius
|
|
48
|
+
* measured, which is a separate change.
|
|
49
|
+
*
|
|
50
|
+
* An explicit `requireGuardedMutation: 'fail-closed'` is NOT overridable by the environment. An
|
|
51
|
+
* escape hatch that can undo a decision the host wrote down is not an escape hatch, it is a
|
|
52
|
+
* bypass, and anyone who can set an environment variable would hold it.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* 'fail-closed' default — a mutating call with no verified receipt does not execute.
|
|
56
|
+
* 'advisory' execute anyway, and warn every time. Deliberate, named, and loud.
|
|
57
|
+
*/
|
|
58
|
+
export type GuardedMutationPolicy = 'fail-closed' | 'advisory';
|
|
59
|
+
export declare const ADVISORY_ENV_VAR = "CODERIFTS_ADVISORY";
|
|
60
|
+
export interface UnguardedMutationDecision {
|
|
61
|
+
/** Refuse to execute. */
|
|
62
|
+
readonly stop: boolean;
|
|
63
|
+
/** Executing anyway under advisory — the caller MUST surface this; silence is the failure mode. */
|
|
64
|
+
readonly warn?: string;
|
|
65
|
+
/** Why, in terms of what is at risk. */
|
|
66
|
+
readonly detail?: string;
|
|
67
|
+
/** Which input produced the advisory outcome, so a report can say who chose it. */
|
|
68
|
+
readonly source?: 'config' | 'environment';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @param mutating isMutatingCall() over the REDACTED descriptor — never the raw one.
|
|
72
|
+
* @param policy host configuration; undefined means the new default.
|
|
73
|
+
* @param env process.env, injected so this stays a pure function and is testable.
|
|
74
|
+
*/
|
|
75
|
+
export declare function decideUnguardedMutation(mutating: boolean, policy: GuardedMutationPolicy | undefined, env: Record<string, string | undefined>): UnguardedMutationDecision;
|
|
76
|
+
//# sourceMappingURL=unguarded-mutation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unguarded-mutation.d.ts","sourceRoot":"","sources":["../../src/unguarded-mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,UAAU,CAAC;AAK/D,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACxC,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,mGAAmG;IACnG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;CAC5C;AAOD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,qBAAqB,GAAG,SAAS,EACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,yBAAyB,CAoC3B"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 1356 — the host is the FIRST gate in the inescapability order (host → model → registry → CI),
|
|
4
|
+
* and until now it was the only one of the four that let a mutating call through by default.
|
|
5
|
+
*
|
|
6
|
+
* ── WHAT WAS ALREADY FAIL-CLOSED, MEASURED 2026-09-04 ───────────────────────────────────────
|
|
7
|
+
*
|
|
8
|
+
* Three of the four cases in the brief were ALREADY blocked by default, and the flip must not be
|
|
9
|
+
* described as if it closed them:
|
|
10
|
+
*
|
|
11
|
+
* contract call + NO receipt UNAVAILABLE / RECEIPT_MISSING guard.ts:981,1067
|
|
12
|
+
* contract call + unknown key UNAVAILABLE / RECEIPT_UNVERIFIED guard.ts:813
|
|
13
|
+
* contract call + STOP BLOCK guard.ts:854
|
|
14
|
+
*
|
|
15
|
+
* `enforceable = receiptVerified && …` (guard.ts:981) is the invariant that does it: the guard
|
|
16
|
+
* never runs the factory as enforced without a bound receipt. `requireReceipt: 'fail-closed'`
|
|
17
|
+
* (1307) fires earlier on the same fact; it is not what stood between a stranger and execution.
|
|
18
|
+
*
|
|
19
|
+
* ── THE GAP THAT WAS REAL ───────────────────────────────────────────────────────────────────
|
|
20
|
+
*
|
|
21
|
+
* All three depend on the DETECTOR having triggered. The detector fires on contract artifacts —
|
|
22
|
+
* OpenAPI, GraphQL, protobuf, MCP manifests. A call it does not recognise takes the SKIPPED path
|
|
23
|
+
* (guard.ts:600) and executes with `preflighted:false, enforced:false`. Measured, by default:
|
|
24
|
+
*
|
|
25
|
+
* Read README.md SKIPPED → executed (correct)
|
|
26
|
+
* Edit src/app.py old_string/new_string SKIPPED → executed ← mutation, unguarded
|
|
27
|
+
* Write deploy.sh content: 'rm -rf /' SKIPPED → executed ← mutation, unguarded
|
|
28
|
+
*
|
|
29
|
+
* "Not a contract change" is a true statement about the ARTIFACT and it was being used as a
|
|
30
|
+
* decision about the ACTION. The host wrapped the tool, the guard saw the call, and the write
|
|
31
|
+
* happened anyway with nothing signed.
|
|
32
|
+
*
|
|
33
|
+
* ── THE FLIP ────────────────────────────────────────────────────────────────────────────────
|
|
34
|
+
*
|
|
35
|
+
* A mutating call that reaches the end of the guard with no verified receipt is BLOCKED by
|
|
36
|
+
* default. Advisory remains available and is now a NAMED choice — `CODERIFTS_ADVISORY=1`, or
|
|
37
|
+
* `requireGuardedMutation: 'advisory'` — and it WARNS every time. `verify_ssl=false` is the
|
|
38
|
+
* comparison: a real option, spelled out loud, never the silent default.
|
|
39
|
+
*
|
|
40
|
+
* ── WHAT THIS DELIBERATELY DOES NOT DO ──────────────────────────────────────────────────────
|
|
41
|
+
*
|
|
42
|
+
* It does not widen `isMutatingCall` (freshness.ts:433). That predicate is shared with the
|
|
43
|
+
* conditional-write policy (guard.ts:495), so widening it here would silently change a second,
|
|
44
|
+
* unrelated gate. The consequence is a MEASURED RESIDUAL, and it should be read as a limit of
|
|
45
|
+
* this change rather than a property of it: `Bash { command: 'kubectl apply -f prod.yaml' }` is
|
|
46
|
+
* NOT classified mutating — the predicate reads contents/content/new_string/old_string/patch/
|
|
47
|
+
* edits, and `command` is not among them. A shell command that mutates production still takes the
|
|
48
|
+
* SKIPPED path. Closing that needs the predicate widened WITH the conditional-write blast radius
|
|
49
|
+
* measured, which is a separate change.
|
|
50
|
+
*
|
|
51
|
+
* An explicit `requireGuardedMutation: 'fail-closed'` is NOT overridable by the environment. An
|
|
52
|
+
* escape hatch that can undo a decision the host wrote down is not an escape hatch, it is a
|
|
53
|
+
* bypass, and anyone who can set an environment variable would hold it.
|
|
54
|
+
*/
|
|
55
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
+
exports.ADVISORY_ENV_VAR = void 0;
|
|
57
|
+
exports.decideUnguardedMutation = decideUnguardedMutation;
|
|
58
|
+
/** The named opt-out. Compared against exactly these, so `CODERIFTS_ADVISORY=0` is not advisory. */
|
|
59
|
+
const ADVISORY_TRUE = new Set(['1', 'true', 'yes', 'on']);
|
|
60
|
+
exports.ADVISORY_ENV_VAR = 'CODERIFTS_ADVISORY';
|
|
61
|
+
const RISK = 'A mutating tool call reached the guard with no verified receipt: the detector did not '
|
|
62
|
+
+ 'recognise a contract artifact, so nothing was preflighted and nothing was signed. "Not a '
|
|
63
|
+
+ 'contract change" describes the artifact, not the action — the write still happens.';
|
|
64
|
+
/**
|
|
65
|
+
* @param mutating isMutatingCall() over the REDACTED descriptor — never the raw one.
|
|
66
|
+
* @param policy host configuration; undefined means the new default.
|
|
67
|
+
* @param env process.env, injected so this stays a pure function and is testable.
|
|
68
|
+
*/
|
|
69
|
+
function decideUnguardedMutation(mutating, policy, env) {
|
|
70
|
+
// Read tools are the whole reason this is gated on mutation rather than on "was it preflighted".
|
|
71
|
+
if (!mutating)
|
|
72
|
+
return { stop: false };
|
|
73
|
+
if (policy === 'advisory') {
|
|
74
|
+
return {
|
|
75
|
+
stop: false,
|
|
76
|
+
source: 'config',
|
|
77
|
+
detail: RISK,
|
|
78
|
+
warn: 'CodeRifts: ADVISORY — executing an unguarded mutating tool call. '
|
|
79
|
+
+ 'requireGuardedMutation is set to \'advisory\', so the guard is reporting rather than '
|
|
80
|
+
+ 'enforcing. ' + RISK,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// An explicit fail-closed outranks the environment. Checked BEFORE reading env on purpose.
|
|
84
|
+
if (policy !== 'fail-closed' && ADVISORY_TRUE.has(String(env[exports.ADVISORY_ENV_VAR] ?? '').toLowerCase())) {
|
|
85
|
+
return {
|
|
86
|
+
stop: false,
|
|
87
|
+
source: 'environment',
|
|
88
|
+
detail: RISK,
|
|
89
|
+
warn: `CodeRifts: ADVISORY — executing an unguarded mutating tool call because `
|
|
90
|
+
+ `${exports.ADVISORY_ENV_VAR} is set. This is the documented opt-out and it is not the default. `
|
|
91
|
+
+ RISK,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
stop: true,
|
|
96
|
+
detail: RISK + ' Blocked by default. To proceed without a receipt, choose it explicitly: set '
|
|
97
|
+
+ `${exports.ADVISORY_ENV_VAR}=1 or requireGuardedMutation: 'advisory'. To proceed WITH one, send `
|
|
98
|
+
+ 'the change through preflight so there is something to verify.',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=unguarded-mutation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unguarded-mutation.js","sourceRoot":"","sources":["../../src/unguarded-mutation.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;;;AAkCH,0DAwCC;AAlED,oGAAoG;AACpG,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AAE7C,QAAA,gBAAgB,GAAG,oBAAoB,CAAC;AAarD,MAAM,IAAI,GACR,wFAAwF;MACtF,2FAA2F;MAC3F,oFAAoF,CAAC;AAEzF;;;;GAIG;AACH,SAAgB,uBAAuB,CACrC,QAAiB,EACjB,MAAyC,EACzC,GAAuC;IAEvC,iGAAiG;IACjG,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAEtC,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,IAAI;YACZ,IAAI,EACF,mEAAmE;kBACjE,uFAAuF;kBACvF,aAAa,GAAG,IAAI;SACzB,CAAC;IACJ,CAAC;IAED,2FAA2F;IAC3F,IAAI,MAAM,KAAK,aAAa,IAAI,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,wBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACrG,OAAO;YACL,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,IAAI;YACZ,IAAI,EACF,0EAA0E;kBACxE,GAAG,wBAAgB,qEAAqE;kBACxF,IAAI;SACT,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,IAAI;QACV,MAAM,EACJ,IAAI,GAAG,+EAA+E;cACpF,GAAG,wBAAgB,sEAAsE;cACzF,+DAA+D;KACpE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Vendored verify core — the OFFLINE receipt verifier (1307).
|
|
2
|
+
#
|
|
3
|
+
# Byte copies from the public receipt-verifier, pinned. The guard used to verify over the
|
|
4
|
+
# NETWORK via config.client.verifyReceipt(), which the other three enforcement points do not:
|
|
5
|
+
# contract-gate, k8s-admission and gateway-verifier all verify offline against a pinned keyring.
|
|
6
|
+
# A verifier that needs the network fails differently from one that does not, and the sentence
|
|
7
|
+
# "the same proof at all four points, offline" was false because of this one.
|
|
8
|
+
#
|
|
9
|
+
# Do not edit these files here. Recopy from receipt-verifier and re-pin.
|
|
10
|
+
# source: receipt-verifier e11d3f5d9f5444d8b2a07428c922d2040f4819ce
|
|
11
|
+
|
|
12
|
+
verify.js 363e52c72ec4b913e1f3edc8e2029848feaeacb1efa6c07960fe5e5f195c23b3
|
|
13
|
+
arity.js 721fcac58b960b5e2aa1af91edb6cfc87ebe828a6da73879967ef79a1ca474e8
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 1129 — unified (token, opts) with opts.ctx / opts.intended.
|
|
5
|
+
* 3-ary (token, ctx, opts) wrappers warn once and forward.
|
|
6
|
+
* 2-ary verifiers keep the 1128 throw on a third argument.
|
|
7
|
+
*/
|
|
8
|
+
const warned = new Set();
|
|
9
|
+
|
|
10
|
+
function warnOnce(name) {
|
|
11
|
+
if (warned.has(name)) return;
|
|
12
|
+
warned.add(name);
|
|
13
|
+
const msg = `DEPRECATION: ${name}(token, ctx, opts) is deprecated; use ${name}(token, { ctx, intended }). This warning is emitted once.`;
|
|
14
|
+
if (typeof process !== 'undefined' && typeof process.emitWarning === 'function') {
|
|
15
|
+
process.emitWarning(msg, 'DeprecationWarning');
|
|
16
|
+
} else {
|
|
17
|
+
console.warn(msg);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function throw1128(name, n, consequence) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`${name}(token, opts) — pass intended via opts.intended. `
|
|
24
|
+
+ `Received ${n} arguments; the third would be ignored and the cross-check `
|
|
25
|
+
+ `would silently not run, grading a mismatched artifact ${consequence}.`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function looksUnified(obj) {
|
|
30
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return false;
|
|
31
|
+
// perSlot is the bundle-dispatch unified shape: verifyBundle(bundle, { ctx, perSlot }).
|
|
32
|
+
// Without it, `{ perSlot }` was treated as a bare ctx and opts.perSlot vanished.
|
|
33
|
+
return obj.ctx != null || obj.intended != null || obj.envelope != null || obj.perSlot != null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function split3ary(name, nArgs, second, third) {
|
|
37
|
+
if (nArgs > 3) throw1128(name, nArgs, 'VALID');
|
|
38
|
+
if (nArgs === 3) {
|
|
39
|
+
warnOnce(name);
|
|
40
|
+
return { ctx: second || {}, opts: third && typeof third === 'object' ? third : {} };
|
|
41
|
+
}
|
|
42
|
+
const o = second && typeof second === 'object' ? second : {};
|
|
43
|
+
if (looksUnified(o)) {
|
|
44
|
+
return { ctx: o.ctx || {}, opts: o };
|
|
45
|
+
}
|
|
46
|
+
return { ctx: o, opts: {} };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function _resetWarnedForTest() {
|
|
50
|
+
warned.clear();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { warnOnce, throw1128, split3ary, looksUnified, _resetWarnedForTest };
|