@agenticprimitives/connect 0.1.0-alpha.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agentic Trust Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # @agenticprimitives/connect
2
+
3
+ **Agentic Connect** — the SSO broker ([spec 224](../../specs/224-agentic-connect.md);
4
+ [ADR-0014](../../docs/architecture/decisions/0014-connect-is-an-sso-broker.md)).
5
+ It runs at one central origin, proves a credential once (via
6
+ [`connect-auth`](../connect-auth)), resolves it to a canonical agent (via
7
+ [`identity-directory`](../identity-directory)), and issues a **CAIP-10-subject,
8
+ no-owner `AgentSession`** that relying sites verify with the broker's public key.
9
+
10
+ ## What's here
11
+
12
+ ```
13
+ token.ts AgentSession mint/verify + JWKS — asymmetric (EdDSA/ES256), alg-pinned (CN-4)
14
+ broker.ts convergence (0→bootstrap / 1→issue / many→disambiguate) + issuance gates (CN-2/5/6/8)
15
+ redirect.ts redirect_uri allowlist + single-use auth-code store (CN-1/9)
16
+ ```
17
+
18
+ ## Usage (sketch)
19
+
20
+ ```ts
21
+ import { generateBrokerKeypair, issueForResolution, verifyAgentSession, publishJwks } from '@agenticprimitives/connect';
22
+
23
+ const signer = await generateBrokerKeypair(); // EdDSA by default
24
+ const jwks = await publishJwks([signer]); // serve at /.well-known/jwks.json
25
+
26
+ // after connect-auth verifies a credential and identity-directory resolves it:
27
+ const out = await issueForResolution({ resolution, principal, signer, aud: clientId, iss: connectOrigin, ttlSeconds: 600 });
28
+ // out.status: 'issued' (token) | 'bootstrap' | 'disambiguate' | 'rejected'
29
+
30
+ // relying site:
31
+ const v = await verifyAgentSession(token, { keys: await importJwks(jwks), expectedIss: connectOrigin, expectedAud: clientId });
32
+ ```
33
+
34
+ ## Security (audit CN controls)
35
+
36
+ - **Token (CN-4):** verification pins the algorithm to the key (by `kid`), never
37
+ the token's header — rejects `alg:none` + RS/ES↔HS confusion; an `AgentSession`
38
+ carrying an `owner` is rejected (ADR-0016).
39
+ - **Issuance (CN-6/CN-8):** an existing-agent session needs `onchain-confirmed`
40
+ assurance (which the directory only assigns after an on-chain membership
41
+ confirm — a revoked credential never reaches issuance); a non-`eip155` subject
42
+ is identifier-only (no control session).
43
+ - **Disambiguation (CN-5):** the chosen subject is server-validated against the
44
+ resolution set; never a client-echoed `sub`.
45
+ - **Redirect (CN-1/9):** exact-match `redirect_uri` allowlist + single-use,
46
+ TTL-bounded auth-code exchange — the token never rides in a URL.
47
+ - **Step-up (CN-2):** `requiresStepUp` classifies custody-class actions; a
48
+ login-grade session authorizes no on-chain write.
49
+
50
+ The HS256 same-origin `BrokerSession` is `connect-auth`'s, a different token from
51
+ this asymmetric cross-origin `AgentSession`.
@@ -0,0 +1,78 @@
1
+ import { type Resolution, type IdentityDirectory } from '@agenticprimitives/identity-directory';
2
+ import type { CanonicalAgentId, CredentialPrincipal, Assurance } from '@agenticprimitives/types';
3
+ import { type BrokerSigner } from './token';
4
+ export type { IdentityDirectory };
5
+ /** The convergence cardinality the broker branches on (spec 224 §5). */
6
+ export type Convergence = {
7
+ kind: 'none';
8
+ } | {
9
+ kind: 'one';
10
+ agent: CanonicalAgentId;
11
+ assurance: Assurance;
12
+ } | {
13
+ kind: 'many';
14
+ agents: Array<{
15
+ id: CanonicalAgentId;
16
+ assurance: Assurance;
17
+ }>;
18
+ };
19
+ export declare function convergence(resolution: Resolution): Convergence;
20
+ /** Only `eip155` subjects are custodied by this stack (CN-8; spec 226 §4). */
21
+ export declare function isCustodiedNamespace(id: CanonicalAgentId): boolean;
22
+ /** A control session that authenticates an existing agent needs this floor (CN-6). */
23
+ export declare const SESSION_ISSUANCE_FLOOR: Assurance;
24
+ export type IssueDecision = {
25
+ ok: true;
26
+ } | {
27
+ ok: false;
28
+ reason: string;
29
+ };
30
+ /** Gate a would-be session issuance for one resolved agent. */
31
+ export declare function canIssueSession(agentId: CanonicalAgentId, assurance: Assurance, opts?: {
32
+ floor?: Assurance;
33
+ }): IssueDecision;
34
+ /**
35
+ * Disambiguation server-binding (CN-5): the user's chosen subject MUST be a
36
+ * member of the exact resolution set. Never trust a client-echoed `sub`.
37
+ */
38
+ export declare function selectFromResolution(resolution: Resolution, chosenSub: string): CanonicalAgentId | null;
39
+ /** Custody-class actions that require step-up (CN-2 / §8). */
40
+ export declare const CUSTODY_CLASS_ACTIONS: readonly ["credential-change", "custody-policy-change", "high-value-spend", "delegation-issue"];
41
+ export type CustodyClassAction = (typeof CUSTODY_CLASS_ACTIONS)[number];
42
+ /** Does this action require step-up to a custody-grade credential? */
43
+ export declare function requiresStepUp(action: string): action is CustodyClassAction;
44
+ export interface IssueForResolutionInput {
45
+ resolution: Resolution;
46
+ principal: CredentialPrincipal;
47
+ signer: BrokerSigner;
48
+ aud: string;
49
+ iss: string;
50
+ ttlSeconds: number;
51
+ floor?: Assurance;
52
+ now?: () => number;
53
+ }
54
+ export type IssueOutcome = {
55
+ status: 'issued';
56
+ token: string;
57
+ sub: CanonicalAgentId;
58
+ assurance: Assurance;
59
+ } | {
60
+ status: 'bootstrap';
61
+ } | {
62
+ status: 'disambiguate';
63
+ agents: Array<{
64
+ id: CanonicalAgentId;
65
+ assurance: Assurance;
66
+ }>;
67
+ } | {
68
+ status: 'rejected';
69
+ reason: string;
70
+ };
71
+ /**
72
+ * Drive convergence → outcome. The single-agent path enforces the non-EVM gate +
73
+ * assurance floor before minting; 0 → bootstrap (the caller rate-limits, CN-11);
74
+ * many → disambiguate (the caller then re-enters with a chosen sub validated via
75
+ * selectFromResolution, CN-5).
76
+ */
77
+ export declare function issueForResolution(input: IssueForResolutionInput): Promise<IssueOutcome>;
78
+ //# sourceMappingURL=broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../src/broker.ts"],"names":[],"mappings":"AAcA,OAAO,EAAoB,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAClH,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAE9D,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,wEAAwE;AACxE,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,gBAAgB,CAAC;QAAC,SAAS,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC;AAEpF,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,WAAW,CAK/D;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAElE;AAED,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,EAAE,SAA+B,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,+DAA+D;AAC/D,wBAAgB,eAAe,CAC7B,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,SAAS,EACpB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAA;CAAO,GAC/B,aAAa,CASf;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAGvG;AAED,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,iGAKxB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,kBAAkB,CAE3E;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GAChF;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,gBAAgB,CAAC;QAAC,SAAS,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;CAAE,GACzF;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB9F"}
package/dist/broker.js ADDED
@@ -0,0 +1,86 @@
1
+ // Broker convergence + session issuance (spec 224 §5/§8).
2
+ //
3
+ // Ties identity-directory resolution to AgentSession issuance, enforcing:
4
+ // - Convergence cardinality: 0 → bootstrap, 1 → issue, many → disambiguate.
5
+ // - Session-issuance assurance FLOOR (CN-6): an existing-agent session needs
6
+ // `onchain-confirmed` (which the directory only assigns after an on-chain
7
+ // membership confirm — so a revoked credential never reaches issuance).
8
+ // - Non-EVM control-status GATE (CN-8): a non-`eip155` subject is identifier-
9
+ // only — read/identifier-grade at most, never a control session.
10
+ // - Disambiguation server-binding (CN-5): the chosen sub MUST be in the
11
+ // resolution set returned by convergence.
12
+ // - Step-up classification (CN-2 / §8): custody-class actions need a
13
+ // custody-grade credential; a login-grade session authorizes no on-chain write.
14
+ import { compareAssurance } from '@agenticprimitives/identity-directory';
15
+ import { mintAgentSession } from './token';
16
+ export function convergence(resolution) {
17
+ const agents = resolution.agents;
18
+ if (agents.length === 0)
19
+ return { kind: 'none' };
20
+ if (agents.length === 1)
21
+ return { kind: 'one', agent: agents[0].id, assurance: agents[0].assurance };
22
+ return { kind: 'many', agents: agents.map((a) => ({ id: a.id, assurance: a.assurance })) };
23
+ }
24
+ /** Only `eip155` subjects are custodied by this stack (CN-8; spec 226 §4). */
25
+ export function isCustodiedNamespace(id) {
26
+ return id.startsWith('eip155:');
27
+ }
28
+ /** A control session that authenticates an existing agent needs this floor (CN-6). */
29
+ export const SESSION_ISSUANCE_FLOOR = 'onchain-confirmed';
30
+ /** Gate a would-be session issuance for one resolved agent. */
31
+ export function canIssueSession(agentId, assurance, opts = {}) {
32
+ if (!isCustodiedNamespace(agentId)) {
33
+ return { ok: false, reason: 'non-EVM subject is identifier-only (read/identifier-grade only); cannot issue a control session (CN-8)' };
34
+ }
35
+ const floor = opts.floor ?? SESSION_ISSUANCE_FLOOR;
36
+ if (compareAssurance(assurance, floor) < 0) {
37
+ return { ok: false, reason: `assurance "${assurance}" is below the issuance floor "${floor}" (CN-6); step-up required` };
38
+ }
39
+ return { ok: true };
40
+ }
41
+ /**
42
+ * Disambiguation server-binding (CN-5): the user's chosen subject MUST be a
43
+ * member of the exact resolution set. Never trust a client-echoed `sub`.
44
+ */
45
+ export function selectFromResolution(resolution, chosenSub) {
46
+ const match = resolution.agents.find((a) => a.id === chosenSub);
47
+ return match ? match.id : null;
48
+ }
49
+ /** Custody-class actions that require step-up (CN-2 / §8). */
50
+ export const CUSTODY_CLASS_ACTIONS = [
51
+ 'credential-change',
52
+ 'custody-policy-change',
53
+ 'high-value-spend',
54
+ 'delegation-issue',
55
+ ];
56
+ /** Does this action require step-up to a custody-grade credential? */
57
+ export function requiresStepUp(action) {
58
+ return CUSTODY_CLASS_ACTIONS.includes(action);
59
+ }
60
+ /**
61
+ * Drive convergence → outcome. The single-agent path enforces the non-EVM gate +
62
+ * assurance floor before minting; 0 → bootstrap (the caller rate-limits, CN-11);
63
+ * many → disambiguate (the caller then re-enters with a chosen sub validated via
64
+ * selectFromResolution, CN-5).
65
+ */
66
+ export async function issueForResolution(input) {
67
+ const c = convergence(input.resolution);
68
+ if (c.kind === 'none')
69
+ return { status: 'bootstrap' };
70
+ if (c.kind === 'many')
71
+ return { status: 'disambiguate', agents: c.agents };
72
+ const decision = canIssueSession(c.agent, c.assurance, { floor: input.floor });
73
+ if (!decision.ok)
74
+ return { status: 'rejected', reason: decision.reason };
75
+ const token = await mintAgentSession({
76
+ sub: c.agent,
77
+ principal: input.principal,
78
+ assurance: c.assurance,
79
+ aud: input.aud,
80
+ iss: input.iss,
81
+ ttlSeconds: input.ttlSeconds,
82
+ now: input.now,
83
+ }, input.signer);
84
+ return { status: 'issued', token, sub: c.agent, assurance: c.assurance };
85
+ }
86
+ //# sourceMappingURL=broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.js","sourceRoot":"","sources":["../src/broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { generateBrokerKeypair, mintAgentSession, verifyAgentSession, mintIdToken, mintBoundIdToken, verifyIdToken, verifyEnrollmentGrantBinding, verifyPkceS256, exportPublicJwk, publishJwks, importJwks, type BrokerAlg, type BrokerSigner, type VerifyKey, type VerifyResult, type VerifyOpts, type MintAgentSessionInput, type OidcIdToken, type MintIdTokenInput, type BoundMintIdTokenInput, type VerifyIdTokenResult, type VerifyIdTokenOpts, } from './token';
2
+ export { convergence, isCustodiedNamespace, SESSION_ISSUANCE_FLOOR, canIssueSession, selectFromResolution, requiresStepUp, CUSTODY_CLASS_ACTIONS, issueForResolution, type Convergence, type IssueDecision, type CustodyClassAction, type IssueForResolutionInput, type IssueOutcome, } from './broker';
3
+ export { validateRedirectUri, newAuthCode, createInMemoryAuthCodeStore, type AuthCodeValue, type AuthCodeStore, } from './redirect';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,cAAc,EACd,eAAe,EACf,WAAW,EACX,UAAU,EACV,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,2BAA2B,EAC3B,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ // @agenticprimitives/connect — the SSO broker (spec 224 / ADR-0014).
2
+ //
3
+ // State-machine + token issuer that ties connect-auth (credential ceremonies) +
4
+ // identity-directory (resolution) into a CAIP-10-subject, no-owner AgentSession.
5
+ //
6
+ // See:
7
+ // - capability.manifest.json — boundary (types + connect-auth + identity-directory)
8
+ // - ../../specs/224-agentic-connect.md — the contract
9
+ // - ../../docs/architecture/decisions/0014-connect-is-an-sso-broker.md
10
+ // Token layer (asymmetric AgentSession + JWKS; CN-4) + OIDC id_token / PKCE (spec 230).
11
+ export { generateBrokerKeypair, mintAgentSession, verifyAgentSession, mintIdToken, mintBoundIdToken, verifyIdToken, verifyEnrollmentGrantBinding, verifyPkceS256, exportPublicJwk, publishJwks, importJwks, } from './token';
12
+ // Broker convergence + issuance (CN-2/5/6/8).
13
+ export { convergence, isCustodiedNamespace, SESSION_ISSUANCE_FLOOR, canIssueSession, selectFromResolution, requiresStepUp, CUSTODY_CLASS_ACTIONS, issueForResolution, } from './broker';
14
+ // Redirect & response delivery (CN-1/9).
15
+ export { validateRedirectUri, newAuthCode, createInMemoryAuthCodeStore, } from './redirect';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,EAAE;AACF,OAAO;AACP,sFAAsF;AACtF,wDAAwD;AACxD,yEAAyE;AAEzE,wFAAwF;AACxF,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,4BAA4B,EAC5B,cAAc,EACd,eAAe,EACf,WAAW,EACX,UAAU,GAYX,MAAM,SAAS,CAAC;AAEjB,8CAA8C;AAC9C,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,kBAAkB,GAMnB,MAAM,UAAU,CAAC;AAElB,yCAAyC;AACzC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,2BAA2B,GAG5B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Validate a requested `redirect_uri` against a per-client allowlist (CN-1).
3
+ * EXACT match only — never substring/prefix (open-redirect defense). The
4
+ * allowlist is registered out-of-band per `client_id`, never user-supplied.
5
+ */
6
+ export declare function validateRedirectUri(registered: readonly string[], requested: string): boolean;
7
+ export interface AuthCodeValue {
8
+ /** The minted AgentSession token. */
9
+ token: string;
10
+ /** The relying-site client_id this code (and token) is bound to. */
11
+ aud: string;
12
+ }
13
+ export interface AuthCodeStore {
14
+ /** Store a code → value with a TTL (ms). */
15
+ put(code: string, value: AuthCodeValue, ttlMs: number): void;
16
+ /** Single-use take: returns the value once (removing it) if present + unexpired, else null. */
17
+ take(code: string): AuthCodeValue | null;
18
+ }
19
+ /** Generate a single-use authorization code. */
20
+ export declare function newAuthCode(byteLen?: number): string;
21
+ /**
22
+ * In-memory single-use auth-code store (demo/tests; CN-9). `take` is atomic
23
+ * (deletes on read) so a code can be exchanged at most once. Production uses a
24
+ * shared store (e.g. KV/D1) with the same single-use contract.
25
+ */
26
+ export declare function createInMemoryAuthCodeStore(now?: () => number): AuthCodeStore;
27
+ //# sourceMappingURL=redirect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7F;AAED,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7D,+FAA+F;IAC/F,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;CAC1C;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,OAAO,SAAK,GAAG,MAAM,CAKhD;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,GAAE,MAAM,MAAyB,GAAG,aAAa,CAc/F"}
@@ -0,0 +1,46 @@
1
+ // Redirect & response delivery (spec 224 §4a; CN-1 / CN-9).
2
+ //
3
+ // The AgentSession is NOT delivered as a bearer token in a redirect URL.
4
+ // Instead: the broker mints the token, stores it under a single-use, short-TTL
5
+ // authorization CODE, and redirects with the code; the relying site exchanges
6
+ // the code server-side at the broker token endpoint for the token. This keeps
7
+ // the token out of URLs/history/Referer and gives the broker (which holds the
8
+ // atomic store) the single-use replay guarantee — relying sites need no store.
9
+ /**
10
+ * Validate a requested `redirect_uri` against a per-client allowlist (CN-1).
11
+ * EXACT match only — never substring/prefix (open-redirect defense). The
12
+ * allowlist is registered out-of-band per `client_id`, never user-supplied.
13
+ */
14
+ export function validateRedirectUri(registered, requested) {
15
+ return registered.includes(requested);
16
+ }
17
+ /** Generate a single-use authorization code. */
18
+ export function newAuthCode(byteLen = 32) {
19
+ const b = new Uint8Array(byteLen);
20
+ globalThis.crypto.getRandomValues(b);
21
+ let s = typeof Buffer !== 'undefined' ? Buffer.from(b).toString('base64') : btoa(String.fromCharCode(...b));
22
+ return s.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
23
+ }
24
+ /**
25
+ * In-memory single-use auth-code store (demo/tests; CN-9). `take` is atomic
26
+ * (deletes on read) so a code can be exchanged at most once. Production uses a
27
+ * shared store (e.g. KV/D1) with the same single-use contract.
28
+ */
29
+ export function createInMemoryAuthCodeStore(now = () => Date.now()) {
30
+ const store = new Map();
31
+ return {
32
+ put(code, value, ttlMs) {
33
+ store.set(code, { value, expiresAt: now() + ttlMs });
34
+ },
35
+ take(code) {
36
+ const rec = store.get(code);
37
+ if (!rec)
38
+ return null;
39
+ store.delete(code); // single-use: gone after one read, even if expired
40
+ if (rec.expiresAt <= now())
41
+ return null;
42
+ return rec.value;
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=redirect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA6B,EAAE,SAAiB;IAClF,OAAO,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAgBD,gDAAgD;AAChD,MAAM,UAAU,WAAW,CAAC,OAAO,GAAG,EAAE;IACtC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5G,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAoB,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;IAC9E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuD,CAAC;IAC7E,OAAO;QACL,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK;YACpB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,IAAI;YACP,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,mDAAmD;YACvE,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,EAAE;gBAAE,OAAO,IAAI,CAAC;YACxC,OAAO,GAAG,CAAC,KAAK,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,193 @@
1
+ import type { AgentSession, CanonicalAgentId, CredentialPrincipal, Assurance } from '@agenticprimitives/types';
2
+ export type BrokerAlg = 'EdDSA' | 'ES256';
3
+ export interface BrokerSigner {
4
+ kid: string;
5
+ alg: BrokerAlg;
6
+ privateKey: CryptoKey;
7
+ publicKey: CryptoKey;
8
+ }
9
+ /** A public verification key (the relying-site side; from a JWKS). */
10
+ export interface VerifyKey {
11
+ kid: string;
12
+ alg: BrokerAlg;
13
+ publicKey: CryptoKey;
14
+ }
15
+ /** Generate a broker signing keypair. EdDSA (Ed25519) by default; ES256 fallback. */
16
+ export declare function generateBrokerKeypair(alg?: BrokerAlg): Promise<BrokerSigner>;
17
+ export interface MintAgentSessionInput {
18
+ sub: CanonicalAgentId;
19
+ principal: CredentialPrincipal;
20
+ assurance: Assurance;
21
+ /** Relying-site client_id (exact-match audience). */
22
+ aud: string;
23
+ /** The Connect origin. */
24
+ iss: string;
25
+ ttlSeconds: number;
26
+ now?: () => number;
27
+ jti?: string;
28
+ /** Per-subject derivation rotation (Google × KMS custody, spec 235 §5b). Carried so the custody
29
+ * gate derives the matching per-subject key. Omitted for non-rotated sessions. */
30
+ rotation?: number;
31
+ }
32
+ /** Mint a signed AgentSession (asymmetric). */
33
+ export declare function mintAgentSession(input: MintAgentSessionInput, signer: BrokerSigner): Promise<string>;
34
+ export type VerifyResult = {
35
+ ok: true;
36
+ session: AgentSession;
37
+ } | {
38
+ ok: false;
39
+ reason: string;
40
+ };
41
+ export interface VerifyOpts {
42
+ keys: VerifyKey[];
43
+ /**
44
+ * Audience expected for this AgentSession. **Required** (H7-B.4 closure of
45
+ * PKG-CONNECT-001-sec). The legacy optional form let a caller verify any
46
+ * AgentSession against any audience-A token mistakenly accepted at
47
+ * audience-B. Aligns with `verifyIdToken` which already required this.
48
+ */
49
+ expectedAud: string;
50
+ expectedIss?: string;
51
+ now?: () => number;
52
+ /**
53
+ * H7-B.4: explicit `iat` clock-skew tolerance in seconds. Default 30.
54
+ * Tokens whose `iat` is more than `clockSkewSec` in the future are
55
+ * rejected (closes PKG-CONNECT-002 — future-dated tokens were accepted).
56
+ */
57
+ clockSkewSec?: number;
58
+ }
59
+ /** Verify an AgentSession. Alg is PINNED to the key (by kid), never the token's header. */
60
+ export declare function verifyAgentSession(token: string, opts: VerifyOpts): Promise<VerifyResult>;
61
+ export interface OidcIdToken {
62
+ iss: string;
63
+ sub: CanonicalAgentId;
64
+ aud: string;
65
+ iat: number;
66
+ exp: number;
67
+ nonce?: string;
68
+ agent_name?: string;
69
+ canonical_agent_id: CanonicalAgentId;
70
+ }
71
+ /**
72
+ * @internal — broker-internal mint shape. **Do not call from relying-app
73
+ * code** (app-level SEC-001/SEC-002 root cause). The bound surface is
74
+ * {@link BoundMintIdTokenInput} + {@link mintBoundIdToken} (H7-B.5 closure
75
+ * of PKG-connect-001-arch). The two-flow split keeps the broker's internal
76
+ * mint distinct from any cross-origin enrollment mint a relying app might
77
+ * attempt.
78
+ */
79
+ export interface MintIdTokenInput {
80
+ iss: string;
81
+ sub: CanonicalAgentId;
82
+ aud: string;
83
+ ttlSeconds: number;
84
+ nonce?: string;
85
+ agentName?: string;
86
+ now?: () => number;
87
+ }
88
+ /**
89
+ * H7-B.5 (PKG-connect-001-arch closure) — the **bound** mint surface.
90
+ *
91
+ * Every id_token issued in response to a cross-origin enrollment grant MUST
92
+ * carry binding fields tying the token to:
93
+ *
94
+ * - `enrollmentGrantId` — the server-minted grant the user authorized
95
+ * (closes the SEC-001 app-level root cause: tokens issued without
96
+ * reference to an in-flight grant can be replayed to any registered RP).
97
+ * - `delegationHash` — keccak256 of the issued scoped delegation
98
+ * (closes SEC-002 lateral-movement: tokens become tied to the exact
99
+ * delegation, not just `{aud, sub}`).
100
+ *
101
+ * Relying apps verify these via {@link verifyEnrollmentGrantBinding} after
102
+ * a standard {@link verifyIdToken} pass.
103
+ */
104
+ export interface BoundMintIdTokenInput extends MintIdTokenInput {
105
+ /** Server-minted grant id this mint is authorized by (spec 230 §4.2). */
106
+ enrollmentGrantId: string;
107
+ /** keccak256 of the scoped delegation accompanying this enrollment. */
108
+ delegationHash: `0x${string}`;
109
+ }
110
+ /**
111
+ * @internal — mints an OIDC id_token signed with the broker key. Used by
112
+ * the broker's own re-auth path where no enrollment grant exists.
113
+ *
114
+ * Cross-origin enrollment **MUST** use {@link mintBoundIdToken} which
115
+ * additionally encodes `enrollment_grant_id` + `delegation_hash` so the
116
+ * relying app can verify the bind via {@link verifyEnrollmentGrantBinding}.
117
+ *
118
+ * `canonical_agent_id` mirrors `sub`.
119
+ */
120
+ export declare function mintIdToken(input: MintIdTokenInput, signer: BrokerSigner): Promise<string>;
121
+ /**
122
+ * H7-B.5 — mint an id_token bound to a server-minted enrollment grant +
123
+ * a scoped delegation hash. The two fields land on the wire as
124
+ * `enrollment_grant_id` + `delegation_hash` claims. Closes the package-side
125
+ * gap that let app-level SEC-001/SEC-002 ship.
126
+ */
127
+ export declare function mintBoundIdToken(input: BoundMintIdTokenInput, signer: BrokerSigner): Promise<string>;
128
+ /**
129
+ * H7-B.5 — relying-app helper. After a successful {@link verifyIdToken},
130
+ * pass the verified token + the expected binding (the grant id the app
131
+ * just consumed + the keccak256 of the scoped delegation it received).
132
+ *
133
+ * Returns `{ ok: true }` only when both bindings match. Off-chain replay
134
+ * of a token issued for a different grant or against a different delegation
135
+ * (the SEC-001 / SEC-002 vectors) fails with a precise reason.
136
+ */
137
+ export declare function verifyEnrollmentGrantBinding(token: string, expected: {
138
+ enrollmentGrantId: string;
139
+ delegationHash: `0x${string}`;
140
+ }): {
141
+ ok: true;
142
+ } | {
143
+ ok: false;
144
+ reason: 'malformed' | 'missing-grant-id' | 'grant-id-mismatch' | 'missing-delegation-hash' | 'delegation-hash-mismatch';
145
+ };
146
+ export type VerifyIdTokenResult = {
147
+ ok: true;
148
+ claims: OidcIdToken;
149
+ } | {
150
+ ok: false;
151
+ reason: string;
152
+ };
153
+ export interface VerifyIdTokenOpts {
154
+ keys: VerifyKey[];
155
+ expectedIss: string;
156
+ expectedAud: string;
157
+ expectedNonce?: string;
158
+ now?: () => number;
159
+ }
160
+ /** Verify an OIDC id_token. Alg PINNED to the key by `kid` (rejects alg:none/confusion);
161
+ * `iss`/`aud` exact-match; `nonce` checked when expected; `exp` enforced. */
162
+ export declare function verifyIdToken(token: string, opts: VerifyIdTokenOpts): Promise<VerifyIdTokenResult>;
163
+ /** PKCE S256 verification (RFC 7636): `base64url(SHA-256(verifier)) === challenge`.
164
+ * Used at the token endpoint to bind a code to the client's `code_verifier`. */
165
+ export declare function verifyPkceS256(codeVerifier: string, codeChallenge: string): Promise<boolean>;
166
+ type PublicJwk = JsonWebKey & {
167
+ kid: string;
168
+ alg: string;
169
+ use: string;
170
+ };
171
+ /** Export a signer's public key as a JWKS entry. */
172
+ export declare function exportPublicJwk(k: {
173
+ kid: string;
174
+ alg: BrokerAlg;
175
+ publicKey: CryptoKey;
176
+ }): Promise<PublicJwk>;
177
+ /** Publish a JWKS document for relying sites to fetch + verify against. */
178
+ export declare function publishJwks(keys: Array<{
179
+ kid: string;
180
+ alg: BrokerAlg;
181
+ publicKey: CryptoKey;
182
+ }>): Promise<{
183
+ keys: PublicJwk[];
184
+ }>;
185
+ /** Import a JWKS document into verification keys (relying-site side). */
186
+ export declare function importJwks(jwks: {
187
+ keys: Array<JsonWebKey & {
188
+ kid?: string;
189
+ alg?: string;
190
+ }>;
191
+ }): Promise<VerifyKey[]>;
192
+ export {};
193
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
package/dist/token.js ADDED
@@ -0,0 +1,260 @@
1
+ // AgentSession token layer — asymmetric, JWKS-verifiable (spec 224 §4; CN-4).
2
+ //
3
+ // The cross-origin AgentSession is signed with the broker's PRIVATE key and
4
+ // verified by relying sites with the PUBLIC key (via JWKS). EdDSA (Ed25519) is
5
+ // the default; ES256 (ECDSA P-256) is a capability fallback. Both are Web Crypto
6
+ // (no JWT library). The HS256 same-origin BrokerSession is a different token
7
+ // (connect-auth's mintSession) — never verified here.
8
+ //
9
+ // SECURITY (CN-4): the verifier PINS the algorithm to the KEY (resolved by kid),
10
+ // never to the token's own `alg` header — so alg-confusion (RS/ES↔HS) and
11
+ // `alg: none` are rejected. ADR-0016: an AgentSession has NO `owner` field; a
12
+ // token carrying one is rejected (defense in depth).
13
+ import { base64urlEncode, base64urlDecode } from '@agenticprimitives/connect-auth';
14
+ function genParams(alg) {
15
+ return alg === 'EdDSA' ? { name: 'Ed25519' } : { name: 'ECDSA', namedCurve: 'P-256' };
16
+ }
17
+ function importParams(alg) {
18
+ return alg === 'EdDSA' ? { name: 'Ed25519' } : { name: 'ECDSA', namedCurve: 'P-256' };
19
+ }
20
+ function sigParams(alg) {
21
+ return alg === 'EdDSA' ? { name: 'Ed25519' } : { name: 'ECDSA', hash: 'SHA-256' };
22
+ }
23
+ function randomB64url(byteLen) {
24
+ const b = new Uint8Array(byteLen);
25
+ globalThis.crypto.getRandomValues(b);
26
+ return base64urlEncode(b);
27
+ }
28
+ /** Copy into a fresh ArrayBuffer-backed view (Web Crypto BufferSource typing). */
29
+ function freshBytes(u) {
30
+ const out = new Uint8Array(u.byteLength);
31
+ out.set(u);
32
+ return out;
33
+ }
34
+ /** Generate a broker signing keypair. EdDSA (Ed25519) by default; ES256 fallback. */
35
+ export async function generateBrokerKeypair(alg = 'EdDSA') {
36
+ const kp = (await globalThis.crypto.subtle.generateKey(genParams(alg), true, [
37
+ 'sign',
38
+ 'verify',
39
+ ]));
40
+ return { kid: randomB64url(8), alg, privateKey: kp.privateKey, publicKey: kp.publicKey };
41
+ }
42
+ /** Mint a signed AgentSession (asymmetric). */
43
+ export async function mintAgentSession(input, signer) {
44
+ const nowSec = Math.floor((input.now?.() ?? Date.now()) / 1000);
45
+ const payload = {
46
+ sub: input.sub,
47
+ principal: input.principal,
48
+ assurance: input.assurance,
49
+ aud: input.aud,
50
+ iss: input.iss,
51
+ iat: nowSec,
52
+ exp: nowSec + input.ttlSeconds,
53
+ jti: input.jti ?? randomB64url(12),
54
+ ...(input.rotation ? { rotation: input.rotation } : {}),
55
+ };
56
+ const header = { alg: signer.alg, kid: signer.kid, typ: 'JWT' };
57
+ const enc = new TextEncoder();
58
+ const signingInput = `${base64urlEncode(enc.encode(JSON.stringify(header)))}.${base64urlEncode(enc.encode(JSON.stringify(payload)))}`;
59
+ const sig = await globalThis.crypto.subtle.sign(sigParams(signer.alg), signer.privateKey, new TextEncoder().encode(signingInput));
60
+ return `${signingInput}.${base64urlEncode(new Uint8Array(sig))}`;
61
+ }
62
+ /** Verify an AgentSession. Alg is PINNED to the key (by kid), never the token's header. */
63
+ export async function verifyAgentSession(token, opts) {
64
+ const parts = token.split('.');
65
+ if (parts.length !== 3)
66
+ return { ok: false, reason: 'not a 3-part JWT' };
67
+ const [h, p, s] = parts;
68
+ let header;
69
+ let payload;
70
+ try {
71
+ header = JSON.parse(new TextDecoder().decode(base64urlDecode(h)));
72
+ payload = JSON.parse(new TextDecoder().decode(base64urlDecode(p)));
73
+ }
74
+ catch {
75
+ return { ok: false, reason: 'header/payload not valid JSON' };
76
+ }
77
+ const key = opts.keys.find((k) => k.kid === header.kid);
78
+ if (!key)
79
+ return { ok: false, reason: `no key for kid "${header.kid}"` };
80
+ // Pin alg to the key — rejects alg-confusion + alg:none.
81
+ if (header.alg !== key.alg)
82
+ return { ok: false, reason: `alg "${header.alg}" does not match key alg "${key.alg}"` };
83
+ // iss-first (so an HS BrokerSession token can never enter this verifier).
84
+ if (opts.expectedIss && payload.iss !== opts.expectedIss)
85
+ return { ok: false, reason: 'iss mismatch' };
86
+ const valid = await globalThis.crypto.subtle.verify(sigParams(key.alg), key.publicKey, freshBytes(base64urlDecode(s)), new TextEncoder().encode(`${h}.${p}`));
87
+ if (!valid)
88
+ return { ok: false, reason: 'signature invalid' };
89
+ // H7-B.4: expectedAud is required (PKG-CONNECT-001-sec closure). The legacy
90
+ // optional form let callers verify any AgentSession against any audience.
91
+ if (typeof opts.expectedAud !== 'string' || opts.expectedAud.length === 0) {
92
+ return { ok: false, reason: 'expectedAud is required (H7-B.4)' };
93
+ }
94
+ if (payload.aud !== opts.expectedAud)
95
+ return { ok: false, reason: 'aud mismatch' };
96
+ const nowSec = Math.floor((opts.now?.() ?? Date.now()) / 1000);
97
+ if (typeof payload.exp !== 'number' || payload.exp <= nowSec)
98
+ return { ok: false, reason: 'expired' };
99
+ // H7-B.4: reject future-dated `iat` beyond clock-skew tolerance (PKG-CONNECT-002).
100
+ const clockSkewSec = opts.clockSkewSec ?? 30;
101
+ if (typeof payload.iat === 'number') {
102
+ const iat = payload.iat;
103
+ if (iat > nowSec + clockSkewSec)
104
+ return { ok: false, reason: 'iat in future beyond clock skew' };
105
+ }
106
+ if (payload.owner !== undefined)
107
+ return { ok: false, reason: 'AgentSession must not carry an owner field (ADR-0016)' };
108
+ return { ok: true, session: payload };
109
+ }
110
+ /**
111
+ * @internal — mints an OIDC id_token signed with the broker key. Used by
112
+ * the broker's own re-auth path where no enrollment grant exists.
113
+ *
114
+ * Cross-origin enrollment **MUST** use {@link mintBoundIdToken} which
115
+ * additionally encodes `enrollment_grant_id` + `delegation_hash` so the
116
+ * relying app can verify the bind via {@link verifyEnrollmentGrantBinding}.
117
+ *
118
+ * `canonical_agent_id` mirrors `sub`.
119
+ */
120
+ export async function mintIdToken(input, signer) {
121
+ const nowSec = Math.floor((input.now?.() ?? Date.now()) / 1000);
122
+ const payload = {
123
+ iss: input.iss,
124
+ sub: input.sub,
125
+ aud: input.aud,
126
+ iat: nowSec,
127
+ exp: nowSec + input.ttlSeconds,
128
+ canonical_agent_id: input.sub,
129
+ ...(input.nonce ? { nonce: input.nonce } : {}),
130
+ ...(input.agentName ? { agent_name: input.agentName } : {}),
131
+ };
132
+ const header = { alg: signer.alg, kid: signer.kid, typ: 'JWT' };
133
+ const enc = new TextEncoder();
134
+ const signingInput = `${base64urlEncode(enc.encode(JSON.stringify(header)))}.${base64urlEncode(enc.encode(JSON.stringify(payload)))}`;
135
+ const sig = await globalThis.crypto.subtle.sign(sigParams(signer.alg), signer.privateKey, enc.encode(signingInput));
136
+ return `${signingInput}.${base64urlEncode(new Uint8Array(sig))}`;
137
+ }
138
+ /**
139
+ * H7-B.5 — mint an id_token bound to a server-minted enrollment grant +
140
+ * a scoped delegation hash. The two fields land on the wire as
141
+ * `enrollment_grant_id` + `delegation_hash` claims. Closes the package-side
142
+ * gap that let app-level SEC-001/SEC-002 ship.
143
+ */
144
+ export async function mintBoundIdToken(input, signer) {
145
+ const nowSec = Math.floor((input.now?.() ?? Date.now()) / 1000);
146
+ const payload = {
147
+ iss: input.iss,
148
+ sub: input.sub,
149
+ aud: input.aud,
150
+ iat: nowSec,
151
+ exp: nowSec + input.ttlSeconds,
152
+ canonical_agent_id: input.sub,
153
+ enrollment_grant_id: input.enrollmentGrantId,
154
+ delegation_hash: input.delegationHash,
155
+ ...(input.nonce ? { nonce: input.nonce } : {}),
156
+ ...(input.agentName ? { agent_name: input.agentName } : {}),
157
+ };
158
+ const header = { alg: signer.alg, kid: signer.kid, typ: 'JWT' };
159
+ const enc = new TextEncoder();
160
+ const signingInput = `${base64urlEncode(enc.encode(JSON.stringify(header)))}.${base64urlEncode(enc.encode(JSON.stringify(payload)))}`;
161
+ const sig = await globalThis.crypto.subtle.sign(sigParams(signer.alg), signer.privateKey, enc.encode(signingInput));
162
+ return `${signingInput}.${base64urlEncode(new Uint8Array(sig))}`;
163
+ }
164
+ /**
165
+ * H7-B.5 — relying-app helper. After a successful {@link verifyIdToken},
166
+ * pass the verified token + the expected binding (the grant id the app
167
+ * just consumed + the keccak256 of the scoped delegation it received).
168
+ *
169
+ * Returns `{ ok: true }` only when both bindings match. Off-chain replay
170
+ * of a token issued for a different grant or against a different delegation
171
+ * (the SEC-001 / SEC-002 vectors) fails with a precise reason.
172
+ */
173
+ export function verifyEnrollmentGrantBinding(token, expected) {
174
+ const parts = token.split('.');
175
+ if (parts.length !== 3)
176
+ return { ok: false, reason: 'malformed' };
177
+ let payload;
178
+ try {
179
+ payload = JSON.parse(new TextDecoder().decode(base64urlDecode(parts[1])));
180
+ }
181
+ catch {
182
+ return { ok: false, reason: 'malformed' };
183
+ }
184
+ if (typeof payload.enrollment_grant_id !== 'string') {
185
+ return { ok: false, reason: 'missing-grant-id' };
186
+ }
187
+ if (payload.enrollment_grant_id !== expected.enrollmentGrantId) {
188
+ return { ok: false, reason: 'grant-id-mismatch' };
189
+ }
190
+ if (typeof payload.delegation_hash !== 'string') {
191
+ return { ok: false, reason: 'missing-delegation-hash' };
192
+ }
193
+ if (payload.delegation_hash.toLowerCase() !== expected.delegationHash.toLowerCase()) {
194
+ return { ok: false, reason: 'delegation-hash-mismatch' };
195
+ }
196
+ return { ok: true };
197
+ }
198
+ /** Verify an OIDC id_token. Alg PINNED to the key by `kid` (rejects alg:none/confusion);
199
+ * `iss`/`aud` exact-match; `nonce` checked when expected; `exp` enforced. */
200
+ export async function verifyIdToken(token, opts) {
201
+ const parts = token.split('.');
202
+ if (parts.length !== 3)
203
+ return { ok: false, reason: 'not a 3-part JWT' };
204
+ const [h, p, s] = parts;
205
+ let header;
206
+ let claims;
207
+ try {
208
+ header = JSON.parse(new TextDecoder().decode(base64urlDecode(h)));
209
+ claims = JSON.parse(new TextDecoder().decode(base64urlDecode(p)));
210
+ }
211
+ catch {
212
+ return { ok: false, reason: 'header/payload not valid JSON' };
213
+ }
214
+ const key = opts.keys.find((k) => k.kid === header.kid);
215
+ if (!key)
216
+ return { ok: false, reason: `no key for kid "${header.kid}"` };
217
+ if (header.alg !== key.alg)
218
+ return { ok: false, reason: `alg "${header.alg}" does not match key alg "${key.alg}"` };
219
+ if (claims.iss !== opts.expectedIss)
220
+ return { ok: false, reason: 'iss mismatch' };
221
+ const valid = await globalThis.crypto.subtle.verify(sigParams(key.alg), key.publicKey, freshBytes(base64urlDecode(s)), new TextEncoder().encode(`${h}.${p}`));
222
+ if (!valid)
223
+ return { ok: false, reason: 'signature invalid' };
224
+ if (claims.aud !== opts.expectedAud)
225
+ return { ok: false, reason: 'aud mismatch' };
226
+ if (opts.expectedNonce !== undefined && claims.nonce !== opts.expectedNonce)
227
+ return { ok: false, reason: 'nonce mismatch' };
228
+ const nowSec = Math.floor((opts.now?.() ?? Date.now()) / 1000);
229
+ if (typeof claims.exp !== 'number' || claims.exp <= nowSec)
230
+ return { ok: false, reason: 'expired' };
231
+ return { ok: true, claims };
232
+ }
233
+ /** PKCE S256 verification (RFC 7636): `base64url(SHA-256(verifier)) === challenge`.
234
+ * Used at the token endpoint to bind a code to the client's `code_verifier`. */
235
+ export async function verifyPkceS256(codeVerifier, codeChallenge) {
236
+ const digest = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier));
237
+ return base64urlEncode(new Uint8Array(digest)) === codeChallenge;
238
+ }
239
+ /** Export a signer's public key as a JWKS entry. */
240
+ export async function exportPublicJwk(k) {
241
+ const jwk = await globalThis.crypto.subtle.exportKey('jwk', k.publicKey);
242
+ return { ...jwk, kid: k.kid, alg: k.alg, use: 'sig' };
243
+ }
244
+ /** Publish a JWKS document for relying sites to fetch + verify against. */
245
+ export async function publishJwks(keys) {
246
+ return { keys: await Promise.all(keys.map(exportPublicJwk)) };
247
+ }
248
+ /** Import a JWKS document into verification keys (relying-site side). */
249
+ export async function importJwks(jwks) {
250
+ const out = [];
251
+ for (const jwk of jwks.keys) {
252
+ const alg = jwk.alg;
253
+ if (alg !== 'EdDSA' && alg !== 'ES256')
254
+ continue; // only the broker's algs
255
+ const publicKey = await globalThis.crypto.subtle.importKey('jwk', jwk, importParams(alg), false, ['verify']);
256
+ out.push({ kid: jwk.kid ?? '', alg, publicKey });
257
+ }
258
+ return out;
259
+ }
260
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@agenticprimitives/connect",
3
+ "version": "0.1.0-alpha.2",
4
+ "description": "Agentic Connect \u2014 the SSO broker (spec 224 / ADR-0014). Mints CAIP-10-subject, no-owner AgentSessions (asymmetric + JWKS); drives entry-flow convergence (connect-auth verify \u2192 identity-directory resolve \u2192 issue/bootstrap/disambiguate) with assurance floor, non-EVM gate, and code-exchange redirect security.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
9
+ "directory": "packages/connect"
10
+ },
11
+ "homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/connect",
12
+ "bugs": {
13
+ "url": "https://github.com/agentictrustlabs/agenticprimitives/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "LICENSE",
26
+ "dist",
27
+ "spec.md",
28
+ "README.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.build.json",
32
+ "typecheck": "tsc -p tsconfig.json --noEmit",
33
+ "test": "vitest run",
34
+ "test:unit": "vitest run test/unit",
35
+ "test:integration": "vitest run test/integration --passWithNoTests",
36
+ "test:watch": "vitest",
37
+ "clean": "rm -rf dist"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "peerDependencies": {
43
+ "@agenticprimitives/connect-auth": "workspace:*",
44
+ "@agenticprimitives/identity-directory": "workspace:*",
45
+ "@agenticprimitives/types": "workspace:*"
46
+ },
47
+ "devDependencies": {
48
+ "vitest": "^2.1.0"
49
+ },
50
+ "keywords": [
51
+ "sso",
52
+ "broker",
53
+ "agentsession",
54
+ "jwks",
55
+ "agentic"
56
+ ]
57
+ }
package/spec.md ADDED
@@ -0,0 +1,13 @@
1
+ # Spec — @agenticprimitives/connect
2
+
3
+ The authoritative spec is [`specs/224-agentic-connect.md`](../../specs/224-agentic-connect.md)
4
+ (broker model, AgentSession shape, token design §4, redirect/response §4a, entry
5
+ flows + convergence §5, OIDC §6, WebAuthn §7, step-up §8, anti-patterns §9).
6
+
7
+ Decision record: [ADR-0014 — Connect is an SSO broker at a central origin](../../docs/architecture/decisions/0014-connect-is-an-sso-broker.md).
8
+ Subject + no-owner: [ADR-0016](../../docs/architecture/decisions/0016-canonical-agent-id-is-the-sso-subject.md).
9
+ OIDC/social = login facet: [ADR-0017](../../docs/architecture/decisions/0017-oidc-social-is-a-login-facet-not-custody.md).
10
+ Security controls CN-1…CN-12: [`docs/audits/sso-wave-audit-findings.md`](../../docs/audits/sso-wave-audit-findings.md).
11
+
12
+ This file is the per-package pointer required by `check:package-docs`; do not
13
+ duplicate the spec here — edit spec 224.