@goodmeta/agent-verifier 0.2.0 → 0.6.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.
Files changed (78) hide show
  1. package/README.md +67 -26
  2. package/dist/ap2/chain.d.ts +43 -0
  3. package/dist/ap2/chain.d.ts.map +1 -0
  4. package/dist/ap2/chain.js +100 -0
  5. package/dist/ap2/chain.js.map +1 -0
  6. package/dist/ap2/chains.d.ts +68 -0
  7. package/dist/ap2/chains.d.ts.map +1 -0
  8. package/dist/ap2/chains.js +119 -0
  9. package/dist/ap2/chains.js.map +1 -0
  10. package/dist/ap2/constraints.d.ts +47 -0
  11. package/dist/ap2/constraints.d.ts.map +1 -0
  12. package/dist/ap2/constraints.js +231 -0
  13. package/dist/ap2/constraints.js.map +1 -0
  14. package/dist/ap2/hash.d.ts +23 -0
  15. package/dist/ap2/hash.d.ts.map +1 -0
  16. package/dist/ap2/hash.js +54 -0
  17. package/dist/ap2/hash.js.map +1 -0
  18. package/dist/ap2/index.d.ts +28 -0
  19. package/dist/ap2/index.d.ts.map +1 -0
  20. package/dist/ap2/index.js +35 -0
  21. package/dist/ap2/index.js.map +1 -0
  22. package/dist/ap2/jwk.d.ts +24 -0
  23. package/dist/ap2/jwk.d.ts.map +1 -0
  24. package/dist/ap2/jwk.js +29 -0
  25. package/dist/ap2/jwk.js.map +1 -0
  26. package/dist/ap2/kb-sd-jwt.d.ts +44 -0
  27. package/dist/ap2/kb-sd-jwt.d.ts.map +1 -0
  28. package/dist/ap2/kb-sd-jwt.js +97 -0
  29. package/dist/ap2/kb-sd-jwt.js.map +1 -0
  30. package/dist/ap2/keys.d.ts +41 -0
  31. package/dist/ap2/keys.d.ts.map +1 -0
  32. package/dist/ap2/keys.js +114 -0
  33. package/dist/ap2/keys.js.map +1 -0
  34. package/dist/ap2/max-flow.d.ts +26 -0
  35. package/dist/ap2/max-flow.d.ts.map +1 -0
  36. package/dist/ap2/max-flow.js +173 -0
  37. package/dist/ap2/max-flow.js.map +1 -0
  38. package/dist/ap2/parse.d.ts +35 -0
  39. package/dist/ap2/parse.d.ts.map +1 -0
  40. package/dist/ap2/parse.js +78 -0
  41. package/dist/ap2/parse.js.map +1 -0
  42. package/dist/ap2/sd-jwt.d.ts +83 -0
  43. package/dist/ap2/sd-jwt.d.ts.map +1 -0
  44. package/dist/ap2/sd-jwt.js +306 -0
  45. package/dist/ap2/sd-jwt.js.map +1 -0
  46. package/dist/ap2/types.d.ts +270 -0
  47. package/dist/ap2/types.d.ts.map +1 -0
  48. package/dist/ap2/types.js +141 -0
  49. package/dist/ap2/types.js.map +1 -0
  50. package/dist/client.d.ts +152 -0
  51. package/dist/client.d.ts.map +1 -0
  52. package/dist/client.js +171 -0
  53. package/dist/client.js.map +1 -0
  54. package/dist/index.d.ts +27 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +30 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/policy.d.ts +45 -0
  59. package/dist/policy.d.ts.map +1 -0
  60. package/dist/policy.js +88 -0
  61. package/dist/policy.js.map +1 -0
  62. package/dist/receipt-jwt.d.ts +30 -0
  63. package/dist/receipt-jwt.d.ts.map +1 -0
  64. package/dist/receipt-jwt.js +39 -0
  65. package/dist/receipt-jwt.js.map +1 -0
  66. package/dist/schema.d.ts +41 -0
  67. package/dist/schema.d.ts.map +1 -0
  68. package/dist/schema.js +50 -0
  69. package/dist/schema.js.map +1 -0
  70. package/dist/types.d.ts +116 -0
  71. package/dist/types.d.ts.map +1 -0
  72. package/dist/types.js +8 -0
  73. package/dist/types.js.map +1 -0
  74. package/dist/verify.d.ts +24 -0
  75. package/dist/verify.d.ts.map +1 -0
  76. package/dist/verify.js +69 -0
  77. package/dist/verify.js.map +1 -0
  78. package/package.json +14 -7
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Payment-constraint evaluation — line-for-line port of AP2's
3
+ * `sdk/constraints.py` (commit e1ea56d). Each evaluator returns a list of
4
+ * violation messages ([] = satisfied). Violation strings match AP2's f-strings
5
+ * byte-for-byte where the inputs are reproducible (amounts, ids, names, dates);
6
+ * the few AP2 messages that embed a Python object `repr` (pisp / pre-set
7
+ * amount+instrument) are noted and use a readable JSON form instead — only the
8
+ * violation COUNT is asserted against AP2 for those.
9
+ *
10
+ * Closed-world rule (AUTH-15 / SPEC-39): an UNKNOWN constraint type MUST be
11
+ * treated as failing evaluation.
12
+ */
13
+ import { KnownPaymentConstraintSchema, KnownCheckoutConstraintSchema, } from "./types.js";
14
+ import { evaluateLineItemsMaxFlow } from "./max-flow.js";
15
+ /** Port of `merchant_matches`: id-first, else name+website (both non-empty). */
16
+ export function merchantMatches(candidate, target) {
17
+ if (candidate.id && target.id)
18
+ return candidate.id === target.id;
19
+ return (candidate.name === target.name &&
20
+ Boolean(candidate.name) &&
21
+ candidate.website === target.website &&
22
+ Boolean(candidate.website));
23
+ }
24
+ function amountsEqual(a, b) {
25
+ return a?.amount === b?.amount && a?.currency === b?.currency;
26
+ }
27
+ /** Field-wise instrument equality with null/omitted normalized (matches AP2's
28
+ * pydantic model equality, where `description: null` == omitted). */
29
+ function instrumentsEqual(a, b) {
30
+ return a.id === b.id && a.type === b.type && (a.description ?? null) === (b.description ?? null);
31
+ }
32
+ // ── Per-constraint evaluators (return violation messages) ────────────────────
33
+ function amountRange(c, closed) {
34
+ const v = [];
35
+ const amount = closed.payment_amount;
36
+ if (c.currency && amount.currency !== c.currency) {
37
+ v.push(`Currency mismatch: expected ${c.currency}, got ${amount.currency}`);
38
+ }
39
+ if (c.min !== undefined && c.min !== null && amount.amount < c.min) {
40
+ v.push(`Amount ${amount.amount} below minimum ${c.min}`);
41
+ }
42
+ if (c.max !== undefined && c.max !== null && amount.amount > c.max) {
43
+ v.push(`Amount ${amount.amount} exceeds maximum ${c.max}`);
44
+ }
45
+ return v;
46
+ }
47
+ function allowedPayees(c, closed) {
48
+ const payee = closed.payee;
49
+ if (c.allowed.some((a) => merchantMatches(a, payee)))
50
+ return [];
51
+ return [`Payee ${payee.name} not in allowed list`];
52
+ }
53
+ function paymentReference(c, ctx) {
54
+ if (!ctx.openCheckoutHash) {
55
+ return ["open_checkout_hash is required to evaluate PaymentReference constraints"];
56
+ }
57
+ if (ctx.openCheckoutHash !== c.conditional_transaction_id) {
58
+ return [
59
+ `PaymentReference mismatch: expected open checkout hash ${c.conditional_transaction_id}, got ${ctx.openCheckoutHash}`,
60
+ ];
61
+ }
62
+ return [];
63
+ }
64
+ function agentRecurrence(c, ctx) {
65
+ const limit = c.max_occurrences;
66
+ if (limit === undefined || limit === null)
67
+ return [];
68
+ if (!ctx.mandateContext)
69
+ return ["Missing mandate context required to evaluate recurrence"];
70
+ const count = ctx.mandateContext.total_uses;
71
+ if (count >= limit)
72
+ return [`Maximum occurrences exceeded: ${count} >= ${limit}`];
73
+ return [];
74
+ }
75
+ function allowedPaymentInstruments(c, closed) {
76
+ const instrument = closed.payment_instrument;
77
+ if (!instrument)
78
+ return ["Missing payment instrument in closed mandate"];
79
+ if (c.allowed.some((a) => a.id === instrument.id))
80
+ return [];
81
+ return [`Payment instrument ${instrument.id} not in allowed list`];
82
+ }
83
+ function allowedPisps(c, closed) {
84
+ const pisp = closed.pisp;
85
+ if (!pisp)
86
+ return ["Missing PISP in closed mandate"];
87
+ if (c.allowed.some((a) => a.domain_name === pisp.domain_name && a.legal_name === pisp.legal_name && a.brand_name === pisp.brand_name)) {
88
+ return [];
89
+ }
90
+ // AP2 embeds a Python repr here; we use a readable form (count is what's asserted).
91
+ return [`PISP ${JSON.stringify(pisp)} not in allowed list`];
92
+ }
93
+ function budget(c, closed, ctx) {
94
+ if (closed.payment_amount.currency !== c.currency) {
95
+ return [`Budget currency mismatch: expected ${c.currency}, got ${closed.payment_amount.currency}`];
96
+ }
97
+ if (!ctx.mandateContext)
98
+ return ["Missing mandate context required to evaluate budget"];
99
+ const pastSpend = ctx.mandateContext.total_amount;
100
+ const totalSpend = pastSpend + closed.payment_amount.amount;
101
+ const budgetMaxCents = Math.trunc(c.max * 100);
102
+ if (totalSpend > budgetMaxCents) {
103
+ return [`Cumulative spend ${totalSpend} exceeds budget limit ${budgetMaxCents} (past spend: ${pastSpend})`];
104
+ }
105
+ return [];
106
+ }
107
+ function executionDate(c, closed) {
108
+ const execDate = closed.execution_date;
109
+ if (!execDate)
110
+ return [];
111
+ const v = [];
112
+ if (c.not_before && execDate < c.not_before) {
113
+ v.push(`Execution date ${execDate} is before allowed window ${c.not_before}`);
114
+ }
115
+ if (c.not_after && execDate > c.not_after) {
116
+ v.push(`Execution date ${execDate} is after allowed window ${c.not_after}`);
117
+ }
118
+ return v;
119
+ }
120
+ /** Dispatch one constraint; UNKNOWN type ⇒ a violation (closed-world, AUTH-15). */
121
+ function evaluatePaymentConstraint(raw, closed, ctx) {
122
+ const parsed = KnownPaymentConstraintSchema.safeParse(raw);
123
+ if (!parsed.success) {
124
+ return [`Unknown or malformed constraint type '${raw.type}' — treated as failing evaluation`];
125
+ }
126
+ const c = parsed.data;
127
+ switch (c.type) {
128
+ case "payment.amount_range":
129
+ return amountRange(c, closed);
130
+ case "payment.allowed_payees":
131
+ return allowedPayees(c, closed);
132
+ case "payment.reference":
133
+ return paymentReference(c, ctx);
134
+ case "payment.agent_recurrence":
135
+ return agentRecurrence(c, ctx);
136
+ case "payment.allowed_payment_instruments":
137
+ return allowedPaymentInstruments(c, closed);
138
+ case "payment.allowed_pisps":
139
+ return allowedPisps(c, closed);
140
+ case "payment.budget":
141
+ return budget(c, closed, ctx);
142
+ case "payment.execution_date":
143
+ return executionDate(c, closed);
144
+ }
145
+ }
146
+ /** Port of `check_preset_payment_claims`: open mandate pre-set fields must be
147
+ * present unchanged in the closed mandate (SPEC-38 / step 2). */
148
+ export function checkPresetPaymentClaims(open, closed) {
149
+ const v = [];
150
+ if (open.payee != null && !merchantMatches(open.payee, closed.payee)) {
151
+ v.push(`Pre-set payee mismatch: expected ${open.payee.name}, got ${closed.payee.name}`);
152
+ }
153
+ if (open.payment_amount != null && !amountsEqual(open.payment_amount, closed.payment_amount)) {
154
+ v.push("Pre-set amount mismatch"); // AP2 embeds a Python repr; count is asserted
155
+ }
156
+ if (open.payment_instrument != null && !instrumentsEqual(open.payment_instrument, closed.payment_instrument)) {
157
+ v.push("Pre-set payment_instrument mismatch");
158
+ }
159
+ if (open.execution_date != null && open.execution_date !== closed.execution_date) {
160
+ v.push(`Pre-set execution_date mismatch: expected ${open.execution_date}, got ${closed.execution_date}`);
161
+ }
162
+ return v;
163
+ }
164
+ /**
165
+ * Verify a closed payment satisfies an open mandate's pre-set claims and
166
+ * constraints. Port of `check_payment_constraints`. Returns [] when satisfied.
167
+ */
168
+ export function checkPaymentConstraints(open, closed, ctx = {}) {
169
+ const violations = [];
170
+ violations.push(...checkPresetPaymentClaims(open, closed));
171
+ const types = open.constraints.map((c) => c.type);
172
+ if (types.includes("payment.agent_recurrence")) {
173
+ if (!types.includes("payment.amount_range")) {
174
+ violations.push("payment.agent_recurrence requires payment.amount_range constraint");
175
+ }
176
+ if (!types.includes("payment.budget")) {
177
+ violations.push("payment.agent_recurrence requires payment.budget constraint");
178
+ }
179
+ }
180
+ // Caller-declared coverage. Same shape as the agent_recurrence check above,
181
+ // generalised: a constraint the caller requires but which is not present was
182
+ // never evaluated, so reporting no violation for it would certify a limit that
183
+ // was never applied. Only runs when the caller opts in.
184
+ for (const required of ctx.requiredConstraints ?? []) {
185
+ if (!types.includes(required)) {
186
+ violations.push(`${required} was required but is not present in the open mandate, so it was never evaluated`);
187
+ }
188
+ }
189
+ for (const c of open.constraints) {
190
+ violations.push(...evaluatePaymentConstraint(c, closed, ctx));
191
+ }
192
+ return violations;
193
+ }
194
+ // ── Checkout constraints (port of the checkout half of constraints.py) ───────
195
+ function allowedMerchants(c, checkout) {
196
+ const merchant = checkout.merchant;
197
+ if (!merchant)
198
+ return ["Missing merchant in checkout"];
199
+ if (c.allowed.some((a) => merchantMatches(a, merchant)))
200
+ return [];
201
+ return [`Merchant ${merchant.name || ""} not in allowed list`];
202
+ }
203
+ function lineItems(c, checkout) {
204
+ const checkoutItems = checkout.line_items ?? [];
205
+ if (checkoutItems.length === 0)
206
+ return ["Empty cart does not satisfy line_items constraint"];
207
+ return evaluateLineItemsMaxFlow(checkoutItems, c.items);
208
+ }
209
+ function evaluateCheckoutConstraint(raw, checkout) {
210
+ const parsed = KnownCheckoutConstraintSchema.safeParse(raw);
211
+ if (!parsed.success) {
212
+ return [`Unknown or malformed constraint type '${raw.type}' — treated as failing evaluation`];
213
+ }
214
+ const c = parsed.data;
215
+ switch (c.type) {
216
+ case "checkout.allowed_merchants":
217
+ return allowedMerchants(c, checkout);
218
+ case "checkout.line_items":
219
+ return lineItems(c, checkout);
220
+ }
221
+ }
222
+ /** Verify a checkout satisfies an open checkout mandate's constraints. Port of
223
+ * `check_checkout_constraints`. Returns [] when satisfied. */
224
+ export function checkCheckoutConstraints(open, checkout) {
225
+ const violations = [];
226
+ for (const c of open.constraints) {
227
+ violations.push(...evaluateCheckoutConstraint(c, checkout));
228
+ }
229
+ return violations;
230
+ }
231
+ //# sourceMappingURL=constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.js","sourceRoot":"","sources":["../../src/ap2/constraints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * SD-JWT binding + disclosure hashes.
3
+ *
4
+ * Byte-exact port of AP2's `sdjwt/common.py` hashing: hash the ASCII bytes of
5
+ * the on-wire string with the algorithm named by `_sd_alg` (default sha-256),
6
+ * base64url (no padding). Used for `sd_hash` / `issuer_jwt_hash` chain binding
7
+ * and disclosure digests. Tested against AP2-minted vectors.
8
+ */
9
+ import type { ParsedToken } from "./parse.js";
10
+ /** Hash of the SD-JWT (issuer JWT + disclosures, trailing `~`, NO KB segment). */
11
+ export declare function computeSdHash(token: ParsedToken): string;
12
+ /** Hash of only the issuer-signed JWT portion. */
13
+ export declare function computeIssuerJwtHash(token: ParsedToken): string;
14
+ /** Hash of a single disclosure string, using the token's `_sd_alg`. */
15
+ export declare function computeDisclosureDigest(disclosure: string, sdAlg: string | undefined): string;
16
+ /**
17
+ * base64url hash of an arbitrary on-wire value (ASCII), keyed off `_sd_alg`.
18
+ * Used for the `checkout_hash` / `transaction_id` linkage (hash of the
19
+ * `checkout_jwt`) and the receipt `reference`, all of which the spec defines as
20
+ * "calculated in the same manner as `sd_hash`" (AUTH-17 / SPEC-4).
21
+ */
22
+ export declare function computeValueHash(value: string, sdAlg: string | undefined): string;
23
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/ap2/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA0B9C,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAExD;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE/D;AAED,uEAAuE;AACvE,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEjF"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * SD-JWT binding + disclosure hashes.
3
+ *
4
+ * Byte-exact port of AP2's `sdjwt/common.py` hashing: hash the ASCII bytes of
5
+ * the on-wire string with the algorithm named by `_sd_alg` (default sha-256),
6
+ * base64url (no padding). Used for `sd_hash` / `issuer_jwt_hash` chain binding
7
+ * and disclosure digests. Tested against AP2-minted vectors.
8
+ */
9
+ import { createHash } from "node:crypto";
10
+ const HASH_BY_SD_ALG = {
11
+ "sha-256": "sha256",
12
+ "sha-384": "sha384",
13
+ "sha-512": "sha512",
14
+ };
15
+ function hashForAlg(sdAlg) {
16
+ if (sdAlg === undefined)
17
+ return "sha256";
18
+ const alg = HASH_BY_SD_ALG[sdAlg];
19
+ if (!alg)
20
+ throw new Error(`Unsupported _sd_alg: ${sdAlg}`);
21
+ return alg;
22
+ }
23
+ function hashAscii(value, sdAlg) {
24
+ // AP2 hashes `value.encode('ascii')`, which RAISES on non-ASCII. Node's
25
+ // "ascii" decoder silently masks to the low 8 bits (so 'a' and 'š' would
26
+ // collide). Reject non-ASCII to match AP2 and avoid a hash collision on the
27
+ // public hash exports.
28
+ if (!/^[\x00-\x7f]*$/.test(value)) {
29
+ throw new Error("Non-ASCII byte in hash input (AP2 hashes ASCII only)");
30
+ }
31
+ return createHash(hashForAlg(sdAlg)).update(Buffer.from(value, "ascii")).digest("base64url");
32
+ }
33
+ /** Hash of the SD-JWT (issuer JWT + disclosures, trailing `~`, NO KB segment). */
34
+ export function computeSdHash(token) {
35
+ return hashAscii(token.sdJwt, token.sdAlg);
36
+ }
37
+ /** Hash of only the issuer-signed JWT portion. */
38
+ export function computeIssuerJwtHash(token) {
39
+ return hashAscii(token.issuerJwt, token.sdAlg);
40
+ }
41
+ /** Hash of a single disclosure string, using the token's `_sd_alg`. */
42
+ export function computeDisclosureDigest(disclosure, sdAlg) {
43
+ return hashAscii(disclosure, sdAlg);
44
+ }
45
+ /**
46
+ * base64url hash of an arbitrary on-wire value (ASCII), keyed off `_sd_alg`.
47
+ * Used for the `checkout_hash` / `transaction_id` linkage (hash of the
48
+ * `checkout_jwt`) and the receipt `reference`, all of which the spec defines as
49
+ * "calculated in the same manner as `sd_hash`" (AUTH-17 / SPEC-4).
50
+ */
51
+ export function computeValueHash(value, sdAlg) {
52
+ return hashAscii(value, sdAlg);
53
+ }
54
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/ap2/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,cAAc,GAAmD;IACrE,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,QAAQ;CACpB,CAAC;AAEF,SAAS,UAAU,CAAC,KAAyB;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,KAAyB;IACzD,wEAAwE;IACxE,yEAAyE;IACzE,4EAA4E;IAC5E,uBAAuB;IACvB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAC/F,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,oBAAoB,CAAC,KAAkB;IACrD,OAAO,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,uBAAuB,CAAC,UAAkB,EAAE,KAAyB;IACnF,OAAO,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAyB;IACvE,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Real AP2 mandate verification — dSD-JWT delegation chains.
3
+ *
4
+ * Ported byte-exact from AP2's reference SDK (pinned commit e1ea56db…) and
5
+ * validated against 65 golden vectors. See AP2-AUDIT.md for the conformance
6
+ * matrix; the verifier is STRICTER than AP2 on every trust decision (ES256 pin,
7
+ * x5c fail-closed, aud+nonce required, self-computed linkage).
8
+ *
9
+ * import { ap2 } from "@goodmeta/agent-verifier";
10
+ * const tokens = ap2.splitChain(compactChain);
11
+ * const payloads = await ap2.verifyChain(
12
+ * tokens,
13
+ * ap2.x5cOrKidProvider({ trustedRoots }), // or pass a key directly
14
+ * { expectedAud, expectedNonce },
15
+ * );
16
+ * const chain = ap2.parsePaymentChain(payloads);
17
+ * const violations = ap2.verifyPaymentChain(chain, { mandateContext }); // [] = ok
18
+ */
19
+ export { splitChain, parseToken, type ParsedToken } from "./parse.js";
20
+ export { verifyChain, CHAIN_CAPS, type VerifyChainOptions, type RootKeyProvider } from "./chain.js";
21
+ export { verifyRootSdJwt, cnfJwk, type ResolvedToken, type VerificationKey } from "./sd-jwt.js";
22
+ export { x5cOrKidProvider, type X5cKidProviderOptions } from "./keys.js";
23
+ export { computeSdHash, computeIssuerJwtHash, computeValueHash, computeDisclosureDigest } from "./hash.js";
24
+ export { JwkSchema, parseJwk, type Jwk } from "./jwk.js";
25
+ export { parsePaymentChain, verifyPaymentChain, parseCheckoutChain, verifyCheckoutChain, extractCheckout, receiptReference, getClosedMandateJwt, type PaymentChain, type CheckoutChain, type VerifyPaymentChainOptions, type VerifyCheckoutChainOptions, } from "./chains.js";
26
+ export { checkPaymentConstraints, checkCheckoutConstraints, merchantMatches } from "./constraints.js";
27
+ export { OpenPaymentMandateSchema, PaymentMandateSchema, OpenCheckoutMandateSchema, CheckoutMandateSchema, CheckoutSchema, type OpenPaymentMandate, type PaymentMandate, type OpenCheckoutMandate, type CheckoutMandate, type Checkout, type MandateContext, } from "./types.js";
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ap2/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhG,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAG3G,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGtG,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Real AP2 mandate verification — dSD-JWT delegation chains.
3
+ *
4
+ * Ported byte-exact from AP2's reference SDK (pinned commit e1ea56db…) and
5
+ * validated against 65 golden vectors. See AP2-AUDIT.md for the conformance
6
+ * matrix; the verifier is STRICTER than AP2 on every trust decision (ES256 pin,
7
+ * x5c fail-closed, aud+nonce required, self-computed linkage).
8
+ *
9
+ * import { ap2 } from "@goodmeta/agent-verifier";
10
+ * const tokens = ap2.splitChain(compactChain);
11
+ * const payloads = await ap2.verifyChain(
12
+ * tokens,
13
+ * ap2.x5cOrKidProvider({ trustedRoots }), // or pass a key directly
14
+ * { expectedAud, expectedNonce },
15
+ * );
16
+ * const chain = ap2.parsePaymentChain(payloads);
17
+ * const violations = ap2.verifyPaymentChain(chain, { mandateContext }); // [] = ok
18
+ */
19
+ // Chain parsing + walk
20
+ export { splitChain, parseToken } from "./parse.js";
21
+ export { verifyChain, CHAIN_CAPS } from "./chain.js";
22
+ export { verifyRootSdJwt, cnfJwk } from "./sd-jwt.js";
23
+ // Trust anchoring (x5c chain / kid lookup) — fail-closed
24
+ export { x5cOrKidProvider } from "./keys.js";
25
+ // Binding / disclosure / linkage hashes
26
+ export { computeSdHash, computeIssuerJwtHash, computeValueHash, computeDisclosureDigest } from "./hash.js";
27
+ // Strict EC P-256 JWK
28
+ export { JwkSchema, parseJwk } from "./jwk.js";
29
+ // Typed chains + linkage + receipt reference
30
+ export { parsePaymentChain, verifyPaymentChain, parseCheckoutChain, verifyCheckoutChain, extractCheckout, receiptReference, getClosedMandateJwt, } from "./chains.js";
31
+ // Constraint evaluation (closed-world: unknown constraint ⇒ violation)
32
+ export { checkPaymentConstraints, checkCheckoutConstraints, merchantMatches } from "./constraints.js";
33
+ // Mandate schemas + inferred types (snake_case, vct pinned exact)
34
+ export { OpenPaymentMandateSchema, PaymentMandateSchema, OpenCheckoutMandateSchema, CheckoutMandateSchema, CheckoutSchema, } from "./types.js";
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ap2/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,uBAAuB;AACvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAoB,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAiD,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,EAA4C,MAAM,aAAa,CAAC;AAEhG,yDAAyD;AACzD,OAAO,EAAE,gBAAgB,EAA8B,MAAM,WAAW,CAAC;AAEzE,wCAAwC;AACxC,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAE3G,sBAAsB;AACtB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAY,MAAM,UAAU,CAAC;AAEzD,6CAA6C;AAC7C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GAKpB,MAAM,aAAa,CAAC;AAErB,uEAAuE;AACvE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEtG,kEAAkE;AAClE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,GAOf,MAAM,YAAY,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Strict EC P-256 JWK validation.
3
+ *
4
+ * Mirrors AP2's `generated/types/jwk.py` (Pydantic `extra='forbid'`): kty='EC',
5
+ * crv='P-256', alg='ES256', x/y are 43-char base64url. We pin P-256/ES256 — our
6
+ * documented ES256-only narrowing — and reject unknown members so a `cnf.jwk`
7
+ * can't smuggle extra fields.
8
+ */
9
+ import { z } from "zod";
10
+ export declare const JwkSchema: z.ZodObject<{
11
+ kty: z.ZodLiteral<"EC">;
12
+ crv: z.ZodLiteral<"P-256">;
13
+ x: z.ZodString;
14
+ y: z.ZodString;
15
+ alg: z.ZodOptional<z.ZodLiteral<"ES256">>;
16
+ kid: z.ZodOptional<z.ZodString>;
17
+ use: z.ZodOptional<z.ZodString>;
18
+ x5c: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
+ "x5t#S256": z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strict>;
21
+ export type Jwk = z.infer<typeof JwkSchema>;
22
+ /** Validate an untrusted value as a strict EC P-256 JWK, or return null. */
23
+ export declare function parseJwk(input: unknown): Jwk | null;
24
+ //# sourceMappingURL=jwk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwk.d.ts","sourceRoot":"","sources":["../../src/ap2/jwk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,SAAS;;;;;;;;;;kBAYX,CAAC;AAEZ,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAE5C,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,GAAG,IAAI,CAGnD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Strict EC P-256 JWK validation.
3
+ *
4
+ * Mirrors AP2's `generated/types/jwk.py` (Pydantic `extra='forbid'`): kty='EC',
5
+ * crv='P-256', alg='ES256', x/y are 43-char base64url. We pin P-256/ES256 — our
6
+ * documented ES256-only narrowing — and reject unknown members so a `cnf.jwk`
7
+ * can't smuggle extra fields.
8
+ */
9
+ import { z } from "zod";
10
+ const B64URL_43 = /^[A-Za-z0-9_-]{43}$/;
11
+ export const JwkSchema = z
12
+ .object({
13
+ kty: z.literal("EC"),
14
+ crv: z.literal("P-256"),
15
+ x: z.string().regex(B64URL_43),
16
+ y: z.string().regex(B64URL_43),
17
+ alg: z.literal("ES256").optional(),
18
+ kid: z.string().optional(),
19
+ use: z.string().optional(),
20
+ x5c: z.array(z.string()).optional(),
21
+ "x5t#S256": z.string().optional(),
22
+ })
23
+ .strict();
24
+ /** Validate an untrusted value as a strict EC P-256 JWK, or return null. */
25
+ export function parseJwk(input) {
26
+ const r = JwkSchema.safeParse(input);
27
+ return r.success ? r.data : null;
28
+ }
29
+ //# sourceMappingURL=jwk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwk.js","sourceRoot":"","sources":["../../src/ap2/jwk.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,qBAAqB,CAAC;AAExC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACpB,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACvB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE;IAClC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACnC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,MAAM,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * KB-SD-JWT delegation-hop verification.
3
+ *
4
+ * Line-for-line port of AP2's `sdjwt/kb_sd_jwt.py::verify` plus the binding /
5
+ * expected-claim helpers from `sdjwt/common.py`. The exact order matters and
6
+ * mirrors AP2:
7
+ * 1. `typ` is a known AP2 KB type (terminal `kb+sd-jwt`/`kb-sd-jwt`, or
8
+ * intermediate `kb+sd-jwt+kb`/`kb-sd-jwt+kb`).
9
+ * 2. Signature verifies (ES256, pinned) under the PREVIOUS hop's `cnf.jwk`.
10
+ * 3. Resolve `delegate_payload` digests (CMWallet quirk) FIRST.
11
+ * 4. Binding: exactly one of `sd_hash`/`issuer_jwt_hash`, equal to the hash of
12
+ * the previous on-wire token. Both-present AND both-absent are errors.
13
+ * 5. Terminal hop → enforce expected aud/nonce (when provided) + `iat`.
14
+ * 6. cnf presence: terminal MUST NOT carry `cnf`; intermediate MUST.
15
+ *
16
+ * The "aud+nonce are mandatory for any KB-bearing chain" hardening (H4) is
17
+ * enforced one level up in `chain.ts`, matching AP2's structure (AP2 only
18
+ * checks them on the terminal hop, and only if the caller supplied them).
19
+ */
20
+ import type { ParsedToken } from "./parse.js";
21
+ import { type ResolvedToken } from "./sd-jwt.js";
22
+ type Json = Record<string, unknown>;
23
+ /** Exactly one of `sd_hash`/`issuer_jwt_hash`, matching the hash of `prev`. */
24
+ export declare function verifyBinding(payload: Json, prev: ParsedToken): void;
25
+ /** Validate `iat` presence and, when provided, `aud`/`nonce` (port of
26
+ * `verify_expected_claims`; the "always required" tightening lives in chain.ts). */
27
+ export declare function verifyExpectedClaims(payload: Json, expectedAud: string | undefined, expectedNonce: string | undefined, label?: string): void;
28
+ export interface KbHopOptions {
29
+ /** Enforced only on the terminal hop, and only when provided (chain.ts makes
30
+ * them mandatory for any KB-bearing chain — hardening H4). */
31
+ expectedAud?: string;
32
+ expectedNonce?: string;
33
+ /** When set (the chain's positionally-last hop), the hop MUST be terminal-typ
34
+ * — otherwise a chain truncated to end on an intermediate hop would skip the
35
+ * aud/nonce check (H4 bypass). Stricter than AP2. */
36
+ requireTerminal?: boolean;
37
+ }
38
+ /**
39
+ * Verify one KB-SD-JWT hop against the previous (already verified+resolved)
40
+ * token, returning this hop's verified, disclosure-resolved payload.
41
+ */
42
+ export declare function verifyKbHop(token: ParsedToken, prev: ResolvedToken, opts?: KbHopOptions): Promise<Json>;
43
+ export {};
44
+ //# sourceMappingURL=kb-sd-jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-sd-jwt.d.ts","sourceRoot":"","sources":["../../src/ap2/kb-sd-jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAmE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAKlH,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAMpC,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAoBpE;AAED;oFACoF;AACpF,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,IAAI,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,KAAK,SAAc,GAClB,IAAI,CAQN;AAQD,MAAM,WAAW,YAAY;IAC3B;kEAC8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;yDAEqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BjH"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * KB-SD-JWT delegation-hop verification.
3
+ *
4
+ * Line-for-line port of AP2's `sdjwt/kb_sd_jwt.py::verify` plus the binding /
5
+ * expected-claim helpers from `sdjwt/common.py`. The exact order matters and
6
+ * mirrors AP2:
7
+ * 1. `typ` is a known AP2 KB type (terminal `kb+sd-jwt`/`kb-sd-jwt`, or
8
+ * intermediate `kb+sd-jwt+kb`/`kb-sd-jwt+kb`).
9
+ * 2. Signature verifies (ES256, pinned) under the PREVIOUS hop's `cnf.jwk`.
10
+ * 3. Resolve `delegate_payload` digests (CMWallet quirk) FIRST.
11
+ * 4. Binding: exactly one of `sd_hash`/`issuer_jwt_hash`, equal to the hash of
12
+ * the previous on-wire token. Both-present AND both-absent are errors.
13
+ * 5. Terminal hop → enforce expected aud/nonce (when provided) + `iat`.
14
+ * 6. cnf presence: terminal MUST NOT carry `cnf`; intermediate MUST.
15
+ *
16
+ * The "aud+nonce are mandatory for any KB-bearing chain" hardening (H4) is
17
+ * enforced one level up in `chain.ts`, matching AP2's structure (AP2 only
18
+ * checks them on the terminal hop, and only if the caller supplied them).
19
+ */
20
+ import { computeSdHash, computeIssuerJwtHash } from "./hash.js";
21
+ import { verifyEs256, resolveDisclosures, resolveDelegatePayload, cnfJwk } from "./sd-jwt.js";
22
+ const TYP_TERMINAL = ["kb+sd-jwt", "kb-sd-jwt"];
23
+ const TYP_INTERMEDIATE = ["kb+sd-jwt+kb", "kb-sd-jwt+kb"];
24
+ function isPlainObject(value) {
25
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26
+ }
27
+ /** Exactly one of `sd_hash`/`issuer_jwt_hash`, matching the hash of `prev`. */
28
+ export function verifyBinding(payload, prev) {
29
+ const hasSd = "sd_hash" in payload;
30
+ const hasIss = "issuer_jwt_hash" in payload;
31
+ if (hasSd === hasIss) {
32
+ throw new Error(`KB-SD-JWT payload must contain exactly one of 'sd_hash' or 'issuer_jwt_hash' ` +
33
+ `(got sd_hash=${hasSd}, issuer_jwt_hash=${hasIss})`);
34
+ }
35
+ if (hasSd) {
36
+ const expected = computeSdHash(prev);
37
+ if (payload["sd_hash"] !== expected) {
38
+ throw new Error(`sd_hash mismatch: expected '${expected}', got '${String(payload["sd_hash"])}'`);
39
+ }
40
+ }
41
+ else {
42
+ const expected = computeIssuerJwtHash(prev);
43
+ if (payload["issuer_jwt_hash"] !== expected) {
44
+ throw new Error(`issuer_jwt_hash mismatch: expected '${expected}', got '${String(payload["issuer_jwt_hash"])}'`);
45
+ }
46
+ }
47
+ }
48
+ /** Validate `iat` presence and, when provided, `aud`/`nonce` (port of
49
+ * `verify_expected_claims`; the "always required" tightening lives in chain.ts). */
50
+ export function verifyExpectedClaims(payload, expectedAud, expectedNonce, label = "KB-SD-JWT") {
51
+ if (!("iat" in payload))
52
+ throw new Error(`${label} missing required 'iat' claim`);
53
+ if (expectedAud !== undefined && payload["aud"] !== expectedAud) {
54
+ throw new Error(`${label} aud mismatch: expected '${expectedAud}', got '${String(payload["aud"])}'`);
55
+ }
56
+ if (expectedNonce !== undefined && payload["nonce"] !== expectedNonce) {
57
+ throw new Error(`${label} nonce mismatch: expected '${expectedNonce}', got '${String(payload["nonce"])}'`);
58
+ }
59
+ }
60
+ function delegatePayloadHasCnf(payload) {
61
+ const dp = payload["delegate_payload"];
62
+ if (!Array.isArray(dp))
63
+ return false;
64
+ return dp.some((item) => isPlainObject(item) && isPlainObject(item["cnf"]));
65
+ }
66
+ /**
67
+ * Verify one KB-SD-JWT hop against the previous (already verified+resolved)
68
+ * token, returning this hop's verified, disclosure-resolved payload.
69
+ */
70
+ export async function verifyKbHop(token, prev, opts = {}) {
71
+ const typ = token.typ;
72
+ const isTerminal = typ !== undefined && TYP_TERMINAL.includes(typ);
73
+ const isIntermediate = typ !== undefined && TYP_INTERMEDIATE.includes(typ);
74
+ if (!isTerminal && !isIntermediate) {
75
+ throw new Error(`Unexpected JWT typ: expected one of ${[...TYP_TERMINAL, ...TYP_INTERMEDIATE].join(", ")}, got '${String(typ)}'`);
76
+ }
77
+ const prevKey = cnfJwk(prev); // 3-tier _find_cnf + single-cnf hardening (H3)
78
+ await verifyEs256(token.issuerJwt, prevKey); // ES256 under prev's cnf.jwk
79
+ const payload = resolveDisclosures(token.payload, token.disclosures, token.sdAlg);
80
+ resolveDelegatePayload(payload, token); // CMWallet digest-string resolution FIRST
81
+ verifyBinding(payload, prev.token);
82
+ if (isTerminal)
83
+ verifyExpectedClaims(payload, opts.expectedAud, opts.expectedNonce);
84
+ const hasCnf = delegatePayloadHasCnf(payload);
85
+ if (isTerminal && hasCnf)
86
+ throw new Error("Terminal KB-SD-JWT MUST NOT carry a 'cnf' claim");
87
+ if (isIntermediate && !hasCnf)
88
+ throw new Error(`Intermediate ${typ} requires a 'cnf' claim`);
89
+ // H4 anti-truncation: the chain's last hop MUST be terminal-typ. Placed after
90
+ // the cnf-presence checks so a non-terminal last hop still rejects (its
91
+ // aud/nonce would otherwise be silently skipped under attacker-chosen values).
92
+ if (opts.requireTerminal && !isTerminal) {
93
+ throw new Error(`Final chain hop must be a terminal KB-SD-JWT, got typ '${String(typ)}'`);
94
+ }
95
+ return payload;
96
+ }
97
+ //# sourceMappingURL=kb-sd-jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-sd-jwt.js","sourceRoot":"","sources":["../../src/ap2/kb-sd-jwt.ts"],"names":[],"mappings":"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"}