@agent-score/commerce 2.5.0 → 2.6.1
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 +19 -17
- package/dist/challenge/index.d.mts +26 -2
- package/dist/challenge/index.d.ts +26 -2
- package/dist/challenge/index.js +14 -5
- package/dist/challenge/index.js.map +1 -1
- package/dist/challenge/index.mjs +14 -5
- package/dist/challenge/index.mjs.map +1 -1
- package/dist/{checkout-McfNpZJf.d.ts → checkout-C4RD7M0Z.d.ts} +46 -13
- package/dist/{checkout-o17dIxHi.d.mts → checkout-CzB9f_jf.d.mts} +46 -13
- package/dist/core.d.mts +20 -9
- package/dist/core.d.ts +20 -9
- package/dist/core.js +35 -24
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +35 -24
- package/dist/core.mjs.map +1 -1
- package/dist/discovery/index.d.mts +17 -2
- package/dist/discovery/index.d.ts +17 -2
- package/dist/discovery/index.js +36 -12
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +35 -12
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/{gate-CWP10xPQ.d.mts → gate-D2RP6bZg.d.ts} +109 -141
- package/dist/{gate-CWP10xPQ.d.ts → gate-GCXy4FHI.d.mts} +109 -141
- package/dist/identity/express.d.mts +3 -1
- package/dist/identity/express.d.ts +3 -1
- package/dist/identity/express.js +164 -55
- package/dist/identity/express.js.map +1 -1
- package/dist/identity/express.mjs +164 -55
- package/dist/identity/express.mjs.map +1 -1
- package/dist/identity/fastify.d.mts +3 -1
- package/dist/identity/fastify.d.ts +3 -1
- package/dist/identity/fastify.js +171 -57
- package/dist/identity/fastify.js.map +1 -1
- package/dist/identity/fastify.mjs +171 -57
- package/dist/identity/fastify.mjs.map +1 -1
- package/dist/identity/hono.d.mts +3 -1
- package/dist/identity/hono.d.ts +3 -1
- package/dist/identity/hono.js +159 -59
- package/dist/identity/hono.js.map +1 -1
- package/dist/identity/hono.mjs +159 -59
- package/dist/identity/hono.mjs.map +1 -1
- package/dist/identity/nextjs.d.mts +3 -1
- package/dist/identity/nextjs.d.ts +3 -1
- package/dist/identity/nextjs.js +153 -56
- package/dist/identity/nextjs.js.map +1 -1
- package/dist/identity/nextjs.mjs +153 -56
- package/dist/identity/nextjs.mjs.map +1 -1
- package/dist/identity/policy.d.mts +21 -2
- package/dist/identity/policy.d.ts +21 -2
- package/dist/identity/policy.js +22 -1
- package/dist/identity/policy.js.map +1 -1
- package/dist/identity/policy.mjs +21 -1
- package/dist/identity/policy.mjs.map +1 -1
- package/dist/identity/web.d.mts +3 -1
- package/dist/identity/web.d.ts +3 -1
- package/dist/identity/web.js +153 -56
- package/dist/identity/web.js.map +1 -1
- package/dist/identity/web.mjs +153 -56
- package/dist/identity/web.mjs.map +1 -1
- package/dist/index.d.mts +55 -10
- package/dist/index.d.ts +55 -10
- package/dist/index.js +2227 -501
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2219 -501
- package/dist/index.mjs.map +1 -1
- package/dist/payment/index.d.mts +1 -1
- package/dist/payment/index.d.ts +1 -1
- package/dist/payment/index.js +10 -2
- package/dist/payment/index.js.map +1 -1
- package/dist/payment/index.mjs +10 -2
- package/dist/payment/index.mjs.map +1 -1
- package/dist/stripe-multichain/index.js +1621 -266
- package/dist/stripe-multichain/index.js.map +1 -1
- package/dist/stripe-multichain/index.mjs +1621 -266
- package/dist/stripe-multichain/index.mjs.map +1 -1
- package/dist/types-D1slMt0H.d.mts +137 -0
- package/dist/types-D1slMt0H.d.ts +137 -0
- package/dist/{wwwauthenticate-CVaGUMjU.d.mts → wwwauthenticate-Dgm-_af9.d.mts} +11 -1
- package/dist/{wwwauthenticate-CVaGUMjU.d.ts → wwwauthenticate-Dgm-_af9.d.ts} +11 -1
- package/package.json +23 -18
|
@@ -1,139 +1,6 @@
|
|
|
1
|
+
import { a as AitPayload, T as TrustLevel } from './types-D1slMt0H.js';
|
|
1
2
|
import { JWK } from 'jose';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* AIP (Agentic Identity Protocol) token types and the claim contract.
|
|
5
|
-
*
|
|
6
|
-
* An Agent Identity Token (AIT) is a JWT signed by an Identity Provider (IdP). It binds a
|
|
7
|
-
* verified human's identity to the specific agent presenting it (via `cnf`, RFC 7800) and
|
|
8
|
-
* carries the trust level, authentication method, optional intent, and optional identity
|
|
9
|
-
* claims the IdP attests to.
|
|
10
|
-
*
|
|
11
|
-
* This module is the single source of truth for the claim shape on the verifier side. It
|
|
12
|
-
* encodes the spec's required / recommended / optional claims plus the AgentScore extension
|
|
13
|
-
* claims (sanctions, jurisdiction, structured id-verification, cross-merchant graph, payment
|
|
14
|
-
* signer) we carry when we act as a compliance IdP.
|
|
15
|
-
*
|
|
16
|
-
* Extensibility contract (per spec): the `identity` object is open. If a claim is present,
|
|
17
|
-
* the IdP attests to it; verifiers ignore claims they don't recognize. Absence is the
|
|
18
|
-
* "unknown" signal — IdPs do not ship `null` for "not checked".
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/** Degree of human involvement in issuing this specific AIT. */
|
|
22
|
-
type TrustLevel = 'autonomous' | 'human_present' | 'human_confirmed';
|
|
23
|
-
/**
|
|
24
|
-
* Authentication Method Reference values (RFC 8176 / IANA AMR registry). Open set — these
|
|
25
|
-
* are the values relevant to agent identity; others are valid and pass through.
|
|
26
|
-
*/
|
|
27
|
-
type AmrValue = 'face' | 'fpt' | 'hwk' | 'otp' | 'pin' | 'pwd' | 'sms' | 'swk' | 'user' | 'mfa';
|
|
28
|
-
/** RFC 7800 confirmation claim: binds the AIT to the agent's signing key. */
|
|
29
|
-
interface CnfClaim {
|
|
30
|
-
jwk: JWK;
|
|
31
|
-
}
|
|
32
|
-
/** Agent metadata. `provider` is required; `instance` is recommended. */
|
|
33
|
-
interface AgentClaim {
|
|
34
|
-
provider: string;
|
|
35
|
-
instance?: string;
|
|
36
|
-
}
|
|
37
|
-
/** How the user authorized THIS AIT (not prior authentication history). */
|
|
38
|
-
interface AuthClaim {
|
|
39
|
-
amr?: AmrValue[] | string[];
|
|
40
|
-
/** When the user authenticated for this token (Unix seconds). Mirrors OIDC `auth_time`. */
|
|
41
|
-
time?: number;
|
|
42
|
-
}
|
|
43
|
-
/** What the agent intends to do. Optional; verifiers may require it for non-read actions. */
|
|
44
|
-
interface IntentClaim {
|
|
45
|
-
actions?: string[];
|
|
46
|
-
description?: string;
|
|
47
|
-
}
|
|
48
|
-
/** AgentScore wallet-binding extension (orthogonal to `cnf`, which binds the agent key). */
|
|
49
|
-
interface PaymentSignerClaim {
|
|
50
|
-
address: string;
|
|
51
|
-
network: 'evm' | 'solana';
|
|
52
|
-
/** Relationship the IdP attests between signer and the operator graph. */
|
|
53
|
-
match?: 'linked_operator' | 'claimed_operator';
|
|
54
|
-
}
|
|
55
|
-
interface PaymentClaim {
|
|
56
|
-
signer?: PaymentSignerClaim;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Identity claims (presence == IdP attestation). Spec-defined fields plus AgentScore
|
|
60
|
-
* compliance extension claims. Open by contract — unknown fields are allowed and ignored.
|
|
61
|
-
*/
|
|
62
|
-
interface IdentityClaim {
|
|
63
|
-
email?: string;
|
|
64
|
-
email_verified?: boolean;
|
|
65
|
-
name?: string;
|
|
66
|
-
phone?: string;
|
|
67
|
-
phone_verified?: boolean;
|
|
68
|
-
age_over_18?: boolean;
|
|
69
|
-
age_over_21?: boolean;
|
|
70
|
-
id_verified?: boolean;
|
|
71
|
-
id_verification?: {
|
|
72
|
-
provider?: string;
|
|
73
|
-
method?: string;
|
|
74
|
-
document_type?: string;
|
|
75
|
-
verified_at?: number;
|
|
76
|
-
};
|
|
77
|
-
/** ISO 3166-1 alpha-2, optionally with ISO 3166-2 subdivision (e.g. "US-CA"). */
|
|
78
|
-
jurisdiction?: string;
|
|
79
|
-
sanctions_clear?: boolean;
|
|
80
|
-
sanctions_checked_at?: number;
|
|
81
|
-
sanctions_providers?: string[];
|
|
82
|
-
linked_wallets?: Array<{
|
|
83
|
-
address: string;
|
|
84
|
-
network: 'evm' | 'solana';
|
|
85
|
-
}>;
|
|
86
|
-
merchants_paid?: number;
|
|
87
|
-
first_seen?: number;
|
|
88
|
-
[claim: string]: unknown;
|
|
89
|
-
}
|
|
90
|
-
/** The decoded AIT JWT payload. */
|
|
91
|
-
interface AitPayload {
|
|
92
|
-
aip_version: string;
|
|
93
|
-
iss: string;
|
|
94
|
-
sub: string;
|
|
95
|
-
iat: number;
|
|
96
|
-
exp: number;
|
|
97
|
-
cnf: CnfClaim;
|
|
98
|
-
agent: AgentClaim;
|
|
99
|
-
trust_level?: TrustLevel;
|
|
100
|
-
auth?: AuthClaim;
|
|
101
|
-
intent?: IntentClaim;
|
|
102
|
-
identity?: IdentityClaim;
|
|
103
|
-
payment?: PaymentClaim;
|
|
104
|
-
[claim: string]: unknown;
|
|
105
|
-
}
|
|
106
|
-
/** The decoded AIT JWT header. */
|
|
107
|
-
interface AitHeader {
|
|
108
|
-
alg: string;
|
|
109
|
-
typ?: string;
|
|
110
|
-
kid?: string;
|
|
111
|
-
[param: string]: unknown;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Structural validation of a decoded AIT payload. Confirms the required claims are present
|
|
115
|
-
* and well-typed, and enforces the one normative conditional in the spec: a
|
|
116
|
-
* `human_confirmed` token MUST carry at least one `auth.amr` value.
|
|
117
|
-
*
|
|
118
|
-
* This is shape/contract validation only — it does NOT verify signatures (that's the
|
|
119
|
-
* verifier pipeline) and does NOT apply trust policy (that's the gate / `/v1/assess`).
|
|
120
|
-
*/
|
|
121
|
-
type AitValidationResult = {
|
|
122
|
-
ok: true;
|
|
123
|
-
payload: AitPayload;
|
|
124
|
-
} | {
|
|
125
|
-
ok: false;
|
|
126
|
-
reason: AitValidationFailure;
|
|
127
|
-
};
|
|
128
|
-
type AitValidationFailure = 'not_an_object' | 'missing_aip_version' | 'missing_iss' | 'missing_sub' | 'missing_iat' | 'missing_exp' | 'missing_cnf' | 'missing_agent_provider' | 'human_confirmed_without_amr';
|
|
129
|
-
/**
|
|
130
|
-
* Detect whether a decoded JWT payload is an AIT: per spec, an AIT is discriminated by the
|
|
131
|
-
* presence of `cnf` + `agent` claims (not the `typ` header).
|
|
132
|
-
*/
|
|
133
|
-
declare const isAitShape: (payload: unknown) => boolean;
|
|
134
|
-
/** Validate the structural contract of a decoded AIT payload. */
|
|
135
|
-
declare const validateAitPayload: (payload: unknown) => AitValidationResult;
|
|
136
|
-
|
|
137
4
|
/**
|
|
138
5
|
* AIP IdP key discovery: fetch, cache, and select JWKS signing keys.
|
|
139
6
|
*
|
|
@@ -172,7 +39,7 @@ type FetchLike = (url: string, init?: {
|
|
|
172
39
|
* gate/adapter built on it) without the merchant listing it — this SDK is the AgentScore
|
|
173
40
|
* verifier, so a merchant can't accidentally fail to trust AgentScore-issued AITs. `trustedIssuers`
|
|
174
41
|
* only needs to name ADDITIONAL external issuers. */
|
|
175
|
-
declare const AGENTSCORE_CANONICAL_ISSUER = "https://agentscore.
|
|
42
|
+
declare const AGENTSCORE_CANONICAL_ISSUER = "https://www.agentscore.com";
|
|
176
43
|
interface JwksCacheOptions {
|
|
177
44
|
/** ADDITIONAL external issuer URLs to trust beyond AgentScore's own (compared after
|
|
178
45
|
* canonicalization). AgentScore's canonical issuer is always trusted; omit/empty to accept
|
|
@@ -209,6 +76,12 @@ declare class JwksCache {
|
|
|
209
76
|
private readonly now;
|
|
210
77
|
private readonly userAgent;
|
|
211
78
|
private readonly cache;
|
|
79
|
+
/** Per-issuer in-flight refresh promise — coalesces concurrent refreshes to ONE upstream fetch.
|
|
80
|
+
* Without it, a concurrent burst of distinct-kid lookups on a cold/expired cache each call
|
|
81
|
+
* `refresh()` before any has populated the cache → N parallel JWKS GETs (refetch amplification).
|
|
82
|
+
* The cooldown only suppresses SEQUENTIAL refetches; single-flight suppresses CONCURRENT ones.
|
|
83
|
+
* Entry is cleared in a `finally` once the fetch settles. */
|
|
84
|
+
private readonly inflight;
|
|
212
85
|
constructor(opts: JwksCacheOptions);
|
|
213
86
|
/** Is this issuer on the canonicalized trust list? */
|
|
214
87
|
isTrusted(iss: string): boolean;
|
|
@@ -218,7 +91,19 @@ declare class JwksCache {
|
|
|
218
91
|
*/
|
|
219
92
|
getKey(iss: string, kid: string | undefined): Promise<JwksLookupResult>;
|
|
220
93
|
private select;
|
|
94
|
+
/**
|
|
95
|
+
* Refresh the cached key set for `canonIssuer`, coalescing concurrent callers onto a single
|
|
96
|
+
* upstream fetch (single-flight). The first caller for an issuer with no in-flight refresh kicks
|
|
97
|
+
* off the fetch and registers the promise; concurrent callers await that same promise instead of
|
|
98
|
+
* issuing their own GET. The entry is cleared once the fetch settles so the NEXT cold/expired
|
|
99
|
+
* lookup can refresh again.
|
|
100
|
+
*/
|
|
221
101
|
private refresh;
|
|
102
|
+
private fetchAndCache;
|
|
103
|
+
/** Stamp the per-issuer refetch cooldown on a FAILED fetch attempt (the negative cache). Any
|
|
104
|
+
* previously cached keys + expiry are preserved — a failed kid-miss refetch must not nuke a
|
|
105
|
+
* still-fresh key set; only the cooldown and failure reason are updated. */
|
|
106
|
+
private stampFailure;
|
|
222
107
|
}
|
|
223
108
|
|
|
224
109
|
/**
|
|
@@ -260,6 +145,12 @@ interface VerifyAitOptions {
|
|
|
260
145
|
jwks: JwksCache;
|
|
261
146
|
now?: number;
|
|
262
147
|
maxSkewSeconds?: number;
|
|
148
|
+
/** Max accepted AIT lifetime (`exp - iat`) in seconds. Defense-in-depth vs an external issuer
|
|
149
|
+
* minting a long-lived bearer credential. The spec recommends a 60–300s window; default 300 so a
|
|
150
|
+
* stolen AIT's usable window stays short even at the edge (standalone `aipGate`, no `/v1/assess`).
|
|
151
|
+
* Our own mint is 300s, so first-party tokens sit exactly at the ceiling. Matches the
|
|
152
|
+
* authoritative API verifier's default (the AgentScore API verifier), lowered from 3600. */
|
|
153
|
+
maxLifetimeSeconds?: number;
|
|
263
154
|
}
|
|
264
155
|
/**
|
|
265
156
|
* Failure reasons, aligned with AIP wire error codes. The gate maps:
|
|
@@ -276,6 +167,16 @@ interface VerifiedAit {
|
|
|
276
167
|
/** The raw JWT string that verified (the winning `Agent-Identity` header value, Bearer
|
|
277
168
|
* prefix stripped). Lets a gate forward the exact token to `/v1/assess` as `aip_token`. */
|
|
278
169
|
token: string;
|
|
170
|
+
/** The RFC 9421 signature material for this request — forwarded to `/v1/assess` as
|
|
171
|
+
* `aip_signature` so the API re-verifies proof-of-possession authoritatively (the edge
|
|
172
|
+
* check here is only a fail-fast filter; the API is the source of truth). */
|
|
173
|
+
signatureMaterial: {
|
|
174
|
+
method: string;
|
|
175
|
+
authority: string;
|
|
176
|
+
path: string;
|
|
177
|
+
signature_input: string;
|
|
178
|
+
signature: string;
|
|
179
|
+
};
|
|
279
180
|
}
|
|
280
181
|
type VerifyAitResult = {
|
|
281
182
|
ok: true;
|
|
@@ -310,6 +211,26 @@ interface AipGateOptions {
|
|
|
310
211
|
jwks: JwksCache;
|
|
311
212
|
now?: number;
|
|
312
213
|
maxSkewSeconds?: number;
|
|
214
|
+
/** Expected `@authority` (public hostname) the RFC 9421 signature must cover. When set, the
|
|
215
|
+
* verifier binds the signature to this value instead of trusting the inbound `Host` header —
|
|
216
|
+
* pin it to your real public host (e.g. `'wine.example.com'`) when behind a proxy or
|
|
217
|
+
* multi-vhost listener that does not normalize `Host`, to prevent a captured AIT+signature
|
|
218
|
+
* from being replayed to a different virtual host on the same origin. Same semantics as
|
|
219
|
+
* Checkout's `AipGateConfig.authority`. */
|
|
220
|
+
authority?: string;
|
|
221
|
+
/** Minimum `trust_level` (autonomous < human_present < human_confirmed) the AIT must assert —
|
|
222
|
+
* the spec's human-presence gate. Insufficient → 403 weak_auth with `required_trust_level`.
|
|
223
|
+
* Enforced by {@link evaluateAipRequest} / {@link evaluateAipParts}. Unset = any trust level. */
|
|
224
|
+
requireTrustLevel?: TrustLevel;
|
|
225
|
+
/** Acceptable `auth.amr` methods (RFC 8176); the AIT must carry ≥1. Insufficient → 403 weak_auth
|
|
226
|
+
* with `required_amr`. Unset = not enforced. */
|
|
227
|
+
requireAmr?: string[];
|
|
228
|
+
/** Identity claims the endpoint needs — surfaced as `required_claims` on insufficient_claims
|
|
229
|
+
* denials so the agent can self-correct. Advisory only (enforce by feeding the verified claims
|
|
230
|
+
* to your own policy / `/v1/assess`; this gate does identity + trust_level/amr). */
|
|
231
|
+
requiredClaims?: string[];
|
|
232
|
+
/** Trusted issuer URLs surfaced as `trusted_issuers` on untrusted_issuer denials. */
|
|
233
|
+
trustedIssuers?: string[];
|
|
313
234
|
}
|
|
314
235
|
type AipGateResult = {
|
|
315
236
|
ok: true;
|
|
@@ -325,15 +246,62 @@ declare const aipErrorCode: (failure: VerifyAitFailure) => string;
|
|
|
325
246
|
/** HTTP status for an AIP verify failure: 503 when our infra couldn't reach the IdP (retryable),
|
|
326
247
|
* 403 for trust/claims, 401 for auth-presence/signature. */
|
|
327
248
|
declare const aipErrorStatus: (failure: VerifyAitFailure) => 401 | 403 | 503;
|
|
328
|
-
/**
|
|
329
|
-
*
|
|
330
|
-
|
|
331
|
-
*/
|
|
332
|
-
declare const buildAipErrorBody: (failure: VerifyAitFailure) => {
|
|
249
|
+
/** RFC 9457 problem-details body for an AIP denial. Known fields are typed; `required_*` /
|
|
250
|
+
* `trusted_issuers` escalation extensions ride in the index signature. */
|
|
251
|
+
type AipErrorBody = {
|
|
333
252
|
type: string;
|
|
334
253
|
title: string;
|
|
335
254
|
status: number;
|
|
336
255
|
detail: string;
|
|
256
|
+
[k: string]: unknown;
|
|
257
|
+
};
|
|
258
|
+
/** Merchant requirements attached to an AIP escalation body so the agent can self-correct. */
|
|
259
|
+
interface AipErrorRequirements {
|
|
260
|
+
trustedIssuers?: string[];
|
|
261
|
+
requiredClaims?: string[];
|
|
262
|
+
requiredTrustLevel?: TrustLevel;
|
|
263
|
+
requiredAmr?: string[];
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Build an RFC 9457 problem-details body for an AIP verify failure. Adapters serialize this as
|
|
267
|
+
* `application/problem+json` with {@link aipErrorStatus}. Optionally carries the merchant's
|
|
268
|
+
* requirements — `trusted_issuers` on untrusted_issuer; `required_claims` / `required_trust_level` /
|
|
269
|
+
* `required_amr` on insufficient_claims — so the agent learns what would satisfy the gate.
|
|
270
|
+
*/
|
|
271
|
+
declare const buildAipErrorBody: (failure: VerifyAitFailure, requirements?: AipErrorRequirements) => AipErrorBody;
|
|
272
|
+
/**
|
|
273
|
+
* Check a verified AIT against the gate's `trust_level` / `auth.amr` requirements (the spec's
|
|
274
|
+
* human-presence gate). Returns a detail string when insufficient (→ weak_auth), else null.
|
|
275
|
+
*/
|
|
276
|
+
declare const checkTrustRequirements: (payload: {
|
|
277
|
+
trust_level?: string | undefined;
|
|
278
|
+
auth?: {
|
|
279
|
+
amr?: string[] | undefined;
|
|
280
|
+
} | undefined;
|
|
281
|
+
}, requiredTrustLevel?: TrustLevel, requiredAmr?: string[]) => string | null;
|
|
282
|
+
/** Build an RFC 9457 `weak_auth` body for a token that failed the trust_level / auth.amr gate. */
|
|
283
|
+
declare const buildAipWeakAuthBody: (opts: {
|
|
284
|
+
detail: string;
|
|
285
|
+
requiredTrustLevel?: TrustLevel;
|
|
286
|
+
requiredAmr?: string[];
|
|
287
|
+
trustedIssuers?: string[];
|
|
288
|
+
}) => AipErrorBody;
|
|
289
|
+
/** A verified AIT, or a ready-to-render RFC 9457 denial body (HTTP status on `body.status`). */
|
|
290
|
+
type AipGateEvaluation = {
|
|
291
|
+
ok: true;
|
|
292
|
+
ait: VerifiedAit;
|
|
293
|
+
} | {
|
|
294
|
+
ok: false;
|
|
295
|
+
body: AipErrorBody;
|
|
337
296
|
};
|
|
297
|
+
/** Verify + trust-enforce on a standard Fetch `Request` (Hono / Web / Next.js adapters). */
|
|
298
|
+
declare const evaluateAipRequest: (req: Request, opts: AipGateOptions) => Promise<AipGateEvaluation>;
|
|
299
|
+
/** Verify + trust-enforce from Express/Fastify-style parts (Node header map + method + url). */
|
|
300
|
+
declare const evaluateAipParts: (parts: {
|
|
301
|
+
method: string;
|
|
302
|
+
url: string;
|
|
303
|
+
headers: Record<string, string | string[] | undefined>;
|
|
304
|
+
authority?: string;
|
|
305
|
+
}, opts: AipGateOptions) => Promise<AipGateEvaluation>;
|
|
338
306
|
|
|
339
|
-
export { AGENTSCORE_CANONICAL_ISSUER as A, HARD_MAX_CACHE_SECONDS as H,
|
|
307
|
+
export { AGENTSCORE_CANONICAL_ISSUER as A, HARD_MAX_CACHE_SECONDS as H, JWKS_WELL_KNOWN_PATH as J, type VerifiedAit as V, AGENT_IDENTITY_HEADER as a, type AipErrorRequirements as b, type AipGateEvaluation as c, type AipGateOptions as d, type AipGateResult as e, JwksCache as f, type JwksCacheOptions as g, type JwksLookupResult as h, type VerifyAitFailure as i, type VerifyAitOptions as j, type VerifyAitResult as k, type VerifyRequestContext as l, aipErrorCode as m, aipErrorStatus as n, buildAipErrorBody as o, buildAipWeakAuthBody as p, canonicalizeIssuer as q, checkTrustRequirements as r, evaluateAipParts as s, evaluateAipRequest as t, verifyAitRequest as u, verifyAit as v };
|
|
@@ -1,139 +1,6 @@
|
|
|
1
|
+
import { a as AitPayload, T as TrustLevel } from './types-D1slMt0H.mjs';
|
|
1
2
|
import { JWK } from 'jose';
|
|
2
3
|
|
|
3
|
-
/**
|
|
4
|
-
* AIP (Agentic Identity Protocol) token types and the claim contract.
|
|
5
|
-
*
|
|
6
|
-
* An Agent Identity Token (AIT) is a JWT signed by an Identity Provider (IdP). It binds a
|
|
7
|
-
* verified human's identity to the specific agent presenting it (via `cnf`, RFC 7800) and
|
|
8
|
-
* carries the trust level, authentication method, optional intent, and optional identity
|
|
9
|
-
* claims the IdP attests to.
|
|
10
|
-
*
|
|
11
|
-
* This module is the single source of truth for the claim shape on the verifier side. It
|
|
12
|
-
* encodes the spec's required / recommended / optional claims plus the AgentScore extension
|
|
13
|
-
* claims (sanctions, jurisdiction, structured id-verification, cross-merchant graph, payment
|
|
14
|
-
* signer) we carry when we act as a compliance IdP.
|
|
15
|
-
*
|
|
16
|
-
* Extensibility contract (per spec): the `identity` object is open. If a claim is present,
|
|
17
|
-
* the IdP attests to it; verifiers ignore claims they don't recognize. Absence is the
|
|
18
|
-
* "unknown" signal — IdPs do not ship `null` for "not checked".
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/** Degree of human involvement in issuing this specific AIT. */
|
|
22
|
-
type TrustLevel = 'autonomous' | 'human_present' | 'human_confirmed';
|
|
23
|
-
/**
|
|
24
|
-
* Authentication Method Reference values (RFC 8176 / IANA AMR registry). Open set — these
|
|
25
|
-
* are the values relevant to agent identity; others are valid and pass through.
|
|
26
|
-
*/
|
|
27
|
-
type AmrValue = 'face' | 'fpt' | 'hwk' | 'otp' | 'pin' | 'pwd' | 'sms' | 'swk' | 'user' | 'mfa';
|
|
28
|
-
/** RFC 7800 confirmation claim: binds the AIT to the agent's signing key. */
|
|
29
|
-
interface CnfClaim {
|
|
30
|
-
jwk: JWK;
|
|
31
|
-
}
|
|
32
|
-
/** Agent metadata. `provider` is required; `instance` is recommended. */
|
|
33
|
-
interface AgentClaim {
|
|
34
|
-
provider: string;
|
|
35
|
-
instance?: string;
|
|
36
|
-
}
|
|
37
|
-
/** How the user authorized THIS AIT (not prior authentication history). */
|
|
38
|
-
interface AuthClaim {
|
|
39
|
-
amr?: AmrValue[] | string[];
|
|
40
|
-
/** When the user authenticated for this token (Unix seconds). Mirrors OIDC `auth_time`. */
|
|
41
|
-
time?: number;
|
|
42
|
-
}
|
|
43
|
-
/** What the agent intends to do. Optional; verifiers may require it for non-read actions. */
|
|
44
|
-
interface IntentClaim {
|
|
45
|
-
actions?: string[];
|
|
46
|
-
description?: string;
|
|
47
|
-
}
|
|
48
|
-
/** AgentScore wallet-binding extension (orthogonal to `cnf`, which binds the agent key). */
|
|
49
|
-
interface PaymentSignerClaim {
|
|
50
|
-
address: string;
|
|
51
|
-
network: 'evm' | 'solana';
|
|
52
|
-
/** Relationship the IdP attests between signer and the operator graph. */
|
|
53
|
-
match?: 'linked_operator' | 'claimed_operator';
|
|
54
|
-
}
|
|
55
|
-
interface PaymentClaim {
|
|
56
|
-
signer?: PaymentSignerClaim;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Identity claims (presence == IdP attestation). Spec-defined fields plus AgentScore
|
|
60
|
-
* compliance extension claims. Open by contract — unknown fields are allowed and ignored.
|
|
61
|
-
*/
|
|
62
|
-
interface IdentityClaim {
|
|
63
|
-
email?: string;
|
|
64
|
-
email_verified?: boolean;
|
|
65
|
-
name?: string;
|
|
66
|
-
phone?: string;
|
|
67
|
-
phone_verified?: boolean;
|
|
68
|
-
age_over_18?: boolean;
|
|
69
|
-
age_over_21?: boolean;
|
|
70
|
-
id_verified?: boolean;
|
|
71
|
-
id_verification?: {
|
|
72
|
-
provider?: string;
|
|
73
|
-
method?: string;
|
|
74
|
-
document_type?: string;
|
|
75
|
-
verified_at?: number;
|
|
76
|
-
};
|
|
77
|
-
/** ISO 3166-1 alpha-2, optionally with ISO 3166-2 subdivision (e.g. "US-CA"). */
|
|
78
|
-
jurisdiction?: string;
|
|
79
|
-
sanctions_clear?: boolean;
|
|
80
|
-
sanctions_checked_at?: number;
|
|
81
|
-
sanctions_providers?: string[];
|
|
82
|
-
linked_wallets?: Array<{
|
|
83
|
-
address: string;
|
|
84
|
-
network: 'evm' | 'solana';
|
|
85
|
-
}>;
|
|
86
|
-
merchants_paid?: number;
|
|
87
|
-
first_seen?: number;
|
|
88
|
-
[claim: string]: unknown;
|
|
89
|
-
}
|
|
90
|
-
/** The decoded AIT JWT payload. */
|
|
91
|
-
interface AitPayload {
|
|
92
|
-
aip_version: string;
|
|
93
|
-
iss: string;
|
|
94
|
-
sub: string;
|
|
95
|
-
iat: number;
|
|
96
|
-
exp: number;
|
|
97
|
-
cnf: CnfClaim;
|
|
98
|
-
agent: AgentClaim;
|
|
99
|
-
trust_level?: TrustLevel;
|
|
100
|
-
auth?: AuthClaim;
|
|
101
|
-
intent?: IntentClaim;
|
|
102
|
-
identity?: IdentityClaim;
|
|
103
|
-
payment?: PaymentClaim;
|
|
104
|
-
[claim: string]: unknown;
|
|
105
|
-
}
|
|
106
|
-
/** The decoded AIT JWT header. */
|
|
107
|
-
interface AitHeader {
|
|
108
|
-
alg: string;
|
|
109
|
-
typ?: string;
|
|
110
|
-
kid?: string;
|
|
111
|
-
[param: string]: unknown;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Structural validation of a decoded AIT payload. Confirms the required claims are present
|
|
115
|
-
* and well-typed, and enforces the one normative conditional in the spec: a
|
|
116
|
-
* `human_confirmed` token MUST carry at least one `auth.amr` value.
|
|
117
|
-
*
|
|
118
|
-
* This is shape/contract validation only — it does NOT verify signatures (that's the
|
|
119
|
-
* verifier pipeline) and does NOT apply trust policy (that's the gate / `/v1/assess`).
|
|
120
|
-
*/
|
|
121
|
-
type AitValidationResult = {
|
|
122
|
-
ok: true;
|
|
123
|
-
payload: AitPayload;
|
|
124
|
-
} | {
|
|
125
|
-
ok: false;
|
|
126
|
-
reason: AitValidationFailure;
|
|
127
|
-
};
|
|
128
|
-
type AitValidationFailure = 'not_an_object' | 'missing_aip_version' | 'missing_iss' | 'missing_sub' | 'missing_iat' | 'missing_exp' | 'missing_cnf' | 'missing_agent_provider' | 'human_confirmed_without_amr';
|
|
129
|
-
/**
|
|
130
|
-
* Detect whether a decoded JWT payload is an AIT: per spec, an AIT is discriminated by the
|
|
131
|
-
* presence of `cnf` + `agent` claims (not the `typ` header).
|
|
132
|
-
*/
|
|
133
|
-
declare const isAitShape: (payload: unknown) => boolean;
|
|
134
|
-
/** Validate the structural contract of a decoded AIT payload. */
|
|
135
|
-
declare const validateAitPayload: (payload: unknown) => AitValidationResult;
|
|
136
|
-
|
|
137
4
|
/**
|
|
138
5
|
* AIP IdP key discovery: fetch, cache, and select JWKS signing keys.
|
|
139
6
|
*
|
|
@@ -172,7 +39,7 @@ type FetchLike = (url: string, init?: {
|
|
|
172
39
|
* gate/adapter built on it) without the merchant listing it — this SDK is the AgentScore
|
|
173
40
|
* verifier, so a merchant can't accidentally fail to trust AgentScore-issued AITs. `trustedIssuers`
|
|
174
41
|
* only needs to name ADDITIONAL external issuers. */
|
|
175
|
-
declare const AGENTSCORE_CANONICAL_ISSUER = "https://agentscore.
|
|
42
|
+
declare const AGENTSCORE_CANONICAL_ISSUER = "https://www.agentscore.com";
|
|
176
43
|
interface JwksCacheOptions {
|
|
177
44
|
/** ADDITIONAL external issuer URLs to trust beyond AgentScore's own (compared after
|
|
178
45
|
* canonicalization). AgentScore's canonical issuer is always trusted; omit/empty to accept
|
|
@@ -209,6 +76,12 @@ declare class JwksCache {
|
|
|
209
76
|
private readonly now;
|
|
210
77
|
private readonly userAgent;
|
|
211
78
|
private readonly cache;
|
|
79
|
+
/** Per-issuer in-flight refresh promise — coalesces concurrent refreshes to ONE upstream fetch.
|
|
80
|
+
* Without it, a concurrent burst of distinct-kid lookups on a cold/expired cache each call
|
|
81
|
+
* `refresh()` before any has populated the cache → N parallel JWKS GETs (refetch amplification).
|
|
82
|
+
* The cooldown only suppresses SEQUENTIAL refetches; single-flight suppresses CONCURRENT ones.
|
|
83
|
+
* Entry is cleared in a `finally` once the fetch settles. */
|
|
84
|
+
private readonly inflight;
|
|
212
85
|
constructor(opts: JwksCacheOptions);
|
|
213
86
|
/** Is this issuer on the canonicalized trust list? */
|
|
214
87
|
isTrusted(iss: string): boolean;
|
|
@@ -218,7 +91,19 @@ declare class JwksCache {
|
|
|
218
91
|
*/
|
|
219
92
|
getKey(iss: string, kid: string | undefined): Promise<JwksLookupResult>;
|
|
220
93
|
private select;
|
|
94
|
+
/**
|
|
95
|
+
* Refresh the cached key set for `canonIssuer`, coalescing concurrent callers onto a single
|
|
96
|
+
* upstream fetch (single-flight). The first caller for an issuer with no in-flight refresh kicks
|
|
97
|
+
* off the fetch and registers the promise; concurrent callers await that same promise instead of
|
|
98
|
+
* issuing their own GET. The entry is cleared once the fetch settles so the NEXT cold/expired
|
|
99
|
+
* lookup can refresh again.
|
|
100
|
+
*/
|
|
221
101
|
private refresh;
|
|
102
|
+
private fetchAndCache;
|
|
103
|
+
/** Stamp the per-issuer refetch cooldown on a FAILED fetch attempt (the negative cache). Any
|
|
104
|
+
* previously cached keys + expiry are preserved — a failed kid-miss refetch must not nuke a
|
|
105
|
+
* still-fresh key set; only the cooldown and failure reason are updated. */
|
|
106
|
+
private stampFailure;
|
|
222
107
|
}
|
|
223
108
|
|
|
224
109
|
/**
|
|
@@ -260,6 +145,12 @@ interface VerifyAitOptions {
|
|
|
260
145
|
jwks: JwksCache;
|
|
261
146
|
now?: number;
|
|
262
147
|
maxSkewSeconds?: number;
|
|
148
|
+
/** Max accepted AIT lifetime (`exp - iat`) in seconds. Defense-in-depth vs an external issuer
|
|
149
|
+
* minting a long-lived bearer credential. The spec recommends a 60–300s window; default 300 so a
|
|
150
|
+
* stolen AIT's usable window stays short even at the edge (standalone `aipGate`, no `/v1/assess`).
|
|
151
|
+
* Our own mint is 300s, so first-party tokens sit exactly at the ceiling. Matches the
|
|
152
|
+
* authoritative API verifier's default (the AgentScore API verifier), lowered from 3600. */
|
|
153
|
+
maxLifetimeSeconds?: number;
|
|
263
154
|
}
|
|
264
155
|
/**
|
|
265
156
|
* Failure reasons, aligned with AIP wire error codes. The gate maps:
|
|
@@ -276,6 +167,16 @@ interface VerifiedAit {
|
|
|
276
167
|
/** The raw JWT string that verified (the winning `Agent-Identity` header value, Bearer
|
|
277
168
|
* prefix stripped). Lets a gate forward the exact token to `/v1/assess` as `aip_token`. */
|
|
278
169
|
token: string;
|
|
170
|
+
/** The RFC 9421 signature material for this request — forwarded to `/v1/assess` as
|
|
171
|
+
* `aip_signature` so the API re-verifies proof-of-possession authoritatively (the edge
|
|
172
|
+
* check here is only a fail-fast filter; the API is the source of truth). */
|
|
173
|
+
signatureMaterial: {
|
|
174
|
+
method: string;
|
|
175
|
+
authority: string;
|
|
176
|
+
path: string;
|
|
177
|
+
signature_input: string;
|
|
178
|
+
signature: string;
|
|
179
|
+
};
|
|
279
180
|
}
|
|
280
181
|
type VerifyAitResult = {
|
|
281
182
|
ok: true;
|
|
@@ -310,6 +211,26 @@ interface AipGateOptions {
|
|
|
310
211
|
jwks: JwksCache;
|
|
311
212
|
now?: number;
|
|
312
213
|
maxSkewSeconds?: number;
|
|
214
|
+
/** Expected `@authority` (public hostname) the RFC 9421 signature must cover. When set, the
|
|
215
|
+
* verifier binds the signature to this value instead of trusting the inbound `Host` header —
|
|
216
|
+
* pin it to your real public host (e.g. `'wine.example.com'`) when behind a proxy or
|
|
217
|
+
* multi-vhost listener that does not normalize `Host`, to prevent a captured AIT+signature
|
|
218
|
+
* from being replayed to a different virtual host on the same origin. Same semantics as
|
|
219
|
+
* Checkout's `AipGateConfig.authority`. */
|
|
220
|
+
authority?: string;
|
|
221
|
+
/** Minimum `trust_level` (autonomous < human_present < human_confirmed) the AIT must assert —
|
|
222
|
+
* the spec's human-presence gate. Insufficient → 403 weak_auth with `required_trust_level`.
|
|
223
|
+
* Enforced by {@link evaluateAipRequest} / {@link evaluateAipParts}. Unset = any trust level. */
|
|
224
|
+
requireTrustLevel?: TrustLevel;
|
|
225
|
+
/** Acceptable `auth.amr` methods (RFC 8176); the AIT must carry ≥1. Insufficient → 403 weak_auth
|
|
226
|
+
* with `required_amr`. Unset = not enforced. */
|
|
227
|
+
requireAmr?: string[];
|
|
228
|
+
/** Identity claims the endpoint needs — surfaced as `required_claims` on insufficient_claims
|
|
229
|
+
* denials so the agent can self-correct. Advisory only (enforce by feeding the verified claims
|
|
230
|
+
* to your own policy / `/v1/assess`; this gate does identity + trust_level/amr). */
|
|
231
|
+
requiredClaims?: string[];
|
|
232
|
+
/** Trusted issuer URLs surfaced as `trusted_issuers` on untrusted_issuer denials. */
|
|
233
|
+
trustedIssuers?: string[];
|
|
313
234
|
}
|
|
314
235
|
type AipGateResult = {
|
|
315
236
|
ok: true;
|
|
@@ -325,15 +246,62 @@ declare const aipErrorCode: (failure: VerifyAitFailure) => string;
|
|
|
325
246
|
/** HTTP status for an AIP verify failure: 503 when our infra couldn't reach the IdP (retryable),
|
|
326
247
|
* 403 for trust/claims, 401 for auth-presence/signature. */
|
|
327
248
|
declare const aipErrorStatus: (failure: VerifyAitFailure) => 401 | 403 | 503;
|
|
328
|
-
/**
|
|
329
|
-
*
|
|
330
|
-
|
|
331
|
-
*/
|
|
332
|
-
declare const buildAipErrorBody: (failure: VerifyAitFailure) => {
|
|
249
|
+
/** RFC 9457 problem-details body for an AIP denial. Known fields are typed; `required_*` /
|
|
250
|
+
* `trusted_issuers` escalation extensions ride in the index signature. */
|
|
251
|
+
type AipErrorBody = {
|
|
333
252
|
type: string;
|
|
334
253
|
title: string;
|
|
335
254
|
status: number;
|
|
336
255
|
detail: string;
|
|
256
|
+
[k: string]: unknown;
|
|
257
|
+
};
|
|
258
|
+
/** Merchant requirements attached to an AIP escalation body so the agent can self-correct. */
|
|
259
|
+
interface AipErrorRequirements {
|
|
260
|
+
trustedIssuers?: string[];
|
|
261
|
+
requiredClaims?: string[];
|
|
262
|
+
requiredTrustLevel?: TrustLevel;
|
|
263
|
+
requiredAmr?: string[];
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Build an RFC 9457 problem-details body for an AIP verify failure. Adapters serialize this as
|
|
267
|
+
* `application/problem+json` with {@link aipErrorStatus}. Optionally carries the merchant's
|
|
268
|
+
* requirements — `trusted_issuers` on untrusted_issuer; `required_claims` / `required_trust_level` /
|
|
269
|
+
* `required_amr` on insufficient_claims — so the agent learns what would satisfy the gate.
|
|
270
|
+
*/
|
|
271
|
+
declare const buildAipErrorBody: (failure: VerifyAitFailure, requirements?: AipErrorRequirements) => AipErrorBody;
|
|
272
|
+
/**
|
|
273
|
+
* Check a verified AIT against the gate's `trust_level` / `auth.amr` requirements (the spec's
|
|
274
|
+
* human-presence gate). Returns a detail string when insufficient (→ weak_auth), else null.
|
|
275
|
+
*/
|
|
276
|
+
declare const checkTrustRequirements: (payload: {
|
|
277
|
+
trust_level?: string | undefined;
|
|
278
|
+
auth?: {
|
|
279
|
+
amr?: string[] | undefined;
|
|
280
|
+
} | undefined;
|
|
281
|
+
}, requiredTrustLevel?: TrustLevel, requiredAmr?: string[]) => string | null;
|
|
282
|
+
/** Build an RFC 9457 `weak_auth` body for a token that failed the trust_level / auth.amr gate. */
|
|
283
|
+
declare const buildAipWeakAuthBody: (opts: {
|
|
284
|
+
detail: string;
|
|
285
|
+
requiredTrustLevel?: TrustLevel;
|
|
286
|
+
requiredAmr?: string[];
|
|
287
|
+
trustedIssuers?: string[];
|
|
288
|
+
}) => AipErrorBody;
|
|
289
|
+
/** A verified AIT, or a ready-to-render RFC 9457 denial body (HTTP status on `body.status`). */
|
|
290
|
+
type AipGateEvaluation = {
|
|
291
|
+
ok: true;
|
|
292
|
+
ait: VerifiedAit;
|
|
293
|
+
} | {
|
|
294
|
+
ok: false;
|
|
295
|
+
body: AipErrorBody;
|
|
337
296
|
};
|
|
297
|
+
/** Verify + trust-enforce on a standard Fetch `Request` (Hono / Web / Next.js adapters). */
|
|
298
|
+
declare const evaluateAipRequest: (req: Request, opts: AipGateOptions) => Promise<AipGateEvaluation>;
|
|
299
|
+
/** Verify + trust-enforce from Express/Fastify-style parts (Node header map + method + url). */
|
|
300
|
+
declare const evaluateAipParts: (parts: {
|
|
301
|
+
method: string;
|
|
302
|
+
url: string;
|
|
303
|
+
headers: Record<string, string | string[] | undefined>;
|
|
304
|
+
authority?: string;
|
|
305
|
+
}, opts: AipGateOptions) => Promise<AipGateEvaluation>;
|
|
338
306
|
|
|
339
|
-
export { AGENTSCORE_CANONICAL_ISSUER as A, HARD_MAX_CACHE_SECONDS as H,
|
|
307
|
+
export { AGENTSCORE_CANONICAL_ISSUER as A, HARD_MAX_CACHE_SECONDS as H, JWKS_WELL_KNOWN_PATH as J, type VerifiedAit as V, AGENT_IDENTITY_HEADER as a, type AipErrorRequirements as b, type AipGateEvaluation as c, type AipGateOptions as d, type AipGateResult as e, JwksCache as f, type JwksCacheOptions as g, type JwksLookupResult as h, type VerifyAitFailure as i, type VerifyAitOptions as j, type VerifyAitResult as k, type VerifyRequestContext as l, aipErrorCode as m, aipErrorStatus as n, buildAipErrorBody as o, buildAipWeakAuthBody as p, canonicalizeIssuer as q, checkTrustRequirements as r, evaluateAipParts as s, evaluateAipRequest as t, verifyAitRequest as u, verifyAit as v };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as AipGateOptions, o as buildAipErrorBody, V as VerifiedAit } from '../gate-GCXy4FHI.mjs';
|
|
2
2
|
import { AgentScoreCoreOptions, AgentIdentity, DenialReason, CreateSessionOnMissing, AssessResult, FailOpenInfraReason, GateQuotaInfo, SignerVerdict } from '../core.mjs';
|
|
3
3
|
import { Request, Response, NextFunction } from 'express';
|
|
4
|
+
import '../types-D1slMt0H.mjs';
|
|
4
5
|
import 'jose';
|
|
6
|
+
import '@agent-score/sdk';
|
|
5
7
|
import '../signer-3FAit11j.mjs';
|
|
6
8
|
|
|
7
9
|
interface AgentScoreGateOptions extends Omit<AgentScoreCoreOptions, 'createSessionOnMissing'> {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as AipGateOptions, o as buildAipErrorBody, V as VerifiedAit } from '../gate-D2RP6bZg.js';
|
|
2
2
|
import { AgentScoreCoreOptions, AgentIdentity, DenialReason, CreateSessionOnMissing, AssessResult, FailOpenInfraReason, GateQuotaInfo, SignerVerdict } from '../core.js';
|
|
3
3
|
import { Request, Response, NextFunction } from 'express';
|
|
4
|
+
import '../types-D1slMt0H.js';
|
|
4
5
|
import 'jose';
|
|
6
|
+
import '@agent-score/sdk';
|
|
5
7
|
import '../signer-3FAit11j.js';
|
|
6
8
|
|
|
7
9
|
interface AgentScoreGateOptions extends Omit<AgentScoreCoreOptions, 'createSessionOnMissing'> {
|