@agentic-passport/next 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/stores.js ADDED
@@ -0,0 +1,175 @@
1
+ /**
2
+ * State store implementations.
3
+ * - inMemoryStore() — default; per-instance Map-backed; fine for tests + single-isolate dev
4
+ * - kvStore(kv) — Cloudflare Workers KV-backed; works across isolates
5
+ */
6
+ import { publicKeyFromJwk } from '@agentic-passport/core';
7
+ // ---------- in-memory ----------
8
+ export function inMemoryStore() {
9
+ const keys = new Map();
10
+ const revoked = new Set();
11
+ const nonces = new Map(); // key|nonce -> expiresAt
12
+ const mandateJtis = new Map();
13
+ const dpopJtis = new Map();
14
+ const agents = new Map();
15
+ const rateLimitTimestamps = new Map();
16
+ const NONCE_TTL_MS = 300_000;
17
+ const sweep = (m) => {
18
+ const now = Date.now();
19
+ for (const [k, v] of m)
20
+ if (v <= now)
21
+ m.delete(k);
22
+ };
23
+ return {
24
+ async registerKey(keyId, jwk) {
25
+ keys.set(keyId, publicKeyFromJwk(jwk));
26
+ },
27
+ async resolveKey(keyId) {
28
+ return keys.get(keyId) ?? null;
29
+ },
30
+ async isKeyRevoked(keyId) {
31
+ return revoked.has(keyId);
32
+ },
33
+ async revokeKey(keyId) {
34
+ revoked.add(keyId);
35
+ },
36
+ async putAgent(agentId, value) {
37
+ agents.set(agentId, value);
38
+ },
39
+ async getAgent(agentId) {
40
+ return agents.get(agentId) ?? null;
41
+ },
42
+ async isNonceSeen(keyId, nonce) {
43
+ sweep(nonces);
44
+ return nonces.has(`${keyId}\x00${nonce}`);
45
+ },
46
+ async rememberNonce(keyId, nonce) {
47
+ nonces.set(`${keyId}\x00${nonce}`, Date.now() + NONCE_TTL_MS);
48
+ },
49
+ async isMandateJtiUsed(jti) {
50
+ sweep(mandateJtis);
51
+ return mandateJtis.has(jti);
52
+ },
53
+ async rememberMandateJti(jti, expSec) {
54
+ mandateJtis.set(jti, expSec * 1000);
55
+ },
56
+ async isDpopJtiSeen(jti) {
57
+ sweep(dpopJtis);
58
+ return dpopJtis.has(jti);
59
+ },
60
+ async rememberDpopJti(jti, expSec) {
61
+ dpopJtis.set(jti, expSec * 1000);
62
+ },
63
+ async recordRegisterAttempt(keyId) {
64
+ const cutoff = Date.now() - 60_000;
65
+ const arr = (rateLimitTimestamps.get(keyId) ?? []).filter((t) => t > cutoff);
66
+ arr.push(Date.now());
67
+ rateLimitTimestamps.set(keyId, arr);
68
+ return arr.length;
69
+ },
70
+ };
71
+ }
72
+ const KEY_PREFIX = 'k:'; // agent public JWK by keyId
73
+ const REVOKED_PREFIX = 'r:'; // revocation list
74
+ const AGENT_PREFIX = 'a:'; // agent record by agent_id
75
+ const NONCE_PREFIX = 'n:'; // seen nonces
76
+ const MJTI_PREFIX = 'm:'; // consumed mandate jtis
77
+ const DJTI_PREFIX = 'd:'; // seen dpop jtis
78
+ const RL_PREFIX = 'rl:'; // rate-limit counters
79
+ const NONCE_TTL_SEC = 300;
80
+ /**
81
+ * KV-backed state store. Use on Cloudflare Workers / Pages.
82
+ *
83
+ * Two namespaces are recommended:
84
+ * - state: persistent (keys, agents, revocation)
85
+ * - cache: ephemeral (nonces, jtis, rate-limit) — falls back to `state` if omitted
86
+ *
87
+ * Limits to be aware of:
88
+ * - KV writes are eventually consistent (≤60s globally). v0 demo: same-region requests
89
+ * usually see fresh writes within ~1s. For multi-region production, consider Durable Objects.
90
+ * - Each operation = 1 KV op = real cost / rate limit.
91
+ */
92
+ export function kvStore(opts) {
93
+ const state = opts.state;
94
+ const cache = opts.cache ?? opts.state;
95
+ return {
96
+ async registerKey(keyId, jwk) {
97
+ await state.put(`${KEY_PREFIX}${keyId}`, JSON.stringify(jwk));
98
+ },
99
+ async resolveKey(keyId) {
100
+ const raw = await state.get(`${KEY_PREFIX}${keyId}`);
101
+ if (!raw)
102
+ return null;
103
+ try {
104
+ return publicKeyFromJwk(JSON.parse(raw));
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ },
110
+ async isKeyRevoked(keyId) {
111
+ const raw = await state.get(`${REVOKED_PREFIX}${keyId}`);
112
+ return raw === '1';
113
+ },
114
+ async revokeKey(keyId) {
115
+ await state.put(`${REVOKED_PREFIX}${keyId}`, '1');
116
+ },
117
+ async putAgent(agentId, value) {
118
+ await state.put(`${AGENT_PREFIX}${agentId}`, JSON.stringify(value));
119
+ },
120
+ async getAgent(agentId) {
121
+ const raw = await state.get(`${AGENT_PREFIX}${agentId}`);
122
+ if (!raw)
123
+ return null;
124
+ try {
125
+ return JSON.parse(raw);
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ },
131
+ async isNonceSeen(keyId, nonce) {
132
+ const v = await cache.get(`${NONCE_PREFIX}${keyId}:${nonce}`);
133
+ return v !== null;
134
+ },
135
+ async rememberNonce(keyId, nonce) {
136
+ await cache.put(`${NONCE_PREFIX}${keyId}:${nonce}`, '1', { expirationTtl: NONCE_TTL_SEC });
137
+ },
138
+ async isMandateJtiUsed(jti) {
139
+ const v = await cache.get(`${MJTI_PREFIX}${jti}`);
140
+ return v !== null;
141
+ },
142
+ async rememberMandateJti(jti, expSec) {
143
+ const ttl = Math.max(60, expSec - Math.floor(Date.now() / 1000));
144
+ await cache.put(`${MJTI_PREFIX}${jti}`, '1', { expirationTtl: ttl });
145
+ },
146
+ async isDpopJtiSeen(jti) {
147
+ const v = await cache.get(`${DJTI_PREFIX}${jti}`);
148
+ return v !== null;
149
+ },
150
+ async rememberDpopJti(jti, expSec) {
151
+ const ttl = Math.max(60, expSec - Math.floor(Date.now() / 1000));
152
+ await cache.put(`${DJTI_PREFIX}${jti}`, '1', { expirationTtl: ttl });
153
+ },
154
+ async recordRegisterAttempt(keyId) {
155
+ // KV doesn't support atomic increments. Read-modify-write here is best-effort:
156
+ // multiple concurrent calls may under-count. For v0 + per-key rate limits that's
157
+ // acceptable; for production, use Durable Objects or Workers Rate Limiting API.
158
+ const raw = (await cache.get(`${RL_PREFIX}${keyId}`)) ?? '[]';
159
+ let arr;
160
+ try {
161
+ arr = JSON.parse(raw);
162
+ }
163
+ catch {
164
+ arr = [];
165
+ }
166
+ const cutoff = Date.now() - 60_000;
167
+ const filtered = arr.filter((t) => t > cutoff);
168
+ filtered.push(Date.now());
169
+ await cache.put(`${RL_PREFIX}${keyId}`, JSON.stringify(filtered), { expirationTtl: 120 });
170
+ return filtered.length;
171
+ },
172
+ };
173
+ void null;
174
+ }
175
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../src/stores.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ import type { JSONWebKeySet, JWK } from 'jose';
2
+ import type { KeyObject } from 'node:crypto';
3
+ import type { ErrorCode, MandateClaims } from '@agentic-passport/protocol';
4
+ export type AgentSignupContext = {
5
+ agentId: string;
6
+ mandate: MandateClaims;
7
+ request: {
8
+ method: string;
9
+ url: string;
10
+ headers: Readonly<Record<string, string | undefined>>;
11
+ };
12
+ };
13
+ export type AgentSignupResult = {
14
+ allow: boolean;
15
+ principal?: {
16
+ userId: string;
17
+ grantedScopes: string[];
18
+ };
19
+ reason?: string;
20
+ };
21
+ /**
22
+ * Context passed to onAgentSessionMint. Includes the verified agent record
23
+ * (after AgentPassport signature + mandate checks have passed) and the user
24
+ * the vendor mapped them to in onAgentSignup. The vendor uses `userId` to
25
+ * mint a session in their own auth system.
26
+ */
27
+ export type AgentSessionMintContext = {
28
+ agentId: string;
29
+ userId: string;
30
+ scopes: readonly string[];
31
+ mandateJti: string;
32
+ actor?: string;
33
+ };
34
+ /**
35
+ * Browser-handoff result. The agent's browser navigates to `bootstrap_url`;
36
+ * the vendor's auth provider mints its session cookie in that browser
37
+ * context. From that point on, the browser is signed in to the vendor
38
+ * exactly as a human would be after going through the equivalent flow.
39
+ *
40
+ * `bootstrap_url` should be one-time-use and short-lived (≤5 min). Vendor
41
+ * is responsible for revoking unused tokens.
42
+ *
43
+ * Optional `final_url` lets the vendor tell the agent where to land
44
+ * after the bootstrap completes — defaults to the vendor origin.
45
+ */
46
+ export type AgentSessionMintResult = {
47
+ bootstrap_url: string;
48
+ final_url?: string;
49
+ };
50
+ export type PaymentChallenge = {
51
+ rail: 'free';
52
+ };
53
+ /**
54
+ * Storage backend for cross-request gate state.
55
+ *
56
+ * v0 default: inMemoryStore() — fine for single-instance dev / tests.
57
+ * Production / serverless: provide a KV-backed implementation. Each isolate
58
+ * sees the same state via the store, eliminating module-scope state issues.
59
+ */
60
+ export interface AgentStateStore {
61
+ registerKey(keyId: string, jwk: JWK): Promise<void>;
62
+ resolveKey(keyId: string): Promise<KeyObject | null>;
63
+ isKeyRevoked(keyId: string): Promise<boolean>;
64
+ revokeKey(keyId: string): Promise<void>;
65
+ putAgent(agentId: string, value: AgentRecord): Promise<void>;
66
+ getAgent(agentId: string): Promise<AgentRecord | null>;
67
+ isNonceSeen(keyId: string, nonce: string): Promise<boolean>;
68
+ rememberNonce(keyId: string, nonce: string): Promise<void>;
69
+ isMandateJtiUsed(jti: string): Promise<boolean>;
70
+ rememberMandateJti(jti: string, exp: number): Promise<void>;
71
+ isDpopJtiSeen(jti: string): Promise<boolean>;
72
+ rememberDpopJti(jti: string, exp: number): Promise<void>;
73
+ recordRegisterAttempt(keyId: string): Promise<number>;
74
+ }
75
+ export type AgentRecord = {
76
+ granted_scopes: string[];
77
+ mandate_jti: string;
78
+ user_id: string;
79
+ actor?: string;
80
+ };
81
+ export type AgentPassportConfig = {
82
+ /** Vendor's origin (used as JWT aud, signature URL canonicalisation). */
83
+ vendorOrigin: string;
84
+ /** Issuer URLs whose mandate signatures we trust. SDK fetches their JWKS automatically. */
85
+ trustedIssuers: string[];
86
+ /** Scope vocabulary the vendor exposes (advertised in discovery doc). */
87
+ scopes: string[];
88
+ /** Optional human-readable vendor name (discovery doc). */
89
+ vendorName?: string;
90
+ /**
91
+ * Pre-loaded JWKS by issuer URL. Optional — if omitted, the SDK fetches
92
+ * each issuer's `/.well-known/jwks.json` on first use and caches it.
93
+ * Provide explicitly for air-gapped deployments or when you want to
94
+ * pin a JWKS snapshot.
95
+ */
96
+ jwksByIssuer?: Map<string, JSONWebKeySet>;
97
+ /** Hooks the vendor implements (the "agent UX" surface). */
98
+ hooks: {
99
+ onAgentSignup: (ctx: AgentSignupContext) => Promise<AgentSignupResult>;
100
+ /**
101
+ * Browser-handoff: produce a one-time URL that, when navigated to by
102
+ * a real browser context (Playwright, Puppeteer), causes the vendor's
103
+ * auth provider to mint its own session in that browser. After
104
+ * navigation, the browser has a legitimate provider session — same
105
+ * mechanism a human would acquire via their own sign-in flow.
106
+ *
107
+ * Why a URL and not a cookie value: auth providers (Clerk, Auth.js,
108
+ * WorkOS, Auth0) mint session cookies only as the result of a
109
+ * sign-in event in *their* frontend. They expose this surface via a
110
+ * one-time sign-in token + redirect URL — designed for password-
111
+ * reset, magic-link, and impersonation flows. We use exactly that
112
+ * primitive: the agent's browser visits the URL, the provider
113
+ * recognises the token, mints the session cookie, and lands the
114
+ * browser on the requested destination.
115
+ *
116
+ * This hook is ONLY meaningful for browser-based agents (run via
117
+ * @agentic-passport/agent-browser). HTTP-only agents ignore it and use the
118
+ * vendor's getSession()-aware API routes directly.
119
+ *
120
+ * For Clerk:
121
+ *
122
+ * onAgentSessionMint: async ({ userId }) => {
123
+ * const client = await clerkClient();
124
+ * const t = await client.signInTokens.createSignInToken({ userId, expiresInSeconds: 300 });
125
+ * return { bootstrap_url: t.url };
126
+ * }
127
+ */
128
+ onAgentSessionMint?: (ctx: AgentSessionMintContext) => Promise<AgentSessionMintResult>;
129
+ onPaymentRequired?: () => PaymentChallenge;
130
+ };
131
+ /**
132
+ * Optional pre-built state store. Defaults to inMemoryStore().
133
+ * Provide kvStore(env) when running on Cloudflare Workers.
134
+ */
135
+ store?: AgentStateStore;
136
+ /**
137
+ * Optional PKCS8 PEM (or base64-encoded PKCS8 PEM) for the gate's token
138
+ * signing key. If omitted, a fresh keypair is generated per agentPassport()
139
+ * call — which is fine for tests but BROKEN on multi-isolate deployments
140
+ * because each isolate would sign with a different key.
141
+ */
142
+ tokenSigningKeyPem?: string;
143
+ };
144
+ export type AgentPrincipal = {
145
+ type: 'agent';
146
+ agentId: string;
147
+ scopes: readonly string[];
148
+ mandateJti: string;
149
+ };
150
+ export type HumanPrincipal = {
151
+ type: 'human';
152
+ userId: string;
153
+ scopes?: readonly string[];
154
+ };
155
+ export type Session = AgentPrincipal | HumanPrincipal;
156
+ export type { ErrorCode };
157
+ /** @deprecated Use {@link AgentPassportConfig}. */
158
+ export type AgentGateConfig = AgentPassportConfig;
159
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@agentic-passport/next",
3
+ "version": "0.3.0",
4
+ "description": "AgentAuth adapter for Next.js — sidecar middleware + route handler factories.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./edge": {
15
+ "types": "./dist/is-agent-request.d.ts",
16
+ "import": "./dist/is-agent-request.js"
17
+ },
18
+ "./clerk": {
19
+ "types": "./dist/clerk.d.ts",
20
+ "import": "./dist/clerk.js"
21
+ }
22
+ },
23
+ "typesVersions": {
24
+ "*": {
25
+ "edge": [
26
+ "dist/is-agent-request.d.ts"
27
+ ],
28
+ "clerk": [
29
+ "dist/clerk.d.ts"
30
+ ]
31
+ }
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md"
36
+ ],
37
+ "peerDependencies": {
38
+ "next": ">=14.0.0"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "next": {
42
+ "optional": false
43
+ }
44
+ },
45
+ "dependencies": {
46
+ "jose": "^6.2.3",
47
+ "@agentic-passport/protocol": "0.3.0",
48
+ "@agentic-passport/core": "0.3.0"
49
+ },
50
+ "devDependencies": {
51
+ "next": "^16.2.6",
52
+ "react": "^19.2.0",
53
+ "typescript": "^5.7.3",
54
+ "vitest": "^4.1.6"
55
+ },
56
+ "scripts": {
57
+ "build": "tsc -p tsconfig.json",
58
+ "test": "vitest run",
59
+ "test:unit": "vitest run",
60
+ "typecheck": "tsc -p tsconfig.json --noEmit",
61
+ "clean": "rm -rf dist .turbo"
62
+ }
63
+ }