@lelu-auth/lelu 0.1.4 → 0.1.5

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.
@@ -151,6 +151,50 @@ interface DelegateScopeResult {
151
151
  interface RevokeTokenResult {
152
152
  success: boolean;
153
153
  }
154
+ interface AuditEvent {
155
+ id: number;
156
+ tenantId: string;
157
+ traceId: string;
158
+ timestamp: string;
159
+ actor: string;
160
+ action: string;
161
+ resource?: Record<string, string>;
162
+ confidenceScore?: number;
163
+ decision: string;
164
+ reason?: string;
165
+ downgradedScope?: string;
166
+ latencyMs: number;
167
+ engineVersion?: string;
168
+ policyVersion?: string;
169
+ createdAt: string;
170
+ }
171
+ interface ListAuditEventsRequest {
172
+ /** Maximum number of events to return (default: 20, max: 500) */
173
+ limit?: number;
174
+ /** Pagination cursor (offset) */
175
+ cursor?: number;
176
+ /** Filter by actor */
177
+ actor?: string;
178
+ /** Filter by action */
179
+ action?: string;
180
+ /** Filter by decision */
181
+ decision?: string;
182
+ /** Filter by trace ID */
183
+ traceId?: string;
184
+ /** Filter events from this timestamp (ISO 8601) */
185
+ from?: string;
186
+ /** Filter events to this timestamp (ISO 8601) */
187
+ to?: string;
188
+ /** Tenant ID (defaults to "default") */
189
+ tenantId?: string;
190
+ }
191
+ interface ListAuditEventsResult {
192
+ events: AuditEvent[];
193
+ count: number;
194
+ limit: number;
195
+ cursor: number;
196
+ nextCursor: number;
197
+ }
154
198
  type AuthRequest = z.infer<typeof AuthRequestSchema>;
155
199
  type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;
156
200
  type AgentContext = z.infer<typeof AgentContextSchema>;
@@ -225,6 +269,11 @@ declare class LeluClient {
225
269
  * Returns true if the engine is reachable and healthy.
226
270
  */
227
271
  isHealthy(): Promise<boolean>;
272
+ /**
273
+ * Lists audit events from the platform API.
274
+ * Requires the platform service to be running (not just the engine).
275
+ */
276
+ listAuditEvents(req?: ListAuditEventsRequest): Promise<ListAuditEventsResult>;
228
277
  private headers;
229
278
  private post;
230
279
  private delete;
@@ -232,4 +281,4 @@ declare class LeluClient {
232
281
  private parseResponse;
233
282
  }
234
283
 
235
- export { type AgentAuthDecision as A, type ClientConfig as C, type DelegateScopeRequest as D, LeluClient as L, type MintTokenRequest as M, type RevokeTokenResult as R, type AgentAuthRequest as a, AgentAuthRequestSchema as b, type AgentContext as c, AgentContextSchema as d, type AuthDecision as e, AuthEngineError as f, type AuthRequest as g, AuthRequestSchema as h, DelegateScopeRequestSchema as i, type DelegateScopeResult as j, MintTokenRequestSchema as k, type MintTokenResult as l };
284
+ export { type AgentAuthDecision as A, type ClientConfig as C, type DelegateScopeRequest as D, LeluClient as L, type MintTokenRequest as M, type RevokeTokenResult as R, type AgentAuthRequest as a, AgentAuthRequestSchema as b, type AgentContext as c, AgentContextSchema as d, type AuditEvent as e, type AuthDecision as f, AuthEngineError as g, type AuthRequest as h, AuthRequestSchema as i, DelegateScopeRequestSchema as j, type DelegateScopeResult as k, type ListAuditEventsRequest as l, type ListAuditEventsResult as m, MintTokenRequestSchema as n, type MintTokenResult as o };
@@ -151,6 +151,50 @@ interface DelegateScopeResult {
151
151
  interface RevokeTokenResult {
152
152
  success: boolean;
153
153
  }
154
+ interface AuditEvent {
155
+ id: number;
156
+ tenantId: string;
157
+ traceId: string;
158
+ timestamp: string;
159
+ actor: string;
160
+ action: string;
161
+ resource?: Record<string, string>;
162
+ confidenceScore?: number;
163
+ decision: string;
164
+ reason?: string;
165
+ downgradedScope?: string;
166
+ latencyMs: number;
167
+ engineVersion?: string;
168
+ policyVersion?: string;
169
+ createdAt: string;
170
+ }
171
+ interface ListAuditEventsRequest {
172
+ /** Maximum number of events to return (default: 20, max: 500) */
173
+ limit?: number;
174
+ /** Pagination cursor (offset) */
175
+ cursor?: number;
176
+ /** Filter by actor */
177
+ actor?: string;
178
+ /** Filter by action */
179
+ action?: string;
180
+ /** Filter by decision */
181
+ decision?: string;
182
+ /** Filter by trace ID */
183
+ traceId?: string;
184
+ /** Filter events from this timestamp (ISO 8601) */
185
+ from?: string;
186
+ /** Filter events to this timestamp (ISO 8601) */
187
+ to?: string;
188
+ /** Tenant ID (defaults to "default") */
189
+ tenantId?: string;
190
+ }
191
+ interface ListAuditEventsResult {
192
+ events: AuditEvent[];
193
+ count: number;
194
+ limit: number;
195
+ cursor: number;
196
+ nextCursor: number;
197
+ }
154
198
  type AuthRequest = z.infer<typeof AuthRequestSchema>;
155
199
  type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;
156
200
  type AgentContext = z.infer<typeof AgentContextSchema>;
@@ -225,6 +269,11 @@ declare class LeluClient {
225
269
  * Returns true if the engine is reachable and healthy.
226
270
  */
227
271
  isHealthy(): Promise<boolean>;
272
+ /**
273
+ * Lists audit events from the platform API.
274
+ * Requires the platform service to be running (not just the engine).
275
+ */
276
+ listAuditEvents(req?: ListAuditEventsRequest): Promise<ListAuditEventsResult>;
228
277
  private headers;
229
278
  private post;
230
279
  private delete;
@@ -232,4 +281,4 @@ declare class LeluClient {
232
281
  private parseResponse;
233
282
  }
234
283
 
235
- export { type AgentAuthDecision as A, type ClientConfig as C, type DelegateScopeRequest as D, LeluClient as L, type MintTokenRequest as M, type RevokeTokenResult as R, type AgentAuthRequest as a, AgentAuthRequestSchema as b, type AgentContext as c, AgentContextSchema as d, type AuthDecision as e, AuthEngineError as f, type AuthRequest as g, AuthRequestSchema as h, DelegateScopeRequestSchema as i, type DelegateScopeResult as j, MintTokenRequestSchema as k, type MintTokenResult as l };
284
+ export { type AgentAuthDecision as A, type ClientConfig as C, type DelegateScopeRequest as D, LeluClient as L, type MintTokenRequest as M, type RevokeTokenResult as R, type AgentAuthRequest as a, AgentAuthRequestSchema as b, type AgentContext as c, AgentContextSchema as d, type AuditEvent as e, type AuthDecision as f, AuthEngineError as g, type AuthRequest as h, AuthRequestSchema as i, DelegateScopeRequestSchema as j, type DelegateScopeResult as k, type ListAuditEventsRequest as l, type ListAuditEventsResult as m, MintTokenRequestSchema as n, type MintTokenResult as o };
@@ -1,5 +1,5 @@
1
1
  import { RequestHandler } from 'express';
2
- import { L as LeluClient } from '../client-DL75VVER.mjs';
2
+ import { L as LeluClient } from '../client-DY93sy4F.mjs';
3
3
  import 'zod';
4
4
 
5
5
  interface AuthorizeOptions {
@@ -1,5 +1,5 @@
1
1
  import { RequestHandler } from 'express';
2
- import { L as LeluClient } from '../client-DL75VVER.js';
2
+ import { L as LeluClient } from '../client-DY93sy4F.js';
3
3
  import 'zod';
4
4
 
5
5
  interface AuthorizeOptions {
@@ -172,6 +172,46 @@ var LeluClient = class {
172
172
  return false;
173
173
  }
174
174
  }
175
+ // ── Audit log ──────────────────────────────────────────────────────────────
176
+ /**
177
+ * Lists audit events from the platform API.
178
+ * Requires the platform service to be running (not just the engine).
179
+ */
180
+ async listAuditEvents(req = {}) {
181
+ const params = new URLSearchParams();
182
+ if (req.limit !== void 0) params.set("limit", req.limit.toString());
183
+ if (req.cursor !== void 0) params.set("cursor", req.cursor.toString());
184
+ if (req.actor) params.set("actor", req.actor);
185
+ if (req.action) params.set("action", req.action);
186
+ if (req.decision) params.set("decision", req.decision);
187
+ if (req.traceId) params.set("trace_id", req.traceId);
188
+ if (req.from) params.set("from", req.from);
189
+ if (req.to) params.set("to", req.to);
190
+ const headers = this.headers();
191
+ if (req.tenantId) {
192
+ headers["X-Tenant-ID"] = req.tenantId;
193
+ }
194
+ const ctrl = new AbortController();
195
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
196
+ try {
197
+ const url = `${this.baseUrl}/v1/audit${params.toString() ? `?${params.toString()}` : ""}`;
198
+ const res = await fetch(url, {
199
+ method: "GET",
200
+ headers,
201
+ signal: ctrl.signal
202
+ });
203
+ const data = await this.parseResponse(res);
204
+ return {
205
+ events: data.events,
206
+ count: data.count,
207
+ limit: data.limit,
208
+ cursor: data.cursor,
209
+ nextCursor: data.next_cursor
210
+ };
211
+ } finally {
212
+ clearTimeout(timer);
213
+ }
214
+ }
175
215
  // ── HTTP helpers ───────────────────────────────────────────────────────────
176
216
  headers() {
177
217
  const h = { "Content-Type": "application/json" };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types.ts","../../src/client.ts","../../src/express/index.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\r\n\r\n// ─── Request / Response schemas ───────────────────────────────────────────────\r\n\r\nexport const AuthRequestSchema = z.object({\r\n userId: z.string().min(1, \"userId is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n});\r\n\r\nexport const AgentContextSchema = z.object({\r\n /** LLM confidence score — 0.0 to 1.0 */\r\n confidence: z.number().min(0).max(1),\r\n /** User the agent is acting on behalf of */\r\n actingFor: z.string().optional(),\r\n /** Requested agent scope */\r\n scope: z.string().optional(),\r\n});\r\n\r\nexport const AgentAuthRequestSchema = z.object({\r\n actor: z.string().min(1, \"actor is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n context: AgentContextSchema,\r\n});\r\n\r\nexport const MintTokenRequestSchema = z.object({\r\n scope: z.string().min(1),\r\n actingFor: z.string().optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const DelegateScopeRequestSchema = z.object({\r\n delegator: z.string().min(1, \"delegator is required\"),\r\n delegatee: z.string().min(1, \"delegatee is required\"),\r\n scopedTo: z.array(z.string().min(1)).optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n confidence: z.number().min(0).max(1).optional(),\r\n actingFor: z.string().optional(),\r\n tenantId: z.string().optional(),\r\n});\r\n\r\n// ─── Decision types ───────────────────────────────────────────────────────────\r\n\r\nexport interface AuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n}\r\n\r\nexport interface AgentAuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n downgradedScope: string | undefined;\r\n requiresHumanReview: boolean;\r\n confidenceUsed: number;\r\n}\r\n\r\nexport interface MintTokenResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n}\r\n\r\nexport interface DelegateScopeRequest {\r\n /** Agent delegating the scope */\r\n delegator: string;\r\n /** Agent receiving the constrained sub-scope */\r\n delegatee: string;\r\n /** Actions to grant (must be subset of policy's can_delegate.scoped_to) */\r\n scopedTo?: string[];\r\n /** Token TTL in seconds — capped by the policy's max_ttl_seconds */\r\n ttlSeconds?: number;\r\n /** Delegator's confidence score — checked against require_confidence_above */\r\n confidence?: number;\r\n /** User the delegated agent acts on behalf of */\r\n actingFor?: string;\r\n tenantId?: string;\r\n}\r\n\r\nexport interface DelegateScopeResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n delegator: string;\r\n delegatee: string;\r\n grantedScopes: string[];\r\n traceId: string;\r\n}\r\n\r\nexport interface RevokeTokenResult {\r\n success: boolean;\r\n}\r\n\r\n// ─── Typed Input types ───────────────────────────────────────────────────────\r\n\r\nexport type AuthRequest = z.infer<typeof AuthRequestSchema>;\r\nexport type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;\r\nexport type AgentContext = z.infer<typeof AgentContextSchema>;\r\nexport type MintTokenRequest = z.infer<typeof MintTokenRequestSchema>;\r\n\r\n// ─── Client config ────────────────────────────────────────────────────────────\r\n\r\nexport interface ClientConfig {\r\n /** Base URL of the Auth Permission Engine (defaults to LELU_BASE_URL env var, else http://localhost:8080) */\r\n baseUrl?: string;\r\n /** Request timeout in milliseconds (default: 5000) */\r\n timeoutMs?: number;\r\n /** Optional bearer token for authenticating with the engine */\r\n apiKey?: string;\r\n}\r\n\r\n// ─── Error type ───────────────────────────────────────────────────────────────\r\n\r\nexport class AuthEngineError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = \"AuthEngineError\";\r\n }\r\n}\r\n","import {\r\n AuthEngineError,\r\n AuthRequestSchema,\r\n AgentAuthRequestSchema,\r\n MintTokenRequestSchema,\r\n DelegateScopeRequestSchema,\r\n type AuthDecision,\r\n type AgentAuthDecision,\r\n type MintTokenResult,\r\n type DelegateScopeResult,\r\n type DelegateScopeRequest,\r\n type RevokeTokenResult,\r\n type AuthRequest,\r\n type AgentAuthRequest,\r\n type MintTokenRequest,\r\n type ClientConfig,\r\n} from \"./types.js\";\r\n\r\n// ─── Client ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LeluClient is the core SDK entry-point. It communicates with the local\r\n * Auth Permission Engine sidecar over HTTP/JSON.\r\n *\r\n * @example\r\n * ```ts\r\n * const lelu = new LeluClient({ baseUrl: \"http://localhost:8080\" });\r\n *\r\n * const decision = await lelu.agentAuthorize({\r\n * actor: \"invoice_bot\",\r\n * action: \"approve_refunds\",\r\n * context: { confidence: 0.92, actingFor: \"user_123\" },\r\n * });\r\n *\r\n * if (!decision.allowed) {\r\n * console.log(decision.reason);\r\n * }\r\n * ```\r\n */\r\nexport class LeluClient {\r\n private readonly baseUrl: string;\r\n private readonly timeoutMs: number;\r\n private readonly apiKey: string | undefined;\r\n\r\n constructor(cfg: ClientConfig = {}) {\r\n const envBaseUrl =\r\n typeof process !== \"undefined\" && process.env\r\n ? process.env[\"LELU_BASE_URL\"]\r\n : undefined;\r\n this.baseUrl = (cfg.baseUrl ?? envBaseUrl ?? \"http://localhost:8080\").replace(/\\/$/, \"\");\r\n this.timeoutMs = cfg.timeoutMs ?? 5_000;\r\n this.apiKey = cfg.apiKey;\r\n }\r\n\r\n // ── Human authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether a human user is permitted to perform an action.\r\n */\r\n async authorize(req: AuthRequest): Promise<AuthDecision> {\r\n const validated = AuthRequestSchema.parse(req);\r\n const body = {\r\n user_id: validated.userId,\r\n action: validated.action,\r\n resource: validated.resource,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n }>(\"/v1/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Agent authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether an AI agent is permitted to perform an action, taking the\r\n * confidence score into account (Confidence-Aware Auth ★).\r\n */\r\n async agentAuthorize(req: AgentAuthRequest): Promise<AgentAuthDecision> {\r\n const validated = AgentAuthRequestSchema.parse(req);\r\n const body = {\r\n actor: validated.actor,\r\n action: validated.action,\r\n resource: validated.resource,\r\n confidence: validated.context.confidence,\r\n acting_for: validated.context.actingFor,\r\n scope: validated.context.scope,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n downgraded_scope?: string;\r\n requires_human_review: boolean;\r\n confidence_used: number;\r\n }>(\"/v1/agent/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n downgradedScope: data.downgraded_scope,\r\n requiresHumanReview: data.requires_human_review,\r\n confidenceUsed: data.confidence_used,\r\n };\r\n }\r\n\r\n // ── JIT Token minting ──────────────────────────────────────────────────────\r\n\r\n /**\r\n * Mints a scoped JWT for an agent with an optional TTL.\r\n * Default TTL is 60 seconds.\r\n */\r\n async mintToken(req: MintTokenRequest): Promise<MintTokenResult> {\r\n const validated = MintTokenRequestSchema.parse(req);\r\n const body = {\r\n scope: validated.scope,\r\n acting_for: validated.actingFor,\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n }>(\"/v1/tokens/mint\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n };\r\n }\r\n\r\n // ── Token revocation ───────────────────────────────────────────────────────\r\n\r\n /**\r\n * Immediately revokes a JIT token by its ID.\r\n */\r\n async revokeToken(tokenId: string): Promise<RevokeTokenResult> {\r\n const data = await this.delete<{ success: boolean }>(\r\n `/v1/tokens/${encodeURIComponent(tokenId)}`\r\n );\r\n return { success: data.success };\r\n }\r\n\r\n // ── Multi-agent delegation ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Delegates a constrained sub-scope from one agent to another.\r\n *\r\n * Validates the delegation rule in the loaded policy, caps the TTL to the\r\n * policy maximum, and mints a child JIT token scoped to the granted actions.\r\n *\r\n * The delegator's `confidence` score is checked against the policy's\r\n * `require_confidence_above` before delegation is granted.\r\n */\r\n async delegateScope(req: DelegateScopeRequest): Promise<DelegateScopeResult> {\r\n const validated = DelegateScopeRequestSchema.parse(req);\r\n const body = {\r\n delegator: validated.delegator,\r\n delegatee: validated.delegatee,\r\n scoped_to: validated.scopedTo ?? [],\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n confidence: validated.confidence ?? 1.0,\r\n acting_for: validated.actingFor ?? \"\",\r\n tenant_id: validated.tenantId ?? \"\",\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n delegator: string;\r\n delegatee: string;\r\n granted_scopes: string[];\r\n trace_id: string;\r\n }>(\"/v1/agent/delegate\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n delegator: data.delegator,\r\n delegatee: data.delegatee,\r\n grantedScopes: data.granted_scopes,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Health check ───────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Returns true if the engine is reachable and healthy.\r\n */\r\n async isHealthy(): Promise<boolean> {\r\n try {\r\n const data = await this.get<{ status: string }>(\"/healthz\");\r\n return data.status === \"ok\";\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ── HTTP helpers ───────────────────────────────────────────────────────────\r\n\r\n private headers(): Record<string, string> {\r\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.apiKey) {\r\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\r\n }\r\n return h;\r\n }\r\n\r\n private async post<T>(path: string, body: unknown): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"POST\",\r\n headers: this.headers(),\r\n body: JSON.stringify(body),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async delete<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"DELETE\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async get<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"GET\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async parseResponse<T>(res: Response): Promise<T> {\r\n const json = (await res.json()) as Record<string, unknown>;\r\n if (!res.ok) {\r\n throw new AuthEngineError(\r\n (json[\"error\"] as string) ?? \"engine error\",\r\n res.status,\r\n json\r\n );\r\n }\r\n return json as T;\r\n }\r\n}\r\n","import type { Request, Response, NextFunction, RequestHandler } from \"express\";\r\nimport { LeluClient } from \"../client\";\r\n\r\nexport interface AuthorizeOptions {\r\n /** Base URL of the Lelu engine (default: http://localhost:8080) */\r\n baseUrl?: string;\r\n /** API key for the Lelu engine */\r\n apiKey?: string;\r\n /** HTTP header that carries the actor identifier (default: x-actor) */\r\n actorHeader?: string;\r\n /** Confidence score to pass to the engine (default: 1.0) */\r\n confidence?: number;\r\n /** Explicit LeluClient instance (overrides baseUrl/apiKey) */\r\n client?: LeluClient;\r\n}\r\n\r\n/**\r\n * Express middleware factory that calls the Lelu engine and either calls\r\n * `next()` (allowed) or returns a 403 JSON response (denied / human_review).\r\n *\r\n * ```ts\r\n * import express from \"express\";\r\n * import { authorize } from \"@lelu/sdk/express\";\r\n *\r\n * const app = express();\r\n * app.get(\"/sensitive\", authorize(\"files.read\", { confidence: 0.9 }), handler);\r\n * ```\r\n */\r\nexport function authorize(action: string, opts: AuthorizeOptions = {}): RequestHandler {\r\n const clientConfig: any = {\r\n baseUrl: opts.baseUrl ?? process.env[\"LELU_BASE_URL\"] ?? \"http://localhost:8080\",\r\n };\r\n const apiKey = opts.apiKey ?? process.env[\"LELU_API_KEY\"];\r\n if (apiKey !== undefined) {\r\n clientConfig.apiKey = apiKey;\r\n }\r\n const client = opts.client ?? new LeluClient(clientConfig);\r\n\r\n const actorHeader = opts.actorHeader ?? \"x-actor\";\r\n const confidence = opts.confidence ?? 1.0;\r\n\r\n return async function leluAuthorize(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> {\r\n const actor = (req.headers[actorHeader] as string | undefined) ?? \"anonymous\";\r\n\r\n try {\r\n const decision = await client.agentAuthorize({ actor, action, context: { confidence } });\r\n\r\n if (decision.allowed) {\r\n // Attach decision to request for downstream handlers\r\n (req as Request & { leluDecision: typeof decision }).leluDecision = decision;\r\n next();\r\n return;\r\n }\r\n\r\n res.status(403).json({\r\n error: \"forbidden\",\r\n decision: decision.allowed,\r\n reason: decision.reason ?? \"denied by policy\",\r\n actor,\r\n action,\r\n });\r\n } catch (err) {\r\n res.status(503).json({\r\n error: \"lelu_unavailable\",\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/types.ts","../../src/client.ts","../../src/express/index.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\r\n\r\n// ─── Request / Response schemas ───────────────────────────────────────────────\r\n\r\nexport const AuthRequestSchema = z.object({\r\n userId: z.string().min(1, \"userId is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n});\r\n\r\nexport const AgentContextSchema = z.object({\r\n /** LLM confidence score — 0.0 to 1.0 */\r\n confidence: z.number().min(0).max(1),\r\n /** User the agent is acting on behalf of */\r\n actingFor: z.string().optional(),\r\n /** Requested agent scope */\r\n scope: z.string().optional(),\r\n});\r\n\r\nexport const AgentAuthRequestSchema = z.object({\r\n actor: z.string().min(1, \"actor is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n context: AgentContextSchema,\r\n});\r\n\r\nexport const MintTokenRequestSchema = z.object({\r\n scope: z.string().min(1),\r\n actingFor: z.string().optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const DelegateScopeRequestSchema = z.object({\r\n delegator: z.string().min(1, \"delegator is required\"),\r\n delegatee: z.string().min(1, \"delegatee is required\"),\r\n scopedTo: z.array(z.string().min(1)).optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n confidence: z.number().min(0).max(1).optional(),\r\n actingFor: z.string().optional(),\r\n tenantId: z.string().optional(),\r\n});\r\n\r\n// ─── Decision types ───────────────────────────────────────────────────────────\r\n\r\nexport interface AuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n}\r\n\r\nexport interface AgentAuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n downgradedScope: string | undefined;\r\n requiresHumanReview: boolean;\r\n confidenceUsed: number;\r\n}\r\n\r\nexport interface MintTokenResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n}\r\n\r\nexport interface DelegateScopeRequest {\r\n /** Agent delegating the scope */\r\n delegator: string;\r\n /** Agent receiving the constrained sub-scope */\r\n delegatee: string;\r\n /** Actions to grant (must be subset of policy's can_delegate.scoped_to) */\r\n scopedTo?: string[];\r\n /** Token TTL in seconds — capped by the policy's max_ttl_seconds */\r\n ttlSeconds?: number;\r\n /** Delegator's confidence score — checked against require_confidence_above */\r\n confidence?: number;\r\n /** User the delegated agent acts on behalf of */\r\n actingFor?: string;\r\n tenantId?: string;\r\n}\r\n\r\nexport interface DelegateScopeResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n delegator: string;\r\n delegatee: string;\r\n grantedScopes: string[];\r\n traceId: string;\r\n}\r\n\r\nexport interface RevokeTokenResult {\r\n success: boolean;\r\n}\r\n\r\n// ─── Audit types ──────────────────────────────────────────────────────────────\r\n\r\nexport interface AuditEvent {\r\n id: number;\r\n tenantId: string;\r\n traceId: string;\r\n timestamp: string;\r\n actor: string;\r\n action: string;\r\n resource?: Record<string, string>;\r\n confidenceScore?: number;\r\n decision: string; // \"allowed\" | \"denied\" | \"human_review\"\r\n reason?: string;\r\n downgradedScope?: string;\r\n latencyMs: number;\r\n engineVersion?: string;\r\n policyVersion?: string;\r\n createdAt: string;\r\n}\r\n\r\nexport interface ListAuditEventsRequest {\r\n /** Maximum number of events to return (default: 20, max: 500) */\r\n limit?: number;\r\n /** Pagination cursor (offset) */\r\n cursor?: number;\r\n /** Filter by actor */\r\n actor?: string;\r\n /** Filter by action */\r\n action?: string;\r\n /** Filter by decision */\r\n decision?: string;\r\n /** Filter by trace ID */\r\n traceId?: string;\r\n /** Filter events from this timestamp (ISO 8601) */\r\n from?: string;\r\n /** Filter events to this timestamp (ISO 8601) */\r\n to?: string;\r\n /** Tenant ID (defaults to \"default\") */\r\n tenantId?: string;\r\n}\r\n\r\nexport interface ListAuditEventsResult {\r\n events: AuditEvent[];\r\n count: number;\r\n limit: number;\r\n cursor: number;\r\n nextCursor: number;\r\n}\r\n\r\n// ─── Typed Input types ───────────────────────────────────────────────────────\r\n\r\nexport type AuthRequest = z.infer<typeof AuthRequestSchema>;\r\nexport type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;\r\nexport type AgentContext = z.infer<typeof AgentContextSchema>;\r\nexport type MintTokenRequest = z.infer<typeof MintTokenRequestSchema>;\r\n\r\n// ─── Client config ────────────────────────────────────────────────────────────\r\n\r\nexport interface ClientConfig {\r\n /** Base URL of the Auth Permission Engine (defaults to LELU_BASE_URL env var, else http://localhost:8080) */\r\n baseUrl?: string;\r\n /** Request timeout in milliseconds (default: 5000) */\r\n timeoutMs?: number;\r\n /** Optional bearer token for authenticating with the engine */\r\n apiKey?: string;\r\n}\r\n\r\n// ─── Error type ───────────────────────────────────────────────────────────────\r\n\r\nexport class AuthEngineError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = \"AuthEngineError\";\r\n }\r\n}\r\n","import {\r\n AuthEngineError,\r\n AuthRequestSchema,\r\n AgentAuthRequestSchema,\r\n MintTokenRequestSchema,\r\n DelegateScopeRequestSchema,\r\n type AuthDecision,\r\n type AgentAuthDecision,\r\n type MintTokenResult,\r\n type DelegateScopeResult,\r\n type DelegateScopeRequest,\r\n type RevokeTokenResult,\r\n type AuthRequest,\r\n type AgentAuthRequest,\r\n type MintTokenRequest,\r\n type ClientConfig,\r\n type AuditEvent,\r\n type ListAuditEventsRequest,\r\n type ListAuditEventsResult,\r\n} from \"./types.js\";\r\n\r\n// ─── Client ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LeluClient is the core SDK entry-point. It communicates with the local\r\n * Auth Permission Engine sidecar over HTTP/JSON.\r\n *\r\n * @example\r\n * ```ts\r\n * const lelu = new LeluClient({ baseUrl: \"http://localhost:8080\" });\r\n *\r\n * const decision = await lelu.agentAuthorize({\r\n * actor: \"invoice_bot\",\r\n * action: \"approve_refunds\",\r\n * context: { confidence: 0.92, actingFor: \"user_123\" },\r\n * });\r\n *\r\n * if (!decision.allowed) {\r\n * console.log(decision.reason);\r\n * }\r\n * ```\r\n */\r\nexport class LeluClient {\r\n private readonly baseUrl: string;\r\n private readonly timeoutMs: number;\r\n private readonly apiKey: string | undefined;\r\n\r\n constructor(cfg: ClientConfig = {}) {\r\n const envBaseUrl =\r\n typeof process !== \"undefined\" && process.env\r\n ? process.env[\"LELU_BASE_URL\"]\r\n : undefined;\r\n this.baseUrl = (cfg.baseUrl ?? envBaseUrl ?? \"http://localhost:8080\").replace(/\\/$/, \"\");\r\n this.timeoutMs = cfg.timeoutMs ?? 5_000;\r\n this.apiKey = cfg.apiKey;\r\n }\r\n\r\n // ── Human authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether a human user is permitted to perform an action.\r\n */\r\n async authorize(req: AuthRequest): Promise<AuthDecision> {\r\n const validated = AuthRequestSchema.parse(req);\r\n const body = {\r\n user_id: validated.userId,\r\n action: validated.action,\r\n resource: validated.resource,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n }>(\"/v1/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Agent authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether an AI agent is permitted to perform an action, taking the\r\n * confidence score into account (Confidence-Aware Auth ★).\r\n */\r\n async agentAuthorize(req: AgentAuthRequest): Promise<AgentAuthDecision> {\r\n const validated = AgentAuthRequestSchema.parse(req);\r\n const body = {\r\n actor: validated.actor,\r\n action: validated.action,\r\n resource: validated.resource,\r\n confidence: validated.context.confidence,\r\n acting_for: validated.context.actingFor,\r\n scope: validated.context.scope,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n downgraded_scope?: string;\r\n requires_human_review: boolean;\r\n confidence_used: number;\r\n }>(\"/v1/agent/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n downgradedScope: data.downgraded_scope,\r\n requiresHumanReview: data.requires_human_review,\r\n confidenceUsed: data.confidence_used,\r\n };\r\n }\r\n\r\n // ── JIT Token minting ──────────────────────────────────────────────────────\r\n\r\n /**\r\n * Mints a scoped JWT for an agent with an optional TTL.\r\n * Default TTL is 60 seconds.\r\n */\r\n async mintToken(req: MintTokenRequest): Promise<MintTokenResult> {\r\n const validated = MintTokenRequestSchema.parse(req);\r\n const body = {\r\n scope: validated.scope,\r\n acting_for: validated.actingFor,\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n }>(\"/v1/tokens/mint\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n };\r\n }\r\n\r\n // ── Token revocation ───────────────────────────────────────────────────────\r\n\r\n /**\r\n * Immediately revokes a JIT token by its ID.\r\n */\r\n async revokeToken(tokenId: string): Promise<RevokeTokenResult> {\r\n const data = await this.delete<{ success: boolean }>(\r\n `/v1/tokens/${encodeURIComponent(tokenId)}`\r\n );\r\n return { success: data.success };\r\n }\r\n\r\n // ── Multi-agent delegation ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Delegates a constrained sub-scope from one agent to another.\r\n *\r\n * Validates the delegation rule in the loaded policy, caps the TTL to the\r\n * policy maximum, and mints a child JIT token scoped to the granted actions.\r\n *\r\n * The delegator's `confidence` score is checked against the policy's\r\n * `require_confidence_above` before delegation is granted.\r\n */\r\n async delegateScope(req: DelegateScopeRequest): Promise<DelegateScopeResult> {\r\n const validated = DelegateScopeRequestSchema.parse(req);\r\n const body = {\r\n delegator: validated.delegator,\r\n delegatee: validated.delegatee,\r\n scoped_to: validated.scopedTo ?? [],\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n confidence: validated.confidence ?? 1.0,\r\n acting_for: validated.actingFor ?? \"\",\r\n tenant_id: validated.tenantId ?? \"\",\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n delegator: string;\r\n delegatee: string;\r\n granted_scopes: string[];\r\n trace_id: string;\r\n }>(\"/v1/agent/delegate\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n delegator: data.delegator,\r\n delegatee: data.delegatee,\r\n grantedScopes: data.granted_scopes,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Health check ───────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Returns true if the engine is reachable and healthy.\r\n */\r\n async isHealthy(): Promise<boolean> {\r\n try {\r\n const data = await this.get<{ status: string }>(\"/healthz\");\r\n return data.status === \"ok\";\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ── Audit log ──────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Lists audit events from the platform API.\r\n * Requires the platform service to be running (not just the engine).\r\n */\r\n async listAuditEvents(req: ListAuditEventsRequest = {}): Promise<ListAuditEventsResult> {\r\n const params = new URLSearchParams();\r\n \r\n if (req.limit !== undefined) params.set(\"limit\", req.limit.toString());\r\n if (req.cursor !== undefined) params.set(\"cursor\", req.cursor.toString());\r\n if (req.actor) params.set(\"actor\", req.actor);\r\n if (req.action) params.set(\"action\", req.action);\r\n if (req.decision) params.set(\"decision\", req.decision);\r\n if (req.traceId) params.set(\"trace_id\", req.traceId);\r\n if (req.from) params.set(\"from\", req.from);\r\n if (req.to) params.set(\"to\", req.to);\r\n\r\n const headers = this.headers();\r\n if (req.tenantId) {\r\n headers[\"X-Tenant-ID\"] = req.tenantId;\r\n }\r\n\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const url = `${this.baseUrl}/v1/audit${params.toString() ? `?${params.toString()}` : \"\"}`;\r\n const res = await fetch(url, {\r\n method: \"GET\",\r\n headers,\r\n signal: ctrl.signal,\r\n });\r\n \r\n const data = await this.parseResponse<{\r\n events: AuditEvent[];\r\n count: number;\r\n limit: number;\r\n cursor: number;\r\n next_cursor: number;\r\n }>(res);\r\n\r\n return {\r\n events: data.events,\r\n count: data.count,\r\n limit: data.limit,\r\n cursor: data.cursor,\r\n nextCursor: data.next_cursor,\r\n };\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n // ── HTTP helpers ───────────────────────────────────────────────────────────\r\n\r\n private headers(): Record<string, string> {\r\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.apiKey) {\r\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\r\n }\r\n return h;\r\n }\r\n\r\n private async post<T>(path: string, body: unknown): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"POST\",\r\n headers: this.headers(),\r\n body: JSON.stringify(body),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async delete<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"DELETE\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async get<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"GET\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async parseResponse<T>(res: Response): Promise<T> {\r\n const json = (await res.json()) as Record<string, unknown>;\r\n if (!res.ok) {\r\n throw new AuthEngineError(\r\n (json[\"error\"] as string) ?? \"engine error\",\r\n res.status,\r\n json\r\n );\r\n }\r\n return json as T;\r\n }\r\n}\r\n","import type { Request, Response, NextFunction, RequestHandler } from \"express\";\r\nimport { LeluClient } from \"../client\";\r\n\r\nexport interface AuthorizeOptions {\r\n /** Base URL of the Lelu engine (default: http://localhost:8080) */\r\n baseUrl?: string;\r\n /** API key for the Lelu engine */\r\n apiKey?: string;\r\n /** HTTP header that carries the actor identifier (default: x-actor) */\r\n actorHeader?: string;\r\n /** Confidence score to pass to the engine (default: 1.0) */\r\n confidence?: number;\r\n /** Explicit LeluClient instance (overrides baseUrl/apiKey) */\r\n client?: LeluClient;\r\n}\r\n\r\n/**\r\n * Express middleware factory that calls the Lelu engine and either calls\r\n * `next()` (allowed) or returns a 403 JSON response (denied / human_review).\r\n *\r\n * ```ts\r\n * import express from \"express\";\r\n * import { authorize } from \"@lelu/sdk/express\";\r\n *\r\n * const app = express();\r\n * app.get(\"/sensitive\", authorize(\"files.read\", { confidence: 0.9 }), handler);\r\n * ```\r\n */\r\nexport function authorize(action: string, opts: AuthorizeOptions = {}): RequestHandler {\r\n const clientConfig: any = {\r\n baseUrl: opts.baseUrl ?? process.env[\"LELU_BASE_URL\"] ?? \"http://localhost:8080\",\r\n };\r\n const apiKey = opts.apiKey ?? process.env[\"LELU_API_KEY\"];\r\n if (apiKey !== undefined) {\r\n clientConfig.apiKey = apiKey;\r\n }\r\n const client = opts.client ?? new LeluClient(clientConfig);\r\n\r\n const actorHeader = opts.actorHeader ?? \"x-actor\";\r\n const confidence = opts.confidence ?? 1.0;\r\n\r\n return async function leluAuthorize(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> {\r\n const actor = (req.headers[actorHeader] as string | undefined) ?? \"anonymous\";\r\n\r\n try {\r\n const decision = await client.agentAuthorize({ actor, action, context: { confidence } });\r\n\r\n if (decision.allowed) {\r\n // Attach decision to request for downstream handlers\r\n (req as Request & { leluDecision: typeof decision }).leluDecision = decision;\r\n next();\r\n return;\r\n }\r\n\r\n res.status(403).json({\r\n error: \"forbidden\",\r\n decision: decision.allowed,\r\n reason: decision.reason ?? \"denied by policy\",\r\n actor,\r\n action,\r\n });\r\n } catch (err) {\r\n res.status(503).json({\r\n error: \"lelu_unavailable\",\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n };\r\n}\r\n"]}
@@ -170,6 +170,46 @@ var LeluClient = class {
170
170
  return false;
171
171
  }
172
172
  }
173
+ // ── Audit log ──────────────────────────────────────────────────────────────
174
+ /**
175
+ * Lists audit events from the platform API.
176
+ * Requires the platform service to be running (not just the engine).
177
+ */
178
+ async listAuditEvents(req = {}) {
179
+ const params = new URLSearchParams();
180
+ if (req.limit !== void 0) params.set("limit", req.limit.toString());
181
+ if (req.cursor !== void 0) params.set("cursor", req.cursor.toString());
182
+ if (req.actor) params.set("actor", req.actor);
183
+ if (req.action) params.set("action", req.action);
184
+ if (req.decision) params.set("decision", req.decision);
185
+ if (req.traceId) params.set("trace_id", req.traceId);
186
+ if (req.from) params.set("from", req.from);
187
+ if (req.to) params.set("to", req.to);
188
+ const headers = this.headers();
189
+ if (req.tenantId) {
190
+ headers["X-Tenant-ID"] = req.tenantId;
191
+ }
192
+ const ctrl = new AbortController();
193
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
194
+ try {
195
+ const url = `${this.baseUrl}/v1/audit${params.toString() ? `?${params.toString()}` : ""}`;
196
+ const res = await fetch(url, {
197
+ method: "GET",
198
+ headers,
199
+ signal: ctrl.signal
200
+ });
201
+ const data = await this.parseResponse(res);
202
+ return {
203
+ events: data.events,
204
+ count: data.count,
205
+ limit: data.limit,
206
+ cursor: data.cursor,
207
+ nextCursor: data.next_cursor
208
+ };
209
+ } finally {
210
+ clearTimeout(timer);
211
+ }
212
+ }
173
213
  // ── HTTP helpers ───────────────────────────────────────────────────────────
174
214
  headers() {
175
215
  const h = { "Content-Type": "application/json" };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types.ts","../../src/client.ts","../../src/express/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from \"zod\";\r\n\r\n// ─── Request / Response schemas ───────────────────────────────────────────────\r\n\r\nexport const AuthRequestSchema = z.object({\r\n userId: z.string().min(1, \"userId is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n});\r\n\r\nexport const AgentContextSchema = z.object({\r\n /** LLM confidence score — 0.0 to 1.0 */\r\n confidence: z.number().min(0).max(1),\r\n /** User the agent is acting on behalf of */\r\n actingFor: z.string().optional(),\r\n /** Requested agent scope */\r\n scope: z.string().optional(),\r\n});\r\n\r\nexport const AgentAuthRequestSchema = z.object({\r\n actor: z.string().min(1, \"actor is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n context: AgentContextSchema,\r\n});\r\n\r\nexport const MintTokenRequestSchema = z.object({\r\n scope: z.string().min(1),\r\n actingFor: z.string().optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const DelegateScopeRequestSchema = z.object({\r\n delegator: z.string().min(1, \"delegator is required\"),\r\n delegatee: z.string().min(1, \"delegatee is required\"),\r\n scopedTo: z.array(z.string().min(1)).optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n confidence: z.number().min(0).max(1).optional(),\r\n actingFor: z.string().optional(),\r\n tenantId: z.string().optional(),\r\n});\r\n\r\n// ─── Decision types ───────────────────────────────────────────────────────────\r\n\r\nexport interface AuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n}\r\n\r\nexport interface AgentAuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n downgradedScope: string | undefined;\r\n requiresHumanReview: boolean;\r\n confidenceUsed: number;\r\n}\r\n\r\nexport interface MintTokenResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n}\r\n\r\nexport interface DelegateScopeRequest {\r\n /** Agent delegating the scope */\r\n delegator: string;\r\n /** Agent receiving the constrained sub-scope */\r\n delegatee: string;\r\n /** Actions to grant (must be subset of policy's can_delegate.scoped_to) */\r\n scopedTo?: string[];\r\n /** Token TTL in seconds — capped by the policy's max_ttl_seconds */\r\n ttlSeconds?: number;\r\n /** Delegator's confidence score — checked against require_confidence_above */\r\n confidence?: number;\r\n /** User the delegated agent acts on behalf of */\r\n actingFor?: string;\r\n tenantId?: string;\r\n}\r\n\r\nexport interface DelegateScopeResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n delegator: string;\r\n delegatee: string;\r\n grantedScopes: string[];\r\n traceId: string;\r\n}\r\n\r\nexport interface RevokeTokenResult {\r\n success: boolean;\r\n}\r\n\r\n// ─── Typed Input types ───────────────────────────────────────────────────────\r\n\r\nexport type AuthRequest = z.infer<typeof AuthRequestSchema>;\r\nexport type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;\r\nexport type AgentContext = z.infer<typeof AgentContextSchema>;\r\nexport type MintTokenRequest = z.infer<typeof MintTokenRequestSchema>;\r\n\r\n// ─── Client config ────────────────────────────────────────────────────────────\r\n\r\nexport interface ClientConfig {\r\n /** Base URL of the Auth Permission Engine (defaults to LELU_BASE_URL env var, else http://localhost:8080) */\r\n baseUrl?: string;\r\n /** Request timeout in milliseconds (default: 5000) */\r\n timeoutMs?: number;\r\n /** Optional bearer token for authenticating with the engine */\r\n apiKey?: string;\r\n}\r\n\r\n// ─── Error type ───────────────────────────────────────────────────────────────\r\n\r\nexport class AuthEngineError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = \"AuthEngineError\";\r\n }\r\n}\r\n","import {\r\n AuthEngineError,\r\n AuthRequestSchema,\r\n AgentAuthRequestSchema,\r\n MintTokenRequestSchema,\r\n DelegateScopeRequestSchema,\r\n type AuthDecision,\r\n type AgentAuthDecision,\r\n type MintTokenResult,\r\n type DelegateScopeResult,\r\n type DelegateScopeRequest,\r\n type RevokeTokenResult,\r\n type AuthRequest,\r\n type AgentAuthRequest,\r\n type MintTokenRequest,\r\n type ClientConfig,\r\n} from \"./types.js\";\r\n\r\n// ─── Client ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LeluClient is the core SDK entry-point. It communicates with the local\r\n * Auth Permission Engine sidecar over HTTP/JSON.\r\n *\r\n * @example\r\n * ```ts\r\n * const lelu = new LeluClient({ baseUrl: \"http://localhost:8080\" });\r\n *\r\n * const decision = await lelu.agentAuthorize({\r\n * actor: \"invoice_bot\",\r\n * action: \"approve_refunds\",\r\n * context: { confidence: 0.92, actingFor: \"user_123\" },\r\n * });\r\n *\r\n * if (!decision.allowed) {\r\n * console.log(decision.reason);\r\n * }\r\n * ```\r\n */\r\nexport class LeluClient {\r\n private readonly baseUrl: string;\r\n private readonly timeoutMs: number;\r\n private readonly apiKey: string | undefined;\r\n\r\n constructor(cfg: ClientConfig = {}) {\r\n const envBaseUrl =\r\n typeof process !== \"undefined\" && process.env\r\n ? process.env[\"LELU_BASE_URL\"]\r\n : undefined;\r\n this.baseUrl = (cfg.baseUrl ?? envBaseUrl ?? \"http://localhost:8080\").replace(/\\/$/, \"\");\r\n this.timeoutMs = cfg.timeoutMs ?? 5_000;\r\n this.apiKey = cfg.apiKey;\r\n }\r\n\r\n // ── Human authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether a human user is permitted to perform an action.\r\n */\r\n async authorize(req: AuthRequest): Promise<AuthDecision> {\r\n const validated = AuthRequestSchema.parse(req);\r\n const body = {\r\n user_id: validated.userId,\r\n action: validated.action,\r\n resource: validated.resource,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n }>(\"/v1/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Agent authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether an AI agent is permitted to perform an action, taking the\r\n * confidence score into account (Confidence-Aware Auth ★).\r\n */\r\n async agentAuthorize(req: AgentAuthRequest): Promise<AgentAuthDecision> {\r\n const validated = AgentAuthRequestSchema.parse(req);\r\n const body = {\r\n actor: validated.actor,\r\n action: validated.action,\r\n resource: validated.resource,\r\n confidence: validated.context.confidence,\r\n acting_for: validated.context.actingFor,\r\n scope: validated.context.scope,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n downgraded_scope?: string;\r\n requires_human_review: boolean;\r\n confidence_used: number;\r\n }>(\"/v1/agent/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n downgradedScope: data.downgraded_scope,\r\n requiresHumanReview: data.requires_human_review,\r\n confidenceUsed: data.confidence_used,\r\n };\r\n }\r\n\r\n // ── JIT Token minting ──────────────────────────────────────────────────────\r\n\r\n /**\r\n * Mints a scoped JWT for an agent with an optional TTL.\r\n * Default TTL is 60 seconds.\r\n */\r\n async mintToken(req: MintTokenRequest): Promise<MintTokenResult> {\r\n const validated = MintTokenRequestSchema.parse(req);\r\n const body = {\r\n scope: validated.scope,\r\n acting_for: validated.actingFor,\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n }>(\"/v1/tokens/mint\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n };\r\n }\r\n\r\n // ── Token revocation ───────────────────────────────────────────────────────\r\n\r\n /**\r\n * Immediately revokes a JIT token by its ID.\r\n */\r\n async revokeToken(tokenId: string): Promise<RevokeTokenResult> {\r\n const data = await this.delete<{ success: boolean }>(\r\n `/v1/tokens/${encodeURIComponent(tokenId)}`\r\n );\r\n return { success: data.success };\r\n }\r\n\r\n // ── Multi-agent delegation ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Delegates a constrained sub-scope from one agent to another.\r\n *\r\n * Validates the delegation rule in the loaded policy, caps the TTL to the\r\n * policy maximum, and mints a child JIT token scoped to the granted actions.\r\n *\r\n * The delegator's `confidence` score is checked against the policy's\r\n * `require_confidence_above` before delegation is granted.\r\n */\r\n async delegateScope(req: DelegateScopeRequest): Promise<DelegateScopeResult> {\r\n const validated = DelegateScopeRequestSchema.parse(req);\r\n const body = {\r\n delegator: validated.delegator,\r\n delegatee: validated.delegatee,\r\n scoped_to: validated.scopedTo ?? [],\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n confidence: validated.confidence ?? 1.0,\r\n acting_for: validated.actingFor ?? \"\",\r\n tenant_id: validated.tenantId ?? \"\",\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n delegator: string;\r\n delegatee: string;\r\n granted_scopes: string[];\r\n trace_id: string;\r\n }>(\"/v1/agent/delegate\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n delegator: data.delegator,\r\n delegatee: data.delegatee,\r\n grantedScopes: data.granted_scopes,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Health check ───────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Returns true if the engine is reachable and healthy.\r\n */\r\n async isHealthy(): Promise<boolean> {\r\n try {\r\n const data = await this.get<{ status: string }>(\"/healthz\");\r\n return data.status === \"ok\";\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ── HTTP helpers ───────────────────────────────────────────────────────────\r\n\r\n private headers(): Record<string, string> {\r\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.apiKey) {\r\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\r\n }\r\n return h;\r\n }\r\n\r\n private async post<T>(path: string, body: unknown): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"POST\",\r\n headers: this.headers(),\r\n body: JSON.stringify(body),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async delete<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"DELETE\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async get<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"GET\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async parseResponse<T>(res: Response): Promise<T> {\r\n const json = (await res.json()) as Record<string, unknown>;\r\n if (!res.ok) {\r\n throw new AuthEngineError(\r\n (json[\"error\"] as string) ?? \"engine error\",\r\n res.status,\r\n json\r\n );\r\n }\r\n return json as T;\r\n }\r\n}\r\n","import type { Request, Response, NextFunction, RequestHandler } from \"express\";\r\nimport { LeluClient } from \"../client\";\r\n\r\nexport interface AuthorizeOptions {\r\n /** Base URL of the Lelu engine (default: http://localhost:8080) */\r\n baseUrl?: string;\r\n /** API key for the Lelu engine */\r\n apiKey?: string;\r\n /** HTTP header that carries the actor identifier (default: x-actor) */\r\n actorHeader?: string;\r\n /** Confidence score to pass to the engine (default: 1.0) */\r\n confidence?: number;\r\n /** Explicit LeluClient instance (overrides baseUrl/apiKey) */\r\n client?: LeluClient;\r\n}\r\n\r\n/**\r\n * Express middleware factory that calls the Lelu engine and either calls\r\n * `next()` (allowed) or returns a 403 JSON response (denied / human_review).\r\n *\r\n * ```ts\r\n * import express from \"express\";\r\n * import { authorize } from \"@lelu/sdk/express\";\r\n *\r\n * const app = express();\r\n * app.get(\"/sensitive\", authorize(\"files.read\", { confidence: 0.9 }), handler);\r\n * ```\r\n */\r\nexport function authorize(action: string, opts: AuthorizeOptions = {}): RequestHandler {\r\n const clientConfig: any = {\r\n baseUrl: opts.baseUrl ?? process.env[\"LELU_BASE_URL\"] ?? \"http://localhost:8080\",\r\n };\r\n const apiKey = opts.apiKey ?? process.env[\"LELU_API_KEY\"];\r\n if (apiKey !== undefined) {\r\n clientConfig.apiKey = apiKey;\r\n }\r\n const client = opts.client ?? new LeluClient(clientConfig);\r\n\r\n const actorHeader = opts.actorHeader ?? \"x-actor\";\r\n const confidence = opts.confidence ?? 1.0;\r\n\r\n return async function leluAuthorize(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> {\r\n const actor = (req.headers[actorHeader] as string | undefined) ?? \"anonymous\";\r\n\r\n try {\r\n const decision = await client.agentAuthorize({ actor, action, context: { confidence } });\r\n\r\n if (decision.allowed) {\r\n // Attach decision to request for downstream handlers\r\n (req as Request & { leluDecision: typeof decision }).leluDecision = decision;\r\n next();\r\n return;\r\n }\r\n\r\n res.status(403).json({\r\n error: \"forbidden\",\r\n decision: decision.allowed,\r\n reason: decision.reason ?? \"denied by policy\",\r\n actor,\r\n action,\r\n });\r\n } catch (err) {\r\n res.status(503).json({\r\n error: \"lelu_unavailable\",\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/types.ts","../../src/client.ts","../../src/express/index.ts"],"names":[],"mappings":";;;AAIO,IAAM,iBAAA,GAAoB,EAAE,MAAA,CAAO;AAAA,EACxC,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,oBAAoB,CAAA;AAAA,EAC9C,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,oBAAoB,CAAA;AAAA,EAC9C,UAAU,CAAA,CAAE,MAAA,CAAO,EAAE,MAAA,EAAQ,EAAE,QAAA;AACjC,CAAC,CAAA;AAEM,IAAM,kBAAA,GAAqB,EAAE,MAAA,CAAO;AAAA;AAAA,EAEzC,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAEnC,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE/B,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACpB,CAAC,CAAA;AAEM,IAAM,sBAAA,GAAyB,EAAE,MAAA,CAAO;AAAA,EAC7C,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,mBAAmB,CAAA;AAAA,EAC5C,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,oBAAoB,CAAA;AAAA,EAC9C,UAAU,CAAA,CAAE,MAAA,CAAO,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,EACxC,OAAA,EAAS;AACX,CAAC,CAAA;AAEM,IAAM,sBAAA,GAAyB,EAAE,MAAA,CAAO;AAAA,EAC7C,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACvB,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC/B,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,GAAW,QAAA;AAC1C,CAAC,CAAA;AAEM,IAAM,0BAAA,GAA6B,EAAE,MAAA,CAAO;AAAA,EACjD,WAAW,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,uBAAuB,CAAA;AAAA,EACpD,WAAW,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,GAAG,uBAAuB,CAAA;AAAA,EACpD,QAAA,EAAU,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,EAC9C,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACjD,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,EAC9C,SAAA,EAAW,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC/B,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACvB,CAAC,CAAA;AA4HM,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EACzC,WAAA,CACE,OAAA,EACgB,MAAA,EACA,OAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHG,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AAAA,EACd;AACF,CAAA;;;ACnIO,IAAM,aAAN,MAAiB;AAAA,EACL,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EAEjB,WAAA,CAAY,GAAA,GAAoB,EAAC,EAAG;AAClC,IAAA,MAAM,UAAA,GACJ,OAAO,OAAA,KAAY,WAAA,IAAe,QAAQ,GAAA,GACtC,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA,GAC3B,MAAA;AACN,IAAA,IAAA,CAAK,WAAW,GAAA,CAAI,OAAA,IAAW,cAAc,uBAAA,EAAyB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACvF,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,SAAA,IAAa,GAAA;AAClC,IAAA,IAAA,CAAK,SAAS,GAAA,CAAI,MAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,GAAA,EAAyC;AACvD,IAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,KAAA,CAAM,GAAG,CAAA;AAC7C,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,SAAS,SAAA,CAAU,MAAA;AAAA,MACnB,QAAQ,SAAA,CAAU,MAAA;AAAA,MAClB,UAAU,SAAA,CAAU;AAAA,KACtB;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAIrB,iBAAiB,IAAI,CAAA;AAExB,IAAA,OAAO;AAAA,MACL,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,SAAS,IAAA,CAAK;AAAA,KAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,GAAA,EAAmD;AACtE,IAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,KAAA,CAAM,GAAG,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,OAAO,SAAA,CAAU,KAAA;AAAA,MACjB,QAAQ,SAAA,CAAU,MAAA;AAAA,MAClB,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,UAAA,EAAY,UAAU,OAAA,CAAQ,UAAA;AAAA,MAC9B,UAAA,EAAY,UAAU,OAAA,CAAQ,SAAA;AAAA,MAC9B,KAAA,EAAO,UAAU,OAAA,CAAQ;AAAA,KAC3B;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAOrB,uBAAuB,IAAI,CAAA;AAE9B,IAAA,OAAO;AAAA,MACL,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,SAAS,IAAA,CAAK,QAAA;AAAA,MACd,iBAAiB,IAAA,CAAK,gBAAA;AAAA,MACtB,qBAAqB,IAAA,CAAK,qBAAA;AAAA,MAC1B,gBAAgB,IAAA,CAAK;AAAA,KACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAU,GAAA,EAAiD;AAC/D,IAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,KAAA,CAAM,GAAG,CAAA;AAClD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,OAAO,SAAA,CAAU,KAAA;AAAA,MACjB,YAAY,SAAA,CAAU,SAAA;AAAA,MACtB,WAAA,EAAa,UAAU,UAAA,IAAc;AAAA,KACvC;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAIrB,mBAAmB,IAAI,CAAA;AAE1B,IAAA,OAAO;AAAA,MACL,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,SAAS,IAAA,CAAK,QAAA;AAAA,MACd,SAAA,EAAW,IAAI,IAAA,CAAK,IAAA,CAAK,aAAa,GAAI;AAAA,KAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,OAAA,EAA6C;AAC7D,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,MAAA;AAAA,MACtB,CAAA,WAAA,EAAc,kBAAA,CAAmB,OAAO,CAAC,CAAA;AAAA,KAC3C;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,EAAQ;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,cAAc,GAAA,EAAyD;AAC3E,IAAA,MAAM,SAAA,GAAY,0BAAA,CAA2B,KAAA,CAAM,GAAG,CAAA;AACtD,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,WAAW,SAAA,CAAU,SAAA;AAAA,MACrB,WAAW,SAAA,CAAU,SAAA;AAAA,MACrB,SAAA,EAAW,SAAA,CAAU,QAAA,IAAY,EAAC;AAAA,MAClC,WAAA,EAAa,UAAU,UAAA,IAAc,EAAA;AAAA,MACrC,UAAA,EAAY,UAAU,UAAA,IAAc,CAAA;AAAA,MACpC,UAAA,EAAY,UAAU,SAAA,IAAa,EAAA;AAAA,MACnC,SAAA,EAAW,UAAU,QAAA,IAAY;AAAA,KACnC;AACA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,IAAA,CAQrB,sBAAsB,IAAI,CAAA;AAE7B,IAAA,OAAO;AAAA,MACL,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,SAAS,IAAA,CAAK,QAAA;AAAA,MACd,SAAA,EAAW,IAAI,IAAA,CAAK,IAAA,CAAK,aAAa,GAAI,CAAA;AAAA,MAC1C,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,eAAe,IAAA,CAAK,cAAA;AAAA,MACpB,SAAS,IAAA,CAAK;AAAA,KAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAA,GAA8B;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,GAAA,CAAwB,UAAU,CAAA;AAC1D,MAAA,OAAO,KAAK,MAAA,KAAW,IAAA;AAAA,IACzB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAA,CAAgB,GAAA,GAA8B,EAAC,EAAmC;AACtF,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AAEnC,IAAA,IAAI,GAAA,CAAI,UAAU,MAAA,EAAW,MAAA,CAAO,IAAI,OAAA,EAAS,GAAA,CAAI,KAAA,CAAM,QAAA,EAAU,CAAA;AACrE,IAAA,IAAI,GAAA,CAAI,WAAW,MAAA,EAAW,MAAA,CAAO,IAAI,QAAA,EAAU,GAAA,CAAI,MAAA,CAAO,QAAA,EAAU,CAAA;AACxE,IAAA,IAAI,IAAI,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,IAAI,KAAK,CAAA;AAC5C,IAAA,IAAI,IAAI,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,QAAA,EAAU,IAAI,MAAM,CAAA;AAC/C,IAAA,IAAI,IAAI,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,IAAI,QAAQ,CAAA;AACrD,IAAA,IAAI,IAAI,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,IAAI,OAAO,CAAA;AACnD,IAAA,IAAI,IAAI,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,IAAI,IAAI,CAAA;AACzC,IAAA,IAAI,IAAI,EAAA,EAAI,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,IAAI,EAAE,CAAA;AAEnC,IAAA,MAAM,OAAA,GAAU,KAAK,OAAA,EAAQ;AAC7B,IAAA,IAAI,IAAI,QAAA,EAAU;AAChB,MAAA,OAAA,CAAQ,aAAa,IAAI,GAAA,CAAI,QAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,KAAK,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,SAAA,EAAY,MAAA,CAAO,QAAA,EAAS,GAAI,CAAA,CAAA,EAAI,MAAA,CAAO,QAAA,EAAU,KAAK,EAAE,CAAA,CAAA;AACvF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,QAC3B,MAAA,EAAQ,KAAA;AAAA,QACR,OAAA;AAAA,QACA,QAAQ,IAAA,CAAK;AAAA,OACd,CAAA;AAED,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,aAAA,CAMrB,GAAG,CAAA;AAEN,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,YAAY,IAAA,CAAK;AAAA,OACnB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAIQ,OAAA,GAAkC;AACxC,IAAA,MAAM,CAAA,GAA4B,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AACvE,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,CAAA,CAAE,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AAAA,EAEA,MAAc,IAAA,CAAQ,IAAA,EAAc,IAAA,EAA2B;AAC7D,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,KAAK,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,QAChD,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,QACtB,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAAA,QACzB,QAAQ,IAAA,CAAK;AAAA,OACd,CAAA;AACD,MAAA,OAAO,IAAA,CAAK,cAAiB,GAAG,CAAA;AAAA,IAClC,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,OAAU,IAAA,EAA0B;AAChD,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,KAAK,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,QAChD,MAAA,EAAQ,QAAA;AAAA,QACR,OAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,QACtB,QAAQ,IAAA,CAAK;AAAA,OACd,CAAA;AACD,MAAA,OAAO,IAAA,CAAK,cAAiB,GAAG,CAAA;AAAA,IAClC,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,IAAO,IAAA,EAA0B;AAC7C,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,KAAK,KAAA,EAAM,EAAG,KAAK,SAAS,CAAA;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI;AAAA,QAChD,MAAA,EAAQ,KAAA;AAAA,QACR,OAAA,EAAS,KAAK,OAAA,EAAQ;AAAA,QACtB,QAAQ,IAAA,CAAK;AAAA,OACd,CAAA;AACD,MAAA,OAAO,IAAA,CAAK,cAAiB,GAAG,CAAA;AAAA,IAClC,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,cAAiB,GAAA,EAA2B;AACxD,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,eAAA;AAAA,QACP,IAAA,CAAK,OAAO,CAAA,IAAgB,cAAA;AAAA,QAC7B,GAAA,CAAI,MAAA;AAAA,QACJ;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AChTO,SAAS,SAAA,CAAU,MAAA,EAAgB,IAAA,GAAyB,EAAC,EAAmB;AACrF,EAAA,MAAM,YAAA,GAAoB;AAAA,IACxB,SAAS,IAAA,CAAK,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA,IAAK;AAAA,GAC3D;AACA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,OAAA,CAAQ,IAAI,cAAc,CAAA;AACxD,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,YAAA,CAAa,MAAA,GAAS,MAAA;AAAA,EACxB;AACA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,IAAI,WAAW,YAAY,CAAA;AAEzD,EAAA,MAAM,WAAA,GAAc,KAAK,WAAA,IAAe,SAAA;AACxC,EAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,CAAA;AAEtC,EAAA,OAAO,eAAe,aAAA,CACpB,GAAA,EACA,GAAA,EACA,IAAA,EACe;AACf,IAAA,MAAM,KAAA,GAAS,GAAA,CAAI,OAAA,CAAQ,WAAW,CAAA,IAA4B,WAAA;AAElE,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,cAAA,CAAe,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAA,EAAS,EAAE,UAAA,EAAW,EAAG,CAAA;AAEvF,MAAA,IAAI,SAAS,OAAA,EAAS;AAEpB,QAAC,IAAoD,YAAA,GAAe,QAAA;AACpE,QAAA,IAAA,EAAK;AACL,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,QACnB,KAAA,EAAO,WAAA;AAAA,QACP,UAAU,QAAA,CAAS,OAAA;AAAA,QACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,kBAAA;AAAA,QAC3B,KAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,QACnB,KAAA,EAAO,kBAAA;AAAA,QACP,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,OACzD,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACF","file":"index.mjs","sourcesContent":["import { z } from \"zod\";\r\n\r\n// ─── Request / Response schemas ───────────────────────────────────────────────\r\n\r\nexport const AuthRequestSchema = z.object({\r\n userId: z.string().min(1, \"userId is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n});\r\n\r\nexport const AgentContextSchema = z.object({\r\n /** LLM confidence score — 0.0 to 1.0 */\r\n confidence: z.number().min(0).max(1),\r\n /** User the agent is acting on behalf of */\r\n actingFor: z.string().optional(),\r\n /** Requested agent scope */\r\n scope: z.string().optional(),\r\n});\r\n\r\nexport const AgentAuthRequestSchema = z.object({\r\n actor: z.string().min(1, \"actor is required\"),\r\n action: z.string().min(1, \"action is required\"),\r\n resource: z.record(z.string()).optional(),\r\n context: AgentContextSchema,\r\n});\r\n\r\nexport const MintTokenRequestSchema = z.object({\r\n scope: z.string().min(1),\r\n actingFor: z.string().optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n});\r\n\r\nexport const DelegateScopeRequestSchema = z.object({\r\n delegator: z.string().min(1, \"delegator is required\"),\r\n delegatee: z.string().min(1, \"delegatee is required\"),\r\n scopedTo: z.array(z.string().min(1)).optional(),\r\n ttlSeconds: z.number().int().positive().optional(),\r\n confidence: z.number().min(0).max(1).optional(),\r\n actingFor: z.string().optional(),\r\n tenantId: z.string().optional(),\r\n});\r\n\r\n// ─── Decision types ───────────────────────────────────────────────────────────\r\n\r\nexport interface AuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n}\r\n\r\nexport interface AgentAuthDecision {\r\n allowed: boolean;\r\n reason: string;\r\n traceId: string;\r\n downgradedScope: string | undefined;\r\n requiresHumanReview: boolean;\r\n confidenceUsed: number;\r\n}\r\n\r\nexport interface MintTokenResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n}\r\n\r\nexport interface DelegateScopeRequest {\r\n /** Agent delegating the scope */\r\n delegator: string;\r\n /** Agent receiving the constrained sub-scope */\r\n delegatee: string;\r\n /** Actions to grant (must be subset of policy's can_delegate.scoped_to) */\r\n scopedTo?: string[];\r\n /** Token TTL in seconds — capped by the policy's max_ttl_seconds */\r\n ttlSeconds?: number;\r\n /** Delegator's confidence score — checked against require_confidence_above */\r\n confidence?: number;\r\n /** User the delegated agent acts on behalf of */\r\n actingFor?: string;\r\n tenantId?: string;\r\n}\r\n\r\nexport interface DelegateScopeResult {\r\n token: string;\r\n tokenId: string;\r\n expiresAt: Date;\r\n delegator: string;\r\n delegatee: string;\r\n grantedScopes: string[];\r\n traceId: string;\r\n}\r\n\r\nexport interface RevokeTokenResult {\r\n success: boolean;\r\n}\r\n\r\n// ─── Audit types ──────────────────────────────────────────────────────────────\r\n\r\nexport interface AuditEvent {\r\n id: number;\r\n tenantId: string;\r\n traceId: string;\r\n timestamp: string;\r\n actor: string;\r\n action: string;\r\n resource?: Record<string, string>;\r\n confidenceScore?: number;\r\n decision: string; // \"allowed\" | \"denied\" | \"human_review\"\r\n reason?: string;\r\n downgradedScope?: string;\r\n latencyMs: number;\r\n engineVersion?: string;\r\n policyVersion?: string;\r\n createdAt: string;\r\n}\r\n\r\nexport interface ListAuditEventsRequest {\r\n /** Maximum number of events to return (default: 20, max: 500) */\r\n limit?: number;\r\n /** Pagination cursor (offset) */\r\n cursor?: number;\r\n /** Filter by actor */\r\n actor?: string;\r\n /** Filter by action */\r\n action?: string;\r\n /** Filter by decision */\r\n decision?: string;\r\n /** Filter by trace ID */\r\n traceId?: string;\r\n /** Filter events from this timestamp (ISO 8601) */\r\n from?: string;\r\n /** Filter events to this timestamp (ISO 8601) */\r\n to?: string;\r\n /** Tenant ID (defaults to \"default\") */\r\n tenantId?: string;\r\n}\r\n\r\nexport interface ListAuditEventsResult {\r\n events: AuditEvent[];\r\n count: number;\r\n limit: number;\r\n cursor: number;\r\n nextCursor: number;\r\n}\r\n\r\n// ─── Typed Input types ───────────────────────────────────────────────────────\r\n\r\nexport type AuthRequest = z.infer<typeof AuthRequestSchema>;\r\nexport type AgentAuthRequest = z.infer<typeof AgentAuthRequestSchema>;\r\nexport type AgentContext = z.infer<typeof AgentContextSchema>;\r\nexport type MintTokenRequest = z.infer<typeof MintTokenRequestSchema>;\r\n\r\n// ─── Client config ────────────────────────────────────────────────────────────\r\n\r\nexport interface ClientConfig {\r\n /** Base URL of the Auth Permission Engine (defaults to LELU_BASE_URL env var, else http://localhost:8080) */\r\n baseUrl?: string;\r\n /** Request timeout in milliseconds (default: 5000) */\r\n timeoutMs?: number;\r\n /** Optional bearer token for authenticating with the engine */\r\n apiKey?: string;\r\n}\r\n\r\n// ─── Error type ───────────────────────────────────────────────────────────────\r\n\r\nexport class AuthEngineError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n public readonly details?: unknown\r\n ) {\r\n super(message);\r\n this.name = \"AuthEngineError\";\r\n }\r\n}\r\n","import {\r\n AuthEngineError,\r\n AuthRequestSchema,\r\n AgentAuthRequestSchema,\r\n MintTokenRequestSchema,\r\n DelegateScopeRequestSchema,\r\n type AuthDecision,\r\n type AgentAuthDecision,\r\n type MintTokenResult,\r\n type DelegateScopeResult,\r\n type DelegateScopeRequest,\r\n type RevokeTokenResult,\r\n type AuthRequest,\r\n type AgentAuthRequest,\r\n type MintTokenRequest,\r\n type ClientConfig,\r\n type AuditEvent,\r\n type ListAuditEventsRequest,\r\n type ListAuditEventsResult,\r\n} from \"./types.js\";\r\n\r\n// ─── Client ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * LeluClient is the core SDK entry-point. It communicates with the local\r\n * Auth Permission Engine sidecar over HTTP/JSON.\r\n *\r\n * @example\r\n * ```ts\r\n * const lelu = new LeluClient({ baseUrl: \"http://localhost:8080\" });\r\n *\r\n * const decision = await lelu.agentAuthorize({\r\n * actor: \"invoice_bot\",\r\n * action: \"approve_refunds\",\r\n * context: { confidence: 0.92, actingFor: \"user_123\" },\r\n * });\r\n *\r\n * if (!decision.allowed) {\r\n * console.log(decision.reason);\r\n * }\r\n * ```\r\n */\r\nexport class LeluClient {\r\n private readonly baseUrl: string;\r\n private readonly timeoutMs: number;\r\n private readonly apiKey: string | undefined;\r\n\r\n constructor(cfg: ClientConfig = {}) {\r\n const envBaseUrl =\r\n typeof process !== \"undefined\" && process.env\r\n ? process.env[\"LELU_BASE_URL\"]\r\n : undefined;\r\n this.baseUrl = (cfg.baseUrl ?? envBaseUrl ?? \"http://localhost:8080\").replace(/\\/$/, \"\");\r\n this.timeoutMs = cfg.timeoutMs ?? 5_000;\r\n this.apiKey = cfg.apiKey;\r\n }\r\n\r\n // ── Human authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether a human user is permitted to perform an action.\r\n */\r\n async authorize(req: AuthRequest): Promise<AuthDecision> {\r\n const validated = AuthRequestSchema.parse(req);\r\n const body = {\r\n user_id: validated.userId,\r\n action: validated.action,\r\n resource: validated.resource,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n }>(\"/v1/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Agent authorization ────────────────────────────────────────────────────\r\n\r\n /**\r\n * Checks whether an AI agent is permitted to perform an action, taking the\r\n * confidence score into account (Confidence-Aware Auth ★).\r\n */\r\n async agentAuthorize(req: AgentAuthRequest): Promise<AgentAuthDecision> {\r\n const validated = AgentAuthRequestSchema.parse(req);\r\n const body = {\r\n actor: validated.actor,\r\n action: validated.action,\r\n resource: validated.resource,\r\n confidence: validated.context.confidence,\r\n acting_for: validated.context.actingFor,\r\n scope: validated.context.scope,\r\n };\r\n const data = await this.post<{\r\n allowed: boolean;\r\n reason: string;\r\n trace_id: string;\r\n downgraded_scope?: string;\r\n requires_human_review: boolean;\r\n confidence_used: number;\r\n }>(\"/v1/agent/authorize\", body);\r\n\r\n return {\r\n allowed: data.allowed,\r\n reason: data.reason,\r\n traceId: data.trace_id,\r\n downgradedScope: data.downgraded_scope,\r\n requiresHumanReview: data.requires_human_review,\r\n confidenceUsed: data.confidence_used,\r\n };\r\n }\r\n\r\n // ── JIT Token minting ──────────────────────────────────────────────────────\r\n\r\n /**\r\n * Mints a scoped JWT for an agent with an optional TTL.\r\n * Default TTL is 60 seconds.\r\n */\r\n async mintToken(req: MintTokenRequest): Promise<MintTokenResult> {\r\n const validated = MintTokenRequestSchema.parse(req);\r\n const body = {\r\n scope: validated.scope,\r\n acting_for: validated.actingFor,\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n }>(\"/v1/tokens/mint\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n };\r\n }\r\n\r\n // ── Token revocation ───────────────────────────────────────────────────────\r\n\r\n /**\r\n * Immediately revokes a JIT token by its ID.\r\n */\r\n async revokeToken(tokenId: string): Promise<RevokeTokenResult> {\r\n const data = await this.delete<{ success: boolean }>(\r\n `/v1/tokens/${encodeURIComponent(tokenId)}`\r\n );\r\n return { success: data.success };\r\n }\r\n\r\n // ── Multi-agent delegation ─────────────────────────────────────────────────\r\n\r\n /**\r\n * Delegates a constrained sub-scope from one agent to another.\r\n *\r\n * Validates the delegation rule in the loaded policy, caps the TTL to the\r\n * policy maximum, and mints a child JIT token scoped to the granted actions.\r\n *\r\n * The delegator's `confidence` score is checked against the policy's\r\n * `require_confidence_above` before delegation is granted.\r\n */\r\n async delegateScope(req: DelegateScopeRequest): Promise<DelegateScopeResult> {\r\n const validated = DelegateScopeRequestSchema.parse(req);\r\n const body = {\r\n delegator: validated.delegator,\r\n delegatee: validated.delegatee,\r\n scoped_to: validated.scopedTo ?? [],\r\n ttl_seconds: validated.ttlSeconds ?? 60,\r\n confidence: validated.confidence ?? 1.0,\r\n acting_for: validated.actingFor ?? \"\",\r\n tenant_id: validated.tenantId ?? \"\",\r\n };\r\n const data = await this.post<{\r\n token: string;\r\n token_id: string;\r\n expires_at: number;\r\n delegator: string;\r\n delegatee: string;\r\n granted_scopes: string[];\r\n trace_id: string;\r\n }>(\"/v1/agent/delegate\", body);\r\n\r\n return {\r\n token: data.token,\r\n tokenId: data.token_id,\r\n expiresAt: new Date(data.expires_at * 1000),\r\n delegator: data.delegator,\r\n delegatee: data.delegatee,\r\n grantedScopes: data.granted_scopes,\r\n traceId: data.trace_id,\r\n };\r\n }\r\n\r\n // ── Health check ───────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Returns true if the engine is reachable and healthy.\r\n */\r\n async isHealthy(): Promise<boolean> {\r\n try {\r\n const data = await this.get<{ status: string }>(\"/healthz\");\r\n return data.status === \"ok\";\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ── Audit log ──────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Lists audit events from the platform API.\r\n * Requires the platform service to be running (not just the engine).\r\n */\r\n async listAuditEvents(req: ListAuditEventsRequest = {}): Promise<ListAuditEventsResult> {\r\n const params = new URLSearchParams();\r\n \r\n if (req.limit !== undefined) params.set(\"limit\", req.limit.toString());\r\n if (req.cursor !== undefined) params.set(\"cursor\", req.cursor.toString());\r\n if (req.actor) params.set(\"actor\", req.actor);\r\n if (req.action) params.set(\"action\", req.action);\r\n if (req.decision) params.set(\"decision\", req.decision);\r\n if (req.traceId) params.set(\"trace_id\", req.traceId);\r\n if (req.from) params.set(\"from\", req.from);\r\n if (req.to) params.set(\"to\", req.to);\r\n\r\n const headers = this.headers();\r\n if (req.tenantId) {\r\n headers[\"X-Tenant-ID\"] = req.tenantId;\r\n }\r\n\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const url = `${this.baseUrl}/v1/audit${params.toString() ? `?${params.toString()}` : \"\"}`;\r\n const res = await fetch(url, {\r\n method: \"GET\",\r\n headers,\r\n signal: ctrl.signal,\r\n });\r\n \r\n const data = await this.parseResponse<{\r\n events: AuditEvent[];\r\n count: number;\r\n limit: number;\r\n cursor: number;\r\n next_cursor: number;\r\n }>(res);\r\n\r\n return {\r\n events: data.events,\r\n count: data.count,\r\n limit: data.limit,\r\n cursor: data.cursor,\r\n nextCursor: data.next_cursor,\r\n };\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n // ── HTTP helpers ───────────────────────────────────────────────────────────\r\n\r\n private headers(): Record<string, string> {\r\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\r\n if (this.apiKey) {\r\n h[\"Authorization\"] = `Bearer ${this.apiKey}`;\r\n }\r\n return h;\r\n }\r\n\r\n private async post<T>(path: string, body: unknown): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"POST\",\r\n headers: this.headers(),\r\n body: JSON.stringify(body),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async delete<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"DELETE\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async get<T>(path: string): Promise<T> {\r\n const ctrl = new AbortController();\r\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\r\n try {\r\n const res = await fetch(`${this.baseUrl}${path}`, {\r\n method: \"GET\",\r\n headers: this.headers(),\r\n signal: ctrl.signal,\r\n });\r\n return this.parseResponse<T>(res);\r\n } finally {\r\n clearTimeout(timer);\r\n }\r\n }\r\n\r\n private async parseResponse<T>(res: Response): Promise<T> {\r\n const json = (await res.json()) as Record<string, unknown>;\r\n if (!res.ok) {\r\n throw new AuthEngineError(\r\n (json[\"error\"] as string) ?? \"engine error\",\r\n res.status,\r\n json\r\n );\r\n }\r\n return json as T;\r\n }\r\n}\r\n","import type { Request, Response, NextFunction, RequestHandler } from \"express\";\r\nimport { LeluClient } from \"../client\";\r\n\r\nexport interface AuthorizeOptions {\r\n /** Base URL of the Lelu engine (default: http://localhost:8080) */\r\n baseUrl?: string;\r\n /** API key for the Lelu engine */\r\n apiKey?: string;\r\n /** HTTP header that carries the actor identifier (default: x-actor) */\r\n actorHeader?: string;\r\n /** Confidence score to pass to the engine (default: 1.0) */\r\n confidence?: number;\r\n /** Explicit LeluClient instance (overrides baseUrl/apiKey) */\r\n client?: LeluClient;\r\n}\r\n\r\n/**\r\n * Express middleware factory that calls the Lelu engine and either calls\r\n * `next()` (allowed) or returns a 403 JSON response (denied / human_review).\r\n *\r\n * ```ts\r\n * import express from \"express\";\r\n * import { authorize } from \"@lelu/sdk/express\";\r\n *\r\n * const app = express();\r\n * app.get(\"/sensitive\", authorize(\"files.read\", { confidence: 0.9 }), handler);\r\n * ```\r\n */\r\nexport function authorize(action: string, opts: AuthorizeOptions = {}): RequestHandler {\r\n const clientConfig: any = {\r\n baseUrl: opts.baseUrl ?? process.env[\"LELU_BASE_URL\"] ?? \"http://localhost:8080\",\r\n };\r\n const apiKey = opts.apiKey ?? process.env[\"LELU_API_KEY\"];\r\n if (apiKey !== undefined) {\r\n clientConfig.apiKey = apiKey;\r\n }\r\n const client = opts.client ?? new LeluClient(clientConfig);\r\n\r\n const actorHeader = opts.actorHeader ?? \"x-actor\";\r\n const confidence = opts.confidence ?? 1.0;\r\n\r\n return async function leluAuthorize(\r\n req: Request,\r\n res: Response,\r\n next: NextFunction\r\n ): Promise<void> {\r\n const actor = (req.headers[actorHeader] as string | undefined) ?? \"anonymous\";\r\n\r\n try {\r\n const decision = await client.agentAuthorize({ actor, action, context: { confidence } });\r\n\r\n if (decision.allowed) {\r\n // Attach decision to request for downstream handlers\r\n (req as Request & { leluDecision: typeof decision }).leluDecision = decision;\r\n next();\r\n return;\r\n }\r\n\r\n res.status(403).json({\r\n error: \"forbidden\",\r\n decision: decision.allowed,\r\n reason: decision.reason ?? \"denied by policy\",\r\n actor,\r\n action,\r\n });\r\n } catch (err) {\r\n res.status(503).json({\r\n error: \"lelu_unavailable\",\r\n message: err instanceof Error ? err.message : String(err),\r\n });\r\n }\r\n };\r\n}\r\n"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LeluClient, C as ClientConfig } from './client-DL75VVER.mjs';
2
- export { A as AgentAuthDecision, a as AgentAuthRequest, b as AgentAuthRequestSchema, c as AgentContext, d as AgentContextSchema, e as AuthDecision, f as AuthEngineError, g as AuthRequest, h as AuthRequestSchema, D as DelegateScopeRequest, i as DelegateScopeRequestSchema, j as DelegateScopeResult, M as MintTokenRequest, k as MintTokenRequestSchema, l as MintTokenResult, R as RevokeTokenResult } from './client-DL75VVER.mjs';
1
+ import { L as LeluClient, C as ClientConfig } from './client-DY93sy4F.mjs';
2
+ export { A as AgentAuthDecision, a as AgentAuthRequest, b as AgentAuthRequestSchema, c as AgentContext, d as AgentContextSchema, e as AuditEvent, f as AuthDecision, g as AuthEngineError, h as AuthRequest, i as AuthRequestSchema, D as DelegateScopeRequest, j as DelegateScopeRequestSchema, k as DelegateScopeResult, l as ListAuditEventsRequest, m as ListAuditEventsResult, M as MintTokenRequest, n as MintTokenRequestSchema, o as MintTokenResult, R as RevokeTokenResult } from './client-DY93sy4F.mjs';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { L as LeluClient, C as ClientConfig } from './client-DL75VVER.js';
2
- export { A as AgentAuthDecision, a as AgentAuthRequest, b as AgentAuthRequestSchema, c as AgentContext, d as AgentContextSchema, e as AuthDecision, f as AuthEngineError, g as AuthRequest, h as AuthRequestSchema, D as DelegateScopeRequest, i as DelegateScopeRequestSchema, j as DelegateScopeResult, M as MintTokenRequest, k as MintTokenRequestSchema, l as MintTokenResult, R as RevokeTokenResult } from './client-DL75VVER.js';
1
+ import { L as LeluClient, C as ClientConfig } from './client-DY93sy4F.js';
2
+ export { A as AgentAuthDecision, a as AgentAuthRequest, b as AgentAuthRequestSchema, c as AgentContext, d as AgentContextSchema, e as AuditEvent, f as AuthDecision, g as AuthEngineError, h as AuthRequest, i as AuthRequestSchema, D as DelegateScopeRequest, j as DelegateScopeRequestSchema, k as DelegateScopeResult, l as ListAuditEventsRequest, m as ListAuditEventsResult, M as MintTokenRequest, n as MintTokenRequestSchema, o as MintTokenResult, R as RevokeTokenResult } from './client-DY93sy4F.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -225,6 +225,46 @@ var LeluClient = class {
225
225
  return false;
226
226
  }
227
227
  }
228
+ // ── Audit log ──────────────────────────────────────────────────────────────
229
+ /**
230
+ * Lists audit events from the platform API.
231
+ * Requires the platform service to be running (not just the engine).
232
+ */
233
+ async listAuditEvents(req = {}) {
234
+ const params = new URLSearchParams();
235
+ if (req.limit !== void 0) params.set("limit", req.limit.toString());
236
+ if (req.cursor !== void 0) params.set("cursor", req.cursor.toString());
237
+ if (req.actor) params.set("actor", req.actor);
238
+ if (req.action) params.set("action", req.action);
239
+ if (req.decision) params.set("decision", req.decision);
240
+ if (req.traceId) params.set("trace_id", req.traceId);
241
+ if (req.from) params.set("from", req.from);
242
+ if (req.to) params.set("to", req.to);
243
+ const headers = this.headers();
244
+ if (req.tenantId) {
245
+ headers["X-Tenant-ID"] = req.tenantId;
246
+ }
247
+ const ctrl = new AbortController();
248
+ const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
249
+ try {
250
+ const url = `${this.baseUrl}/v1/audit${params.toString() ? `?${params.toString()}` : ""}`;
251
+ const res = await fetch(url, {
252
+ method: "GET",
253
+ headers,
254
+ signal: ctrl.signal
255
+ });
256
+ const data = await this.parseResponse(res);
257
+ return {
258
+ events: data.events,
259
+ count: data.count,
260
+ limit: data.limit,
261
+ cursor: data.cursor,
262
+ nextCursor: data.next_cursor
263
+ };
264
+ } finally {
265
+ clearTimeout(timer);
266
+ }
267
+ }
228
268
  // ── HTTP helpers ───────────────────────────────────────────────────────────
229
269
  headers() {
230
270
  const h = { "Content-Type": "application/json" };