@zauso-ai/capstan-auth 1.0.0-beta.6 → 1.0.0-beta.8

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 (42) hide show
  1. package/dist/execution.d.ts +10 -0
  2. package/dist/execution.d.ts.map +1 -0
  3. package/dist/execution.js +50 -0
  4. package/dist/execution.js.map +1 -0
  5. package/dist/harness-authorizer.d.ts +10 -0
  6. package/dist/harness-authorizer.d.ts.map +1 -0
  7. package/dist/harness-authorizer.js +90 -0
  8. package/dist/harness-authorizer.js.map +1 -0
  9. package/dist/index.d.ts +10 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +6 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/middleware.d.ts.map +1 -1
  14. package/dist/middleware.js +141 -6
  15. package/dist/middleware.js.map +1 -1
  16. package/dist/oauth.d.ts +47 -0
  17. package/dist/oauth.d.ts.map +1 -0
  18. package/dist/oauth.js +199 -0
  19. package/dist/oauth.js.map +1 -0
  20. package/dist/permissions.d.ts +12 -22
  21. package/dist/permissions.d.ts.map +1 -1
  22. package/dist/permissions.js +91 -33
  23. package/dist/permissions.js.map +1 -1
  24. package/dist/runtime-authorizer.d.ts +28 -0
  25. package/dist/runtime-authorizer.d.ts.map +1 -0
  26. package/dist/runtime-authorizer.js +136 -0
  27. package/dist/runtime-authorizer.js.map +1 -0
  28. package/dist/runtime-grants.d.ts +31 -0
  29. package/dist/runtime-grants.d.ts.map +1 -0
  30. package/dist/runtime-grants.js +96 -0
  31. package/dist/runtime-grants.js.map +1 -0
  32. package/dist/session.d.ts +3 -3
  33. package/dist/session.d.ts.map +1 -1
  34. package/dist/session.js +21 -3
  35. package/dist/session.js.map +1 -1
  36. package/dist/store.d.ts +2 -0
  37. package/dist/store.d.ts.map +1 -1
  38. package/dist/store.js +13 -0
  39. package/dist/store.js.map +1 -1
  40. package/dist/types.d.ts +99 -1
  41. package/dist/types.d.ts.map +1 -1
  42. package/package.json +1 -1
package/dist/oauth.js ADDED
@@ -0,0 +1,199 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { signSession } from "./session.js";
3
+ // ── Pre-built providers ───────────────────────────────────────────────
4
+ /** Pre-built Google OAuth provider */
5
+ export function googleProvider(opts) {
6
+ return {
7
+ name: "google",
8
+ authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
9
+ tokenUrl: "https://oauth2.googleapis.com/token",
10
+ userInfoUrl: "https://www.googleapis.com/oauth2/v3/userinfo",
11
+ clientId: opts.clientId,
12
+ clientSecret: opts.clientSecret,
13
+ scopes: ["openid", "email", "profile"],
14
+ };
15
+ }
16
+ /** Pre-built GitHub OAuth provider */
17
+ export function githubProvider(opts) {
18
+ return {
19
+ name: "github",
20
+ authorizeUrl: "https://github.com/login/oauth/authorize",
21
+ tokenUrl: "https://github.com/login/oauth/access_token",
22
+ userInfoUrl: "https://api.github.com/user",
23
+ clientId: opts.clientId,
24
+ clientSecret: opts.clientSecret,
25
+ scopes: ["user:email"],
26
+ };
27
+ }
28
+ // ── State management ──────────────────────────────────────────────────
29
+ /** Generate a cryptographically random state parameter. */
30
+ function generateState() {
31
+ return randomBytes(32).toString("hex");
32
+ }
33
+ // ── Cookie helpers ────────────────────────────────────────────────────
34
+ function parseCookies(header) {
35
+ const cookies = new Map();
36
+ for (const pair of header.split(";")) {
37
+ const eqIndex = pair.indexOf("=");
38
+ if (eqIndex === -1)
39
+ continue;
40
+ const name = pair.slice(0, eqIndex).trim();
41
+ const value = pair.slice(eqIndex + 1).trim();
42
+ cookies.set(name, value);
43
+ }
44
+ return cookies;
45
+ }
46
+ function buildCookie(name, value, options) {
47
+ const parts = [`${name}=${value}`];
48
+ parts.push(`Path=${options?.path ?? "/"}`);
49
+ if (options?.domain)
50
+ parts.push(`Domain=${options.domain}`);
51
+ if (options?.httpOnly !== false)
52
+ parts.push("HttpOnly");
53
+ parts.push(`SameSite=${options?.sameSite ?? "Lax"}`);
54
+ if (options?.secure)
55
+ parts.push("Secure");
56
+ if (options?.maxAge !== undefined)
57
+ parts.push(`Max-Age=${options.maxAge}`);
58
+ return parts.join("; ");
59
+ }
60
+ /**
61
+ * Create OAuth route handlers.
62
+ * Returns handlers for:
63
+ * - GET /auth/login/:provider — redirect to OAuth provider
64
+ * - GET /auth/callback — handle OAuth callback, create session
65
+ */
66
+ export function createOAuthHandlers(config, fetchFn = globalThis.fetch) {
67
+ const callbackPath = config.callbackPath ?? "/auth/callback";
68
+ const stateCookieName = config.stateCookieName ?? "capstan_oauth_state";
69
+ const sessionCookieName = config.session?.cookieName ?? "capstan_session";
70
+ const resolvedSessionSecret = config.session?.secret ?? config.sessionSecret;
71
+ if (!resolvedSessionSecret) {
72
+ throw new Error("OAuthConfig requires session.secret or sessionSecret");
73
+ }
74
+ const sessionSecret = resolvedSessionSecret;
75
+ const providerMap = new Map();
76
+ for (const p of config.providers) {
77
+ providerMap.set(p.name, p);
78
+ }
79
+ function login(request, providerName) {
80
+ const provider = providerMap.get(providerName);
81
+ if (!provider) {
82
+ return new Response(JSON.stringify({ error: `Unknown provider: ${providerName}` }), { status: 400, headers: { "content-type": "application/json" } });
83
+ }
84
+ const state = generateState();
85
+ const url = new URL(request.url);
86
+ const redirectUri = `${url.origin}${callbackPath}`;
87
+ const authorizeUrl = new URL(provider.authorizeUrl);
88
+ authorizeUrl.searchParams.set("client_id", provider.clientId);
89
+ authorizeUrl.searchParams.set("redirect_uri", redirectUri);
90
+ authorizeUrl.searchParams.set("response_type", "code");
91
+ authorizeUrl.searchParams.set("scope", provider.scopes.join(" "));
92
+ authorizeUrl.searchParams.set("state", `${providerName}:${state}`);
93
+ return new Response(null, {
94
+ status: 302,
95
+ headers: {
96
+ location: authorizeUrl.toString(),
97
+ "set-cookie": buildCookie(stateCookieName, `${providerName}:${state}`, {
98
+ maxAge: 600,
99
+ }),
100
+ },
101
+ });
102
+ }
103
+ async function callback(request) {
104
+ const url = new URL(request.url);
105
+ const code = url.searchParams.get("code");
106
+ const stateParam = url.searchParams.get("state");
107
+ if (!code || !stateParam) {
108
+ return new Response(JSON.stringify({ error: "Missing code or state parameter" }), { status: 400, headers: { "content-type": "application/json" } });
109
+ }
110
+ // Validate state against cookie
111
+ const cookieHeader = request.headers.get("cookie") ?? "";
112
+ const cookies = parseCookies(cookieHeader);
113
+ const storedState = cookies.get(stateCookieName);
114
+ if (!storedState || storedState !== stateParam) {
115
+ return new Response(JSON.stringify({ error: "Invalid state parameter" }), { status: 403, headers: { "content-type": "application/json" } });
116
+ }
117
+ // Extract provider name from state
118
+ const colonIndex = stateParam.indexOf(":");
119
+ if (colonIndex === -1) {
120
+ return new Response(JSON.stringify({ error: "Malformed state parameter" }), { status: 400, headers: { "content-type": "application/json" } });
121
+ }
122
+ const providerName = stateParam.slice(0, colonIndex);
123
+ const provider = providerMap.get(providerName);
124
+ if (!provider) {
125
+ return new Response(JSON.stringify({ error: `Unknown provider: ${providerName}` }), { status: 400, headers: { "content-type": "application/json" } });
126
+ }
127
+ // Exchange code for access token
128
+ const redirectUri = `${url.origin}${callbackPath}`;
129
+ let tokenData;
130
+ try {
131
+ const tokenResponse = await fetchFn(provider.tokenUrl, {
132
+ method: "POST",
133
+ headers: {
134
+ "content-type": "application/x-www-form-urlencoded",
135
+ accept: "application/json",
136
+ },
137
+ body: new URLSearchParams({
138
+ grant_type: "authorization_code",
139
+ code,
140
+ redirect_uri: redirectUri,
141
+ client_id: provider.clientId,
142
+ client_secret: provider.clientSecret,
143
+ }).toString(),
144
+ });
145
+ if (!tokenResponse.ok) {
146
+ return new Response(JSON.stringify({ error: "Token exchange failed" }), { status: 502, headers: { "content-type": "application/json" } });
147
+ }
148
+ tokenData = (await tokenResponse.json());
149
+ }
150
+ catch {
151
+ return new Response(JSON.stringify({ error: "Token exchange failed" }), { status: 502, headers: { "content-type": "application/json" } });
152
+ }
153
+ if (!tokenData.access_token) {
154
+ return new Response(JSON.stringify({ error: "Token exchange failed" }), { status: 502, headers: { "content-type": "application/json" } });
155
+ }
156
+ // Fetch user info
157
+ let userInfo;
158
+ try {
159
+ const userResponse = await fetchFn(provider.userInfoUrl, {
160
+ headers: {
161
+ authorization: `Bearer ${tokenData.access_token}`,
162
+ accept: "application/json",
163
+ },
164
+ });
165
+ if (!userResponse.ok) {
166
+ return new Response(JSON.stringify({ error: "Failed to fetch user info" }), { status: 502, headers: { "content-type": "application/json" } });
167
+ }
168
+ userInfo = (await userResponse.json());
169
+ }
170
+ catch {
171
+ return new Response(JSON.stringify({ error: "Failed to fetch user info" }), { status: 502, headers: { "content-type": "application/json" } });
172
+ }
173
+ // Build session from user info
174
+ const userId = userInfo.sub ?? userInfo.id?.toString() ?? userInfo.login ?? "unknown";
175
+ const sessionData = {
176
+ userId: `${providerName}:${userId}`,
177
+ ...(userInfo.name !== undefined ? { displayName: userInfo.name } : {}),
178
+ };
179
+ if (userInfo.email !== undefined) {
180
+ sessionData.email = userInfo.email;
181
+ }
182
+ const sessionToken = signSession(sessionData, sessionSecret, config.session?.maxAge !== undefined
183
+ ? { maxAge: config.session.maxAge }
184
+ : undefined);
185
+ // Set session cookie and redirect to /
186
+ return new Response(null, {
187
+ status: 302,
188
+ headers: {
189
+ location: config.successRedirectPath ?? "/",
190
+ "set-cookie": buildCookie(sessionCookieName, sessionToken, {
191
+ ...(config.session?.cookie ?? {}),
192
+ maxAge: 604800,
193
+ }),
194
+ },
195
+ });
196
+ }
197
+ return { login, callback };
198
+ }
199
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
@@ -1,34 +1,24 @@
1
+ import type { AuthGrant, AuthGrantRequirement } from "./types.js";
2
+ export interface AuthorizationDecision {
3
+ allowed: boolean;
4
+ matchedGrant?: AuthGrant;
5
+ reason?: string;
6
+ }
7
+ export declare function normalizePermissionsToGrants(granted: readonly (string | AuthGrant)[]): AuthGrant[];
8
+ export declare function serializeGrantsToPermissions(grants: readonly AuthGrant[]): string[];
9
+ export declare function authorizeGrant(required: AuthGrantRequirement, granted: readonly (string | AuthGrant)[]): AuthorizationDecision;
10
+ export declare function checkGrant(required: AuthGrantRequirement, granted: readonly (string | AuthGrant)[]): boolean;
1
11
  /**
2
12
  * Check whether a required permission is satisfied by at least one entry in
3
- * the `granted` permission set.
4
- *
5
- * Permission strings follow the `resource:action` pattern.
6
- *
7
- * Wildcards:
8
- * - `*:read` — allows `read` on any resource
9
- * - `ticket:*` — allows any action on `ticket`
10
- * - `*:*` — full access (superuser)
11
- *
12
- * Examples:
13
- * checkPermission({ resource: "ticket", action: "read" }, ["ticket:read"]) // true
14
- * checkPermission({ resource: "ticket", action: "write" }, ["*:write"]) // true
15
- * checkPermission({ resource: "ticket", action: "delete" }, ["ticket:*"]) // true
16
- * checkPermission({ resource: "ticket", action: "delete" }, ["*:*"]) // true
13
+ * the granted permission / grant set.
17
14
  */
18
15
  export declare function checkPermission(required: {
19
16
  resource: string;
20
17
  action: "read" | "write" | "delete";
21
- }, granted: string[]): boolean;
18
+ }, granted: readonly (string | AuthGrant)[]): boolean;
22
19
  /**
23
20
  * Derive a `{ resource, action }` pair from an agent capability mode and
24
21
  * an optional resource name.
25
- *
26
- * Mapping:
27
- * - `"read"` → `{ resource, action: "read" }`
28
- * - `"write"` → `{ resource, action: "write" }`
29
- * - `"external"` → `{ resource: "external", action: "write" }`
30
- *
31
- * When `resource` is omitted the wildcard `"*"` is used.
32
22
  */
33
23
  export declare function derivePermission(capability: "read" | "write" | "external", resource?: string): {
34
24
  resource: string;
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,EACnE,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAiBT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,EACzC,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAStC"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgDD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACvC,SAAS,EAAE,CAab;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,EAAE,CAEnF;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACvC,qBAAqB,CA0BvB;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACvC,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,EACnE,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACvC,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,EACzC,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAStC"}
@@ -1,44 +1,102 @@
1
+ import { createGrant } from "./runtime-grants.js";
2
+ function isGrantRecord(value) {
3
+ return (typeof value === "object" &&
4
+ value !== null &&
5
+ "resource" in value &&
6
+ "action" in value &&
7
+ typeof value["resource"] === "string" &&
8
+ typeof value["action"] === "string");
9
+ }
10
+ function parsePermission(permission) {
11
+ const sepIndex = permission.indexOf(":");
12
+ if (sepIndex === -1)
13
+ return null;
14
+ return createGrant(permission.slice(0, sepIndex), permission.slice(sepIndex + 1));
15
+ }
16
+ function scopeMatches(required, granted) {
17
+ if (!required || Object.keys(required).length === 0)
18
+ return true;
19
+ if (!granted)
20
+ return false;
21
+ for (const [key, value] of Object.entries(required)) {
22
+ const grantedValue = granted[key];
23
+ if (grantedValue !== "*" && grantedValue !== value) {
24
+ return false;
25
+ }
26
+ }
27
+ return true;
28
+ }
29
+ function resourceMatches(required, granted) {
30
+ return granted === "*" || granted === required;
31
+ }
32
+ function actionMatches(required, granted) {
33
+ return granted === "*" || granted === required;
34
+ }
35
+ function isGrantExpired(grant) {
36
+ if (grant.expiresAt === undefined)
37
+ return false;
38
+ const expiresAt = Date.parse(grant.expiresAt);
39
+ return Number.isFinite(expiresAt) && expiresAt <= Date.now();
40
+ }
41
+ export function normalizePermissionsToGrants(granted) {
42
+ const grants = [];
43
+ for (const entry of granted) {
44
+ if (typeof entry === "string") {
45
+ const parsed = parsePermission(entry);
46
+ if (parsed)
47
+ grants.push(parsed);
48
+ continue;
49
+ }
50
+ if (isGrantRecord(entry)) {
51
+ grants.push(entry);
52
+ }
53
+ }
54
+ return grants;
55
+ }
56
+ export function serializeGrantsToPermissions(grants) {
57
+ return grants.map((grant) => `${grant.resource}:${grant.action}`);
58
+ }
59
+ export function authorizeGrant(required, granted) {
60
+ const grants = normalizePermissionsToGrants(granted);
61
+ let matchedAllowGrant;
62
+ for (const grant of grants) {
63
+ if (isGrantExpired(grant))
64
+ continue;
65
+ const matches = resourceMatches(required.resource, grant.resource) &&
66
+ actionMatches(required.action, grant.action) &&
67
+ scopeMatches(required.scope, grant.scope);
68
+ if (!matches)
69
+ continue;
70
+ if (grant.effect === "deny") {
71
+ return {
72
+ allowed: false,
73
+ matchedGrant: grant,
74
+ reason: `Grant explicitly denied ${required.resource}:${required.action}`,
75
+ };
76
+ }
77
+ matchedAllowGrant = grant;
78
+ }
79
+ if (matchedAllowGrant) {
80
+ return { allowed: true, matchedGrant: matchedAllowGrant };
81
+ }
82
+ return {
83
+ allowed: false,
84
+ reason: `No grant matched ${required.resource}:${required.action}`,
85
+ };
86
+ }
87
+ export function checkGrant(required, granted) {
88
+ return authorizeGrant(required, granted).allowed;
89
+ }
1
90
  /**
2
91
  * Check whether a required permission is satisfied by at least one entry in
3
- * the `granted` permission set.
4
- *
5
- * Permission strings follow the `resource:action` pattern.
6
- *
7
- * Wildcards:
8
- * - `*:read` — allows `read` on any resource
9
- * - `ticket:*` — allows any action on `ticket`
10
- * - `*:*` — full access (superuser)
11
- *
12
- * Examples:
13
- * checkPermission({ resource: "ticket", action: "read" }, ["ticket:read"]) // true
14
- * checkPermission({ resource: "ticket", action: "write" }, ["*:write"]) // true
15
- * checkPermission({ resource: "ticket", action: "delete" }, ["ticket:*"]) // true
16
- * checkPermission({ resource: "ticket", action: "delete" }, ["*:*"]) // true
92
+ * the granted permission / grant set.
17
93
  */
18
94
  export function checkPermission(required, granted) {
19
- for (const perm of granted) {
20
- const sepIndex = perm.indexOf(":");
21
- if (sepIndex === -1)
22
- continue; // malformed entry, skip
23
- const grantedResource = perm.slice(0, sepIndex);
24
- const grantedAction = perm.slice(sepIndex + 1);
25
- const resourceMatch = grantedResource === "*" || grantedResource === required.resource;
26
- const actionMatch = grantedAction === "*" || grantedAction === required.action;
27
- if (resourceMatch && actionMatch)
28
- return true;
29
- }
30
- return false;
95
+ return checkGrant(required, granted);
31
96
  }
32
97
  /**
33
98
  * Derive a `{ resource, action }` pair from an agent capability mode and
34
99
  * an optional resource name.
35
- *
36
- * Mapping:
37
- * - `"read"` → `{ resource, action: "read" }`
38
- * - `"write"` → `{ resource, action: "write" }`
39
- * - `"external"` → `{ resource: "external", action: "write" }`
40
- *
41
- * When `resource` is omitted the wildcard `"*"` is used.
42
100
  */
43
101
  export function derivePermission(capability, resource) {
44
102
  if (capability === "external") {
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAmE,EACnE,OAAiB;IAEjB,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,SAAS,CAAC,wBAAwB;QAEvD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAE/C,MAAM,aAAa,GACjB,eAAe,KAAK,GAAG,IAAI,eAAe,KAAK,QAAQ,CAAC,QAAQ,CAAC;QACnE,MAAM,WAAW,GACf,aAAa,KAAK,GAAG,IAAI,aAAa,KAAK,QAAQ,CAAC,MAAM,CAAC;QAE7D,IAAI,aAAa,IAAI,WAAW;YAAE,OAAO,IAAI,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAyC,EACzC,QAAiB;IAEjB,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACnD,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,QAAQ,IAAI,GAAG;QACzB,MAAM,EAAE,UAAU;KACnB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { AuthGrant, AuthGrantRequirement } from "./types.js";
2
+ import { type AuthorizationDecision } from "./permissions.js";
3
+ export interface RuntimeGrantScope {
4
+ runId?: string;
5
+ approvalId?: string;
6
+ artifactId?: string;
7
+ taskId?: string;
8
+ summaryId?: string;
9
+ memoryId?: string;
10
+ tool?: string;
11
+ }
12
+ export interface RuntimeGrantAttributes {
13
+ memoryKind?: "session" | "persistent";
14
+ approvalKind?: "tool" | "task";
15
+ }
16
+ export interface RuntimeGrantAuthorizerRequest {
17
+ action: string;
18
+ scope?: RuntimeGrantScope;
19
+ attributes?: RuntimeGrantAttributes;
20
+ }
21
+ export interface RuntimeGrantAuthorizationResult extends AuthorizationDecision {
22
+ matchedRequirement?: AuthGrantRequirement;
23
+ }
24
+ export type RuntimeGrantSupplier = readonly (string | AuthGrant)[] | (() => readonly (string | AuthGrant)[] | Promise<readonly (string | AuthGrant)[]>);
25
+ export declare function deriveRuntimeGrantRequirements(request: RuntimeGrantAuthorizerRequest): AuthGrantRequirement[];
26
+ export declare function authorizeRuntimeAction(request: RuntimeGrantAuthorizerRequest, granted: readonly (string | AuthGrant)[]): RuntimeGrantAuthorizationResult;
27
+ export declare function createRuntimeGrantAuthorizer(supplier: RuntimeGrantSupplier): (request: RuntimeGrantAuthorizerRequest) => Promise<RuntimeGrantAuthorizationResult>;
28
+ //# sourceMappingURL=runtime-authorizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-authorizer.d.ts","sourceRoot":"","sources":["../src/runtime-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC;AAED,MAAM,WAAW,+BAAgC,SAAQ,qBAAqB;IAC5E,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAC5B,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAC/B,CAAC,MAAM,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AA6CvF,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,6BAA6B,GACrC,oBAAoB,EAAE,CAiExB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,6BAA6B,EACtC,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACvC,+BAA+B,CA+BjC;AAWD,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,oBAAoB,IAC3D,SAAS,6BAA6B,8CAErD"}
@@ -0,0 +1,136 @@
1
+ import { authorizeGrant } from "./permissions.js";
2
+ function parseRuntimeAction(action) {
3
+ const separator = action.indexOf(":");
4
+ if (separator === -1) {
5
+ return { resource: action, action: "read" };
6
+ }
7
+ return {
8
+ resource: action.slice(0, separator),
9
+ action: action.slice(separator + 1),
10
+ };
11
+ }
12
+ function normalizedScope(scope) {
13
+ if (!scope) {
14
+ return undefined;
15
+ }
16
+ const entries = Object.entries(scope).filter((entry) => typeof entry[1] === "string" && entry[1].trim().length > 0);
17
+ if (entries.length === 0) {
18
+ return undefined;
19
+ }
20
+ return Object.fromEntries(entries);
21
+ }
22
+ function requirement(resource, action, scope) {
23
+ const nextScope = normalizedScope(scope);
24
+ return {
25
+ resource,
26
+ action,
27
+ ...(nextScope ? { scope: nextScope } : {}),
28
+ };
29
+ }
30
+ function runScope(scope) {
31
+ return scope?.runId ? { runId: scope.runId } : undefined;
32
+ }
33
+ export function deriveRuntimeGrantRequirements(request) {
34
+ const parsed = parseRuntimeAction(request.action);
35
+ const scope = request.scope;
36
+ const fallbackRunScope = runScope(scope);
37
+ switch (request.action) {
38
+ case "checkpoint:read":
39
+ return [
40
+ requirement("checkpoint", "read", scope),
41
+ requirement("run", "read", fallbackRunScope),
42
+ ];
43
+ case "artifact:read":
44
+ return [
45
+ requirement("artifact", "read", scope),
46
+ requirement("run", "read", fallbackRunScope),
47
+ ];
48
+ case "event:read":
49
+ return [
50
+ requirement("event", "read", scope),
51
+ requirement("run", "read", fallbackRunScope),
52
+ ];
53
+ case "task:read":
54
+ return [
55
+ requirement("task", "read", scope),
56
+ requirement("run", "read", fallbackRunScope),
57
+ ];
58
+ case "context:read":
59
+ return [
60
+ requirement("context", "read", scope),
61
+ requirement("run", "read", fallbackRunScope),
62
+ ];
63
+ case "summary:read":
64
+ return [
65
+ requirement("summary", "read", scope),
66
+ requirement("context", "read", fallbackRunScope),
67
+ requirement("run", "read", fallbackRunScope),
68
+ ];
69
+ case "memory:read":
70
+ return [
71
+ requirement("memory", "read", scope),
72
+ ...(request.attributes?.memoryKind === "session" && fallbackRunScope
73
+ ? [
74
+ requirement("context", "read", fallbackRunScope),
75
+ requirement("run", "read", fallbackRunScope),
76
+ ]
77
+ : []),
78
+ ];
79
+ case "approval:read":
80
+ return [
81
+ requirement("approval", "read", scope),
82
+ requirement("approval", "manage", scope),
83
+ ];
84
+ case "approval:approve":
85
+ return [
86
+ requirement("approval", "approve", scope),
87
+ requirement("approval", "manage", scope),
88
+ ];
89
+ case "approval:deny":
90
+ return [
91
+ requirement("approval", "deny", scope),
92
+ requirement("approval", "manage", scope),
93
+ ];
94
+ default:
95
+ return [requirement(parsed.resource, parsed.action, scope)];
96
+ }
97
+ }
98
+ export function authorizeRuntimeAction(request, granted) {
99
+ const requirements = deriveRuntimeGrantRequirements(request);
100
+ let denied;
101
+ for (const current of requirements) {
102
+ const decision = authorizeGrant(current, granted);
103
+ if (decision.allowed) {
104
+ return {
105
+ ...decision,
106
+ matchedRequirement: current,
107
+ };
108
+ }
109
+ if (decision.matchedGrant?.effect === "deny") {
110
+ denied = {
111
+ ...decision,
112
+ matchedRequirement: current,
113
+ };
114
+ break;
115
+ }
116
+ }
117
+ if (denied) {
118
+ return denied;
119
+ }
120
+ const matchedRequirement = requirements[0];
121
+ return {
122
+ allowed: false,
123
+ reason: `No grant matched ${request.action}`,
124
+ ...(matchedRequirement ? { matchedRequirement } : {}),
125
+ };
126
+ }
127
+ async function resolveRuntimeGrants(supplier) {
128
+ if (typeof supplier === "function") {
129
+ return supplier();
130
+ }
131
+ return supplier;
132
+ }
133
+ export function createRuntimeGrantAuthorizer(supplier) {
134
+ return async (request) => authorizeRuntimeAction(request, await resolveRuntimeGrants(supplier));
135
+ }
136
+ //# sourceMappingURL=runtime-authorizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-authorizer.js","sourceRoot":"","sources":["../src/runtime-authorizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { AuthGrant } from "./types.js";
2
+ export declare function createGrant(resource: string, action: string, options?: {
3
+ scope?: Record<string, string>;
4
+ expiresAt?: string;
5
+ constraints?: Record<string, unknown>;
6
+ effect?: "allow" | "deny";
7
+ }): AuthGrant;
8
+ export declare function grantRunActions(runId: string, actions?: readonly string[]): AuthGrant[];
9
+ export declare function grantApprovalActions(actions?: readonly string[], options?: {
10
+ approvalId?: string;
11
+ runId?: string;
12
+ tool?: string;
13
+ }): AuthGrant[];
14
+ export declare function grantApprovalCollectionActions(actions?: readonly string[], options?: {
15
+ runId?: string;
16
+ }): AuthGrant[];
17
+ export declare function grantArtifactActions(runId: string, actions?: readonly string[], artifactId?: string): AuthGrant[];
18
+ export declare function grantCheckpointActions(runId: string, actions?: readonly string[]): AuthGrant[];
19
+ export declare function grantRunCollectionActions(actions?: readonly string[]): AuthGrant[];
20
+ export declare function grantEventActions(runId: string, actions?: readonly string[]): AuthGrant[];
21
+ export declare function grantEventCollectionActions(actions?: readonly string[]): AuthGrant[];
22
+ export declare function grantTaskActions(runId: string, actions?: readonly string[], taskId?: string): AuthGrant[];
23
+ export declare function grantSummaryActions(runId: string, actions?: readonly string[], summaryId?: string): AuthGrant[];
24
+ export declare function grantSummaryCollectionActions(actions?: readonly string[]): AuthGrant[];
25
+ export declare function grantMemoryActions(actions?: readonly string[], options?: {
26
+ runId?: string;
27
+ memoryId?: string;
28
+ }): AuthGrant[];
29
+ export declare function grantContextActions(runId: string, actions?: readonly string[]): AuthGrant[];
30
+ export declare function grantRuntimePathsActions(actions?: readonly string[]): AuthGrant[];
31
+ //# sourceMappingURL=runtime-grants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-grants.d.ts","sourceRoot":"","sources":["../src/runtime-grants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC3B,GACA,SAAS,CAOX;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAA0C,GACjE,SAAS,EAAE,CAMb;AAED,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,SAAS,MAAM,EAA0C,EAClE,OAAO,CAAC,EAAE;IACR,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACA,SAAS,EAAE,CAUb;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,GAAE,SAAS,MAAM,EAAa,EACrC,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,SAAS,EAAE,CAMb;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,EACrC,UAAU,CAAC,EAAE,MAAM,GAClB,SAAS,EAAE,CAQb;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAMb;AAED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,SAAS,MAAM,EAAsB,GAC7C,SAAS,EAAE,CAEb;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAMb;AAED,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAEb;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,SAAS,EAAE,CAQb;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,EACrC,SAAS,CAAC,EAAE,MAAM,GACjB,SAAS,EAAE,CAQb;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAEb;AAED,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,SAAS,MAAM,EAAa,EACrC,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,SAAS,EAAE,CASb;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAMb;AAED,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,SAAS,MAAM,EAAa,GACpC,SAAS,EAAE,CAEb"}