@zauso-ai/capstan-auth 0.2.0 → 0.3.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.
Files changed (51) hide show
  1. package/dist/dpop.d.ts +46 -0
  2. package/dist/dpop.d.ts.map +1 -0
  3. package/dist/dpop.js +259 -0
  4. package/dist/dpop.js.map +1 -0
  5. package/dist/execution.d.ts +10 -0
  6. package/dist/execution.d.ts.map +1 -0
  7. package/dist/execution.js +50 -0
  8. package/dist/execution.js.map +1 -0
  9. package/dist/harness-authorizer.d.ts +10 -0
  10. package/dist/harness-authorizer.d.ts.map +1 -0
  11. package/dist/harness-authorizer.js +90 -0
  12. package/dist/harness-authorizer.js.map +1 -0
  13. package/dist/index.d.ts +14 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +8 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/middleware.d.ts +6 -3
  18. package/dist/middleware.d.ts.map +1 -1
  19. package/dist/middleware.js +209 -30
  20. package/dist/middleware.js.map +1 -1
  21. package/dist/oauth.d.ts +47 -0
  22. package/dist/oauth.d.ts.map +1 -0
  23. package/dist/oauth.js +199 -0
  24. package/dist/oauth.js.map +1 -0
  25. package/dist/permissions.d.ts +12 -22
  26. package/dist/permissions.d.ts.map +1 -1
  27. package/dist/permissions.js +91 -33
  28. package/dist/permissions.js.map +1 -1
  29. package/dist/runtime-authorizer.d.ts +28 -0
  30. package/dist/runtime-authorizer.d.ts.map +1 -0
  31. package/dist/runtime-authorizer.js +136 -0
  32. package/dist/runtime-authorizer.js.map +1 -0
  33. package/dist/runtime-grants.d.ts +31 -0
  34. package/dist/runtime-grants.d.ts.map +1 -0
  35. package/dist/runtime-grants.js +96 -0
  36. package/dist/runtime-grants.js.map +1 -0
  37. package/dist/session.d.ts +3 -3
  38. package/dist/session.d.ts.map +1 -1
  39. package/dist/session.js +21 -3
  40. package/dist/session.js.map +1 -1
  41. package/dist/store.d.ts +27 -0
  42. package/dist/store.d.ts.map +1 -0
  43. package/dist/store.js +46 -0
  44. package/dist/store.js.map +1 -0
  45. package/dist/types.d.ts +109 -1
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/workload.d.ts +46 -0
  48. package/dist/workload.d.ts.map +1 -0
  49. package/dist/workload.js +227 -0
  50. package/dist/workload.js.map +1 -0
  51. package/package.json +3 -2
package/dist/dpop.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { KeyValueStore } from "./store.js";
2
+ /**
3
+ * Result of a successful DPoP proof validation.
4
+ */
5
+ export interface DpopValidationResult {
6
+ /** Base64url-encoded JWK thumbprint (RFC 7638) of the proof key. */
7
+ thumbprint: string;
8
+ }
9
+ /**
10
+ * Replace the default in-memory DPoP replay store with a custom implementation.
11
+ *
12
+ * Call this at application startup before any DPoP proofs are validated.
13
+ */
14
+ export declare function setDpopReplayStore(store: KeyValueStore<true>): void;
15
+ /**
16
+ * Validate a DPoP proof JWT per RFC 9449.
17
+ *
18
+ * The proof is a compact-serialized JWT whose header contains the public key
19
+ * (`jwk`) used to sign the proof. The function:
20
+ *
21
+ * 1. Parses the JOSE header and verifies `typ: "dpop+jwt"` and a supported `alg`.
22
+ * 2. Extracts the embedded `jwk` and imports it via Web Crypto.
23
+ * 3. Verifies the JWT signature using the imported key.
24
+ * 4. Validates required claims:
25
+ * - `htm` — must match the provided HTTP method.
26
+ * - `htu` — must match the provided HTTP URI (scheme + authority + path).
27
+ * - `iat` — must be within the acceptable time window.
28
+ * - `jti` — must be unique (checked against an in-memory replay cache).
29
+ * 5. If an `accessToken` is provided, verifies the `ath` (access token hash)
30
+ * claim matches the SHA-256 hash of the token.
31
+ *
32
+ * Returns the JWK thumbprint on success, or `null` if validation fails.
33
+ *
34
+ * @param proof - The DPoP proof from the `DPoP` request header.
35
+ * @param method - The HTTP method of the request (e.g. "POST").
36
+ * @param url - The full request URL.
37
+ * @param accessToken - Optional access token to verify `ath` binding.
38
+ */
39
+ export declare function validateDpopProof(proof: string, method: string, url: string, accessToken?: string): Promise<DpopValidationResult | null>;
40
+ /**
41
+ * Clear the DPoP JTI replay cache.
42
+ *
43
+ * Useful for tests so state does not leak between test cases.
44
+ */
45
+ export declare function clearDpopReplayCache(): Promise<void>;
46
+ //# sourceMappingURL=dpop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../src/dpop.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;CACpB;AAoBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAEnE;AAmGD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA4JtC;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1D"}
package/dist/dpop.js ADDED
@@ -0,0 +1,259 @@
1
+ import { createHash } from "node:crypto";
2
+ import { MemoryStore } from "./store.js";
3
+ /** Maximum age (in seconds) for a DPoP proof's `iat` claim. */
4
+ const MAX_PROOF_AGE_SECONDS = 300; // 5 minutes
5
+ /** Minimum age (in seconds) — reject proofs from the far future. */
6
+ const MAX_CLOCK_SKEW_SECONDS = 60;
7
+ /** TTL for JTI replay cache entries (proof age + clock skew). */
8
+ const JTI_TTL_MS = (MAX_PROOF_AGE_SECONDS + MAX_CLOCK_SKEW_SECONDS) * 1000;
9
+ /**
10
+ * Pluggable store for tracking recently seen `jti` values to prevent replay.
11
+ *
12
+ * Each entry stores `true` as a sentinel value with a TTL equal to the proof
13
+ * window. The `MemoryStore` default lazily expires entries on access; custom
14
+ * implementations (e.g. Redis) can use native TTL support.
15
+ */
16
+ let dpopReplayStore = new MemoryStore();
17
+ /**
18
+ * Replace the default in-memory DPoP replay store with a custom implementation.
19
+ *
20
+ * Call this at application startup before any DPoP proofs are validated.
21
+ */
22
+ export function setDpopReplayStore(store) {
23
+ dpopReplayStore = store;
24
+ }
25
+ // ---------------------------------------------------------------------------
26
+ // Base64url helpers
27
+ // ---------------------------------------------------------------------------
28
+ function base64urlDecode(str) {
29
+ // Convert base64url to standard base64.
30
+ let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
31
+ // Pad with '=' to make length a multiple of 4.
32
+ while (base64.length % 4 !== 0) {
33
+ base64 += "=";
34
+ }
35
+ return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
36
+ }
37
+ function base64urlEncode(buffer) {
38
+ const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
39
+ let binary = "";
40
+ for (const b of bytes) {
41
+ binary += String.fromCharCode(b);
42
+ }
43
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // JWK Thumbprint (RFC 7638)
47
+ // ---------------------------------------------------------------------------
48
+ /**
49
+ * Compute the JWK thumbprint per RFC 7638.
50
+ *
51
+ * For RSA keys the required members are: e, kty, n
52
+ * For EC keys: crv, kty, x, y
53
+ */
54
+ function computeJwkThumbprint(jwk) {
55
+ let canonicalMembers;
56
+ if (jwk.kty === "RSA") {
57
+ canonicalMembers = { e: jwk.e, kty: jwk.kty, n: jwk.n };
58
+ }
59
+ else if (jwk.kty === "EC") {
60
+ canonicalMembers = {
61
+ crv: jwk.crv,
62
+ kty: jwk.kty,
63
+ x: jwk.x,
64
+ y: jwk.y,
65
+ };
66
+ }
67
+ else {
68
+ throw new Error(`Unsupported key type: ${jwk.kty}`);
69
+ }
70
+ // Lexicographic ordering of keys (JSON Canonicalization is just sorted keys
71
+ // for the required members).
72
+ const sortedKeys = Object.keys(canonicalMembers).sort();
73
+ const json = "{" +
74
+ sortedKeys
75
+ .map((k) => `${JSON.stringify(k)}:${JSON.stringify(canonicalMembers[k])}`)
76
+ .join(",") +
77
+ "}";
78
+ const hash = createHash("sha256").update(json).digest();
79
+ return base64urlEncode(hash);
80
+ }
81
+ function mapAlgorithm(alg) {
82
+ switch (alg) {
83
+ case "RS256":
84
+ return { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
85
+ case "RS384":
86
+ return { name: "RSASSA-PKCS1-v1_5", hash: "SHA-384" };
87
+ case "RS512":
88
+ return { name: "RSASSA-PKCS1-v1_5", hash: "SHA-512" };
89
+ case "ES256":
90
+ return { name: "ECDSA", hash: "SHA-256", namedCurve: "P-256" };
91
+ case "ES384":
92
+ return { name: "ECDSA", hash: "SHA-384", namedCurve: "P-384" };
93
+ case "ES512":
94
+ return { name: "ECDSA", hash: "SHA-512", namedCurve: "P-521" };
95
+ default:
96
+ return null;
97
+ }
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Public API
101
+ // ---------------------------------------------------------------------------
102
+ /**
103
+ * Validate a DPoP proof JWT per RFC 9449.
104
+ *
105
+ * The proof is a compact-serialized JWT whose header contains the public key
106
+ * (`jwk`) used to sign the proof. The function:
107
+ *
108
+ * 1. Parses the JOSE header and verifies `typ: "dpop+jwt"` and a supported `alg`.
109
+ * 2. Extracts the embedded `jwk` and imports it via Web Crypto.
110
+ * 3. Verifies the JWT signature using the imported key.
111
+ * 4. Validates required claims:
112
+ * - `htm` — must match the provided HTTP method.
113
+ * - `htu` — must match the provided HTTP URI (scheme + authority + path).
114
+ * - `iat` — must be within the acceptable time window.
115
+ * - `jti` — must be unique (checked against an in-memory replay cache).
116
+ * 5. If an `accessToken` is provided, verifies the `ath` (access token hash)
117
+ * claim matches the SHA-256 hash of the token.
118
+ *
119
+ * Returns the JWK thumbprint on success, or `null` if validation fails.
120
+ *
121
+ * @param proof - The DPoP proof from the `DPoP` request header.
122
+ * @param method - The HTTP method of the request (e.g. "POST").
123
+ * @param url - The full request URL.
124
+ * @param accessToken - Optional access token to verify `ath` binding.
125
+ */
126
+ export async function validateDpopProof(proof, method, url, accessToken) {
127
+ // ── 1. Split compact serialization ──────────────────────────────
128
+ const parts = proof.split(".");
129
+ if (parts.length !== 3)
130
+ return null;
131
+ const [headerB64, payloadB64, signatureB64] = parts;
132
+ // ── 2. Parse header ─────────────────────────────────────────────
133
+ let header;
134
+ try {
135
+ header = JSON.parse(new TextDecoder().decode(base64urlDecode(headerB64)));
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ // Must be typ: dpop+jwt
141
+ if (header.typ !== "dpop+jwt")
142
+ return null;
143
+ // Must have a supported algorithm
144
+ if (!header.alg)
145
+ return null;
146
+ const algMapping = mapAlgorithm(header.alg);
147
+ if (!algMapping)
148
+ return null;
149
+ // Must have an embedded JWK
150
+ if (!header.jwk || typeof header.jwk !== "object")
151
+ return null;
152
+ // The JWK must not contain a private key
153
+ if ("d" in header.jwk)
154
+ return null;
155
+ // ── 3. Import the public key and verify signature ───────────────
156
+ let importAlg;
157
+ if (algMapping.name === "RSASSA-PKCS1-v1_5") {
158
+ importAlg = { name: algMapping.name, hash: algMapping.hash };
159
+ }
160
+ else {
161
+ importAlg = {
162
+ name: algMapping.name,
163
+ namedCurve: algMapping.namedCurve,
164
+ };
165
+ }
166
+ let publicKey;
167
+ try {
168
+ publicKey = await crypto.subtle.importKey("jwk", header.jwk, importAlg, false, ["verify"]);
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ // Verify the signature over header.payload
174
+ const signingInput = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
175
+ const signature = base64urlDecode(signatureB64);
176
+ let verifyAlg;
177
+ if (algMapping.name === "ECDSA") {
178
+ verifyAlg = { name: "ECDSA", hash: algMapping.hash };
179
+ }
180
+ else {
181
+ verifyAlg = { name: algMapping.name };
182
+ }
183
+ let valid;
184
+ try {
185
+ valid = await crypto.subtle.verify(verifyAlg, publicKey, signature.buffer, signingInput);
186
+ }
187
+ catch {
188
+ return null;
189
+ }
190
+ if (!valid)
191
+ return null;
192
+ // ── 4. Parse and validate payload claims ────────────────────────
193
+ let payload;
194
+ try {
195
+ payload = JSON.parse(new TextDecoder().decode(base64urlDecode(payloadB64)));
196
+ }
197
+ catch {
198
+ return null;
199
+ }
200
+ // htm — HTTP method must match
201
+ if (typeof payload.htm !== "string")
202
+ return null;
203
+ if (payload.htm.toUpperCase() !== method.toUpperCase())
204
+ return null;
205
+ // htu — HTTP URI must match (scheme + authority + path, no query/fragment)
206
+ if (typeof payload.htu !== "string")
207
+ return null;
208
+ try {
209
+ const proofUrl = new URL(payload.htu);
210
+ const requestUrl = new URL(url);
211
+ // Compare origin + pathname (ignoring query string and fragment).
212
+ if (proofUrl.origin !== requestUrl.origin ||
213
+ proofUrl.pathname !== requestUrl.pathname) {
214
+ return null;
215
+ }
216
+ }
217
+ catch {
218
+ return null;
219
+ }
220
+ // iat — issued at must be recent
221
+ if (typeof payload.iat !== "number")
222
+ return null;
223
+ const nowSeconds = Math.floor(Date.now() / 1000);
224
+ if (payload.iat > nowSeconds + MAX_CLOCK_SKEW_SECONDS)
225
+ return null;
226
+ if (nowSeconds - payload.iat > MAX_PROOF_AGE_SECONDS)
227
+ return null;
228
+ // jti — unique identifier, prevent replay
229
+ if (typeof payload.jti !== "string" || payload.jti.length === 0)
230
+ return null;
231
+ if (await dpopReplayStore.has(payload.jti))
232
+ return null;
233
+ // Record the jti with a TTL matching the proof window.
234
+ await dpopReplayStore.set(payload.jti, true, JTI_TTL_MS);
235
+ // ── 5. Access token hash binding (ath) ──────────────────────────
236
+ if (accessToken !== undefined) {
237
+ const expectedAth = base64urlEncode(createHash("sha256").update(accessToken).digest());
238
+ if (payload.ath !== expectedAth)
239
+ return null;
240
+ }
241
+ // ── 6. Compute JWK thumbprint ───────────────────────────────────
242
+ let thumbprint;
243
+ try {
244
+ thumbprint = computeJwkThumbprint(header.jwk);
245
+ }
246
+ catch {
247
+ return null;
248
+ }
249
+ return { thumbprint };
250
+ }
251
+ /**
252
+ * Clear the DPoP JTI replay cache.
253
+ *
254
+ * Useful for tests so state does not leak between test cases.
255
+ */
256
+ export async function clearDpopReplayCache() {
257
+ await dpopReplayStore.clear();
258
+ }
259
+ //# sourceMappingURL=dpop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpop.js","sourceRoot":"","sources":["../src/dpop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAczC,+DAA+D;AAC/D,MAAM,qBAAqB,GAAG,GAAG,CAAC,CAAC,YAAY;AAE/C,oEAAoE;AACpE,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,iEAAiE;AACjE,MAAM,UAAU,GAAG,CAAC,qBAAqB,GAAG,sBAAsB,CAAC,GAAG,IAAI,CAAC;AAE3E;;;;;;GAMG;AACH,IAAI,eAAe,GAAwB,IAAI,WAAW,EAAE,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,eAAe,GAAG,KAAK,CAAC;AAC1B,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAS,eAAe,CAAC,GAAW;IAClC,wCAAwC;IACxC,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACvD,+CAA+C;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,eAAe,CAAC,MAAgC;IACvD,MAAM,KAAK,GACT,MAAM,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACjE,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,GAAe;IAC3C,IAAI,gBAAoD,CAAC;IAEzD,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;QACtB,gBAAgB,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;SAAM,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5B,gBAAgB,GAAG;YACjB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,CAAC,EAAE,GAAG,CAAC,CAAC;YACR,CAAC,EAAE,GAAG,CAAC,CAAC;SACT,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,4EAA4E;IAC5E,6BAA6B;IAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,IAAI,GACR,GAAG;QACH,UAAU;aACP,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE,IAAI,CAAC,GAAG,CAAC;QACZ,GAAG,CAAC;IAEN,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IACxD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAYD,SAAS,YAAY,CAAC,GAAW;IAC/B,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACxD,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACxD,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACxD,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACjE,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACjE,KAAK,OAAO;YACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QACjE;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,MAAc,EACd,GAAW,EACX,WAAoB;IAEpB,mEAAmE;IACnE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,KAI7C,CAAC;IAEF,mEAAmE;IACnE,IAAI,MAIH,CAAC;IACF,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CACjB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CACrD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,GAAG,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAE3C,kCAAkC;IAClC,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,4BAA4B;IAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE/D,yCAAyC;IACzC,IAAI,GAAG,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEnC,mEAAmE;IACnE,IAAI,SAAoD,CAAC;IACzD,IAAI,UAAU,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QAC5C,SAAS,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAK,EAAE,CAAC;IAChE,CAAC;SAAM,CAAC;QACN,SAAS,GAAG;YACV,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,UAAU,EAAE,UAAU,CAAC,UAAW;SACnC,CAAC;IACJ,CAAC;IAED,IAAI,SAAoB,CAAC;IACzB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACvC,KAAK,EACL,MAAM,CAAC,GAAG,EACV,SAAS,EACT,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2CAA2C;IAC3C,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAC3C,GAAG,SAAS,IAAI,UAAU,EAAE,CAC7B,CAAC;IACF,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAEhD,IAAI,SAA4C,CAAC;IACjD,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,SAAS,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,IAAK,EAAE,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAChC,SAAS,EACT,SAAS,EACT,SAAS,CAAC,MAAqB,EAC/B,YAAY,CACb,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,mEAAmE;IACnE,IAAI,OAMH,CAAC;IACF,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAClB,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CACtD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE;QAAE,OAAO,IAAI,CAAC;IAEpE,2EAA2E;IAC3E,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,kEAAkE;QAClE,IACE,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM;YACrC,QAAQ,CAAC,QAAQ,KAAK,UAAU,CAAC,QAAQ,EACzC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iCAAiC;IACjC,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,GAAG,GAAG,UAAU,GAAG,sBAAsB;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,UAAU,GAAG,OAAO,CAAC,GAAG,GAAG,qBAAqB;QAAE,OAAO,IAAI,CAAC;IAElE,0CAA0C;IAC1C,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,MAAM,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAExD,uDAAuD;IACvD,MAAM,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAEzD,mEAAmE;IACnE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,eAAe,CACjC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,CAClD,CAAC;QACF,IAAI,OAAO,CAAC,GAAG,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;IAC/C,CAAC;IAED,mEAAmE;IACnE,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC;AAChC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ActorIdentity, DelegationLink, ExecutionIdentity, ExecutionKind } from "./types.js";
2
+ export declare function createExecutionIdentity(kind: ExecutionKind, source: string, options?: {
3
+ parentId?: string;
4
+ metadata?: Record<string, unknown>;
5
+ }): ExecutionIdentity;
6
+ export declare function createRequestExecution(request: Request, options?: {
7
+ parentId?: string;
8
+ }): ExecutionIdentity;
9
+ export declare function createDelegationLink(from: ActorIdentity | ExecutionIdentity, to: ActorIdentity | ExecutionIdentity, reason: string, metadata?: Record<string, unknown>): DelegationLink;
10
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAEd,iBAAiB,EACjB,aAAa,EACd,MAAM,YAAY,CAAC;AASpB,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,GACA,iBAAiB,CAQnB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,iBAAiB,CAoBnB;AASD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,GAAG,iBAAiB,EACvC,EAAE,EAAE,aAAa,GAAG,iBAAiB,EACrC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,cAAc,CAWhB"}
@@ -0,0 +1,50 @@
1
+ function buildExecutionId(kind, source) {
2
+ if (kind === "request") {
3
+ return source;
4
+ }
5
+ return `${kind}:${source}`;
6
+ }
7
+ export function createExecutionIdentity(kind, source, options) {
8
+ const execution = {
9
+ kind,
10
+ id: buildExecutionId(kind, source),
11
+ };
12
+ if (options?.parentId !== undefined)
13
+ execution.parentId = options.parentId;
14
+ if (options?.metadata !== undefined)
15
+ execution.metadata = options.metadata;
16
+ return execution;
17
+ }
18
+ export function createRequestExecution(request, options) {
19
+ const url = new URL(request.url);
20
+ const createOptions = {
21
+ metadata: {
22
+ method: request.method,
23
+ pathname: url.pathname,
24
+ origin: url.origin,
25
+ },
26
+ };
27
+ if (options?.parentId !== undefined) {
28
+ createOptions.parentId = options.parentId;
29
+ }
30
+ return createExecutionIdentity("request", `${request.method} ${url.pathname}`, createOptions);
31
+ }
32
+ function toTargetRef(target) {
33
+ return {
34
+ kind: target.kind,
35
+ id: target.id,
36
+ };
37
+ }
38
+ export function createDelegationLink(from, to, reason, metadata) {
39
+ const link = {
40
+ from: toTargetRef(from),
41
+ to: toTargetRef(to),
42
+ reason,
43
+ issuedAt: new Date().toISOString(),
44
+ };
45
+ if (metadata !== undefined) {
46
+ link.metadata = metadata;
47
+ }
48
+ return link;
49
+ }
50
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAQA,SAAS,gBAAgB,CAAC,IAAmB,EAAE,MAAc;IAC3D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,IAAmB,EACnB,MAAc,EACd,OAGC;IAED,MAAM,SAAS,GAAsB;QACnC,IAAI;QACJ,EAAE,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS;QAAE,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC3E,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS;QAAE,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC3E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAAgB,EAChB,OAEC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,aAAa,GAGf;QACF,QAAQ,EAAE;YACR,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB;KACF,CAAC;IACF,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC5C,CAAC;IACD,OAAO,uBAAuB,CAC5B,SAAS,EACT,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,EACnC,aAAa,CACd,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAyC;IAC5D,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,EAAE,EAAE,MAAM,CAAC,EAAE;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAuC,EACvC,EAAqC,EACrC,MAAc,EACd,QAAkC;IAElC,MAAM,IAAI,GAAmB;QAC3B,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC;QACvB,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC;QACnB,MAAM;QACN,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACnC,CAAC;IACF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { RuntimeGrantSupplier } from "./runtime-authorizer.js";
2
+ import { type RuntimeGrantAuthorizationResult, type RuntimeGrantAuthorizerRequest } from "./runtime-authorizer.js";
3
+ export interface HarnessGrantAuthorizationRequest {
4
+ action: string;
5
+ runId?: string;
6
+ detail?: Record<string, unknown>;
7
+ }
8
+ export declare function toRuntimeGrantRequest(request: HarnessGrantAuthorizationRequest): RuntimeGrantAuthorizerRequest;
9
+ export declare function createHarnessGrantAuthorizer(supplier: RuntimeGrantSupplier): (request: HarnessGrantAuthorizationRequest) => Promise<RuntimeGrantAuthorizationResult>;
10
+ //# sourceMappingURL=harness-authorizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-authorizer.d.ts","sourceRoot":"","sources":["../src/harness-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAEL,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EACnC,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAiGD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,gCAAgC,GACxC,6BAA6B,CAa/B;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,oBAAoB,IAIvE,SAAS,gCAAgC,KACxC,OAAO,CAAC,+BAA+B,CAAC,CAE5C"}
@@ -0,0 +1,90 @@
1
+ import { createRuntimeGrantAuthorizer, } from "./runtime-authorizer.js";
2
+ function readString(source, key) {
3
+ const value = source?.[key];
4
+ return typeof value === "string" && value.trim().length > 0 ? value : undefined;
5
+ }
6
+ function readRecord(source, key) {
7
+ const value = source?.[key];
8
+ return value != null && typeof value === "object" && !Array.isArray(value)
9
+ ? value
10
+ : undefined;
11
+ }
12
+ function deriveMemoryAttributes(detail) {
13
+ const kind = readString(detail, "kind");
14
+ if (kind === "session_memory") {
15
+ return { memoryKind: "session" };
16
+ }
17
+ if (kind === "persistent_memory") {
18
+ return { memoryKind: "persistent" };
19
+ }
20
+ const kinds = Array.isArray(detail?.["kinds"])
21
+ ? detail["kinds"].filter((entry) => typeof entry === "string")
22
+ : [];
23
+ if (kinds.length === 1 && kinds[0] === "session_memory") {
24
+ return { memoryKind: "session" };
25
+ }
26
+ if (kinds.length === 1 && kinds[0] === "persistent_memory") {
27
+ return { memoryKind: "persistent" };
28
+ }
29
+ return undefined;
30
+ }
31
+ function deriveApprovalAttributes(detail) {
32
+ const pendingApproval = readRecord(detail, "pendingApproval");
33
+ const directKind = readString(detail, "kind");
34
+ const nestedKind = readString(pendingApproval, "kind");
35
+ const approvalKind = directKind === "tool" || directKind === "task"
36
+ ? directKind
37
+ : nestedKind === "tool" || nestedKind === "task"
38
+ ? nestedKind
39
+ : undefined;
40
+ return approvalKind ? { approvalKind } : undefined;
41
+ }
42
+ function buildScope(request) {
43
+ if (request.action.endsWith(":list")) {
44
+ return request.runId ? { runId: request.runId } : undefined;
45
+ }
46
+ const detail = request.detail;
47
+ const pendingApproval = readRecord(detail, "pendingApproval");
48
+ const pendingToolCall = readRecord(detail, "pendingToolCall");
49
+ const scope = {};
50
+ if (request.runId) {
51
+ scope.runId = request.runId;
52
+ }
53
+ const scopedFields = [
54
+ ["approvalId", readString(detail, "approvalId") ?? readString(pendingApproval, "id")],
55
+ ["artifactId", readString(detail, "artifactId")],
56
+ ["memoryId", readString(detail, "memoryId")],
57
+ ["summaryId", readString(detail, "summaryId")],
58
+ ["taskId", readString(detail, "taskId")],
59
+ [
60
+ "tool",
61
+ readString(detail, "tool") ??
62
+ readString(pendingApproval, "tool") ??
63
+ readString(pendingToolCall, "tool"),
64
+ ],
65
+ ];
66
+ for (const [key, value] of scopedFields) {
67
+ if (value) {
68
+ scope[key] = value;
69
+ }
70
+ }
71
+ return Object.keys(scope).length > 0 ? scope : undefined;
72
+ }
73
+ export function toRuntimeGrantRequest(request) {
74
+ const detail = request.detail;
75
+ const attributes = {
76
+ ...(request.action.startsWith("memory:") ? deriveMemoryAttributes(detail) ?? {} : {}),
77
+ ...(request.action.startsWith("approval:") ? deriveApprovalAttributes(detail) ?? {} : {}),
78
+ };
79
+ const scope = buildScope(request);
80
+ return {
81
+ action: request.action,
82
+ ...(scope ? { scope } : {}),
83
+ ...(Object.keys(attributes).length > 0 ? { attributes } : {}),
84
+ };
85
+ }
86
+ export function createHarnessGrantAuthorizer(supplier) {
87
+ const runtimeAuthorizer = createRuntimeGrantAuthorizer(supplier);
88
+ return async (request) => runtimeAuthorizer(toRuntimeGrantRequest(request));
89
+ }
90
+ //# sourceMappingURL=harness-authorizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-authorizer.js","sourceRoot":"","sources":["../src/harness-authorizer.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  export { signSession, verifySession } from "./session.js";
2
2
  export { generateApiKey, verifyApiKey, extractApiKeyPrefix, } from "./api-key.js";
3
3
  export { createAuthMiddleware } from "./middleware.js";
4
- export { checkPermission, derivePermission } from "./permissions.js";
5
- export type { AuthConfig, SessionPayload, AgentCredential, AuthContext, AuthResolverDeps, } from "./types.js";
4
+ export { authorizeGrant, checkGrant, checkPermission, derivePermission, normalizePermissionsToGrants, serializeGrantsToPermissions, } from "./permissions.js";
5
+ export { createExecutionIdentity, createRequestExecution, createDelegationLink, } from "./execution.js";
6
+ export { createGrant, grantRunActions, grantRunCollectionActions, grantApprovalActions, grantApprovalCollectionActions, grantEventActions, grantEventCollectionActions, grantArtifactActions, grantCheckpointActions, grantTaskActions, grantSummaryActions, grantSummaryCollectionActions, grantMemoryActions, grantContextActions, grantRuntimePathsActions, } from "./runtime-grants.js";
7
+ export { deriveRuntimeGrantRequirements, authorizeRuntimeAction, createRuntimeGrantAuthorizer, } from "./runtime-authorizer.js";
8
+ export { createHarnessGrantAuthorizer, toRuntimeGrantRequest, } from "./harness-authorizer.js";
9
+ export { validateDpopProof, clearDpopReplayCache, setDpopReplayStore } from "./dpop.js";
10
+ export { extractWorkloadIdentity, isValidSpiffeId } from "./workload.js";
11
+ export { googleProvider, githubProvider, createOAuthHandlers, } from "./oauth.js";
12
+ export type { DpopValidationResult } from "./dpop.js";
13
+ export type { WorkloadIdentity } from "./workload.js";
14
+ export type { OAuthProvider, OAuthConfig, OAuthHandlers } from "./oauth.js";
15
+ export type { ActorIdentity, AuthConfig, SessionPayload, SessionSigningOptions, SessionVerificationOptions, AgentCredential, AuthEnvelope, AuthGrant, AuthGrantRequirement, AuthContext, AuthResolverDeps, CredentialProof, DelegationLink, ExecutionIdentity, } from "./types.js";
16
+ export type { RuntimeGrantAuthorizerRequest, RuntimeGrantAuthorizationResult, RuntimeGrantSupplier, } from "./runtime-authorizer.js";
17
+ export type { HarnessGrantAuthorizationRequest } from "./harness-authorizer.js";
6
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,YAAY,EACV,UAAU,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACL,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,eAAe,EACf,yBAAyB,EACzB,oBAAoB,EACpB,8BAA8B,EAC9B,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5E,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,EACf,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,12 @@
1
1
  export { signSession, verifySession } from "./session.js";
2
2
  export { generateApiKey, verifyApiKey, extractApiKeyPrefix, } from "./api-key.js";
3
3
  export { createAuthMiddleware } from "./middleware.js";
4
- export { checkPermission, derivePermission } from "./permissions.js";
4
+ export { authorizeGrant, checkGrant, checkPermission, derivePermission, normalizePermissionsToGrants, serializeGrantsToPermissions, } from "./permissions.js";
5
+ export { createExecutionIdentity, createRequestExecution, createDelegationLink, } from "./execution.js";
6
+ export { createGrant, grantRunActions, grantRunCollectionActions, grantApprovalActions, grantApprovalCollectionActions, grantEventActions, grantEventCollectionActions, grantArtifactActions, grantCheckpointActions, grantTaskActions, grantSummaryActions, grantSummaryCollectionActions, grantMemoryActions, grantContextActions, grantRuntimePathsActions, } from "./runtime-grants.js";
7
+ export { deriveRuntimeGrantRequirements, authorizeRuntimeAction, createRuntimeGrantAuthorizer, } from "./runtime-authorizer.js";
8
+ export { createHarnessGrantAuthorizer, toRuntimeGrantRequest, } from "./harness-authorizer.js";
9
+ export { validateDpopProof, clearDpopReplayCache, setDpopReplayStore } from "./dpop.js";
10
+ export { extractWorkloadIdentity, isValidSpiffeId } from "./workload.js";
11
+ export { googleProvider, githubProvider, createOAuthHandlers, } from "./oauth.js";
5
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACL,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,eAAe,EACf,yBAAyB,EACzB,oBAAoB,EACpB,8BAA8B,EAC9B,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EACL,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -4,11 +4,14 @@ import type { AuthConfig, AuthContext, AuthResolverDeps } from "./types.js";
4
4
  * incoming `Request`.
5
5
  *
6
6
  * Resolution order:
7
- * 1. Session cookie (`capstan_session`) — verifies JWT, returns human context.
8
- * 2. `Authorization: Bearer <token>` header — if the token matches the
7
+ * 1. Client certificate / workload identity (`X-Client-Cert` or
8
+ * `X-Forwarded-Client-Cert` header)extracts SPIFFE ID, validates
9
+ * trust domain, returns workload context.
10
+ * 2. Session cookie (`capstan_session`) — verifies JWT, returns human context.
11
+ * 3. `Authorization: Bearer <token>` header — if the token matches the
9
12
  * configured API key prefix, looks up the agent credential and verifies
10
13
  * the key hash.
11
- * 3. Falls back to `{ type: "anonymous", isAuthenticated: false }`.
14
+ * 4. Falls back to `{ type: "anonymous", isAuthenticated: false }`.
12
15
  */
13
16
  export declare function createAuthMiddleware(config: AuthConfig, deps: AuthResolverDeps): (request: Request) => Promise<AuthContext>;
14
17
  //# sourceMappingURL=middleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AA2BpB;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,gBAAgB,GACrB,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,CAuD5C"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EAGX,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AA6CpB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,gBAAgB,GACrB,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,CAiP5C"}