@intentgate-app/intentgate 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +160 -0
- package/dist/index.cjs +661 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +537 -0
- package/dist/index.d.ts +537 -0
- package/dist/index.js +612 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/capability.ts","../src/memory.ts"],"sourcesContent":["/**\n * Exception hierarchy for the IntentGate SDK.\n *\n * Every gateway response that isn't a clean allow becomes a typed\n * Error. The hierarchy lets callers catch broadly (`catch (e) { if\n * (e instanceof IntentGateError) ... }`) or narrowly (`if (e instanceof\n * CapabilityError) ...`) depending on whether they want to distinguish\n * which check fired.\n *\n * Stage codes are stable across gateway versions:\n *\n * CapabilityError -32010\n * IntentError -32011\n * PolicyError -32012\n * BudgetError -32013\n * ProvenanceError -32014 (opt-in, AAI03 memory-poisoning defense)\n *\n * Anything else (parse errors, method not found, internal errors) is\n * a `ProtocolError`. Network and HTTP transport failures (timeouts,\n * connection refused, non-JSON responses) are `GatewayError` —\n * distinguish \"the gateway is unreachable\" from \"the gateway said no\".\n */\n\nexport class IntentGateError extends Error {\n /** JSON-RPC error code from the gateway, or 0 if client-side. */\n readonly code: number;\n\n /** Optional structured payload from the gateway's `error.data`. */\n readonly data: unknown;\n\n constructor(message: string, opts: { code?: number; data?: unknown; cause?: unknown } = {}) {\n super(message, { cause: opts.cause });\n // Each subclass overrides this in its own constructor; keep the\n // base default predictable for callers that introspect.\n this.name = \"IntentGateError\";\n this.code = opts.code ?? 0;\n this.data = opts.data;\n\n // Preserve the prototype chain across the down-leveled super()\n // call (the well-known TypeScript-when-targeting-ES5 footgun).\n // Targeting ES2022 makes this technically unnecessary, but the\n // explicit setPrototypeOf is a one-line insurance policy that\n // costs nothing and stops `instanceof` from breaking on older\n // bundlers that re-emit class syntax.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * Human-friendly string. When `data` is a string, it usually carries\n * the operator-facing reason (e.g. the Rego rule's explanation), so\n * we surface it on `toString`.\n */\n override toString(): string {\n if (typeof this.data === \"string\" && this.data.length > 0) {\n return `${this.message}: ${this.data}`;\n }\n return this.message;\n }\n}\n\n/** Network or transport failure reaching the gateway. */\nexport class GatewayError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"GatewayError\";\n }\n}\n\n/** JSON-RPC error not in the four stage-specific codes. */\nexport class ProtocolError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"ProtocolError\";\n }\n}\n\n/** Capability stage denied: token signature, expiry, agent lock, etc. */\nexport class CapabilityError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"CapabilityError\";\n }\n}\n\n/** Intent stage denied: requested tool isn't in the extracted intent. */\nexport class IntentError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"IntentError\";\n }\n}\n\n/** Policy stage denied: a Rego rule fired. */\nexport class PolicyError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"PolicyError\";\n }\n}\n\n/** Budget stage denied: max-calls caveat exhausted. */\nexport class BudgetError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"BudgetError\";\n }\n}\n\n/**\n * Provenance stage denied: the opt-in AAI03 memory-poisoning defense\n * rejected the call. Raised when the X-Intent-Memory-Provenance header\n * carries an entry whose HMAC does not verify, whose prev_hash chain\n * is broken, or whose envelope is structurally malformed.\n *\n * JSON-RPC code -32014. Only emitted by gateways with provenance\n * enabled (INTENTGATE_PROVENANCE_ENABLED=true); not raised against\n * the default four-check pipeline.\n */\nexport class ProvenanceError extends IntentGateError {\n constructor(message: string, opts?: { code?: number; data?: unknown; cause?: unknown }) {\n super(message, opts);\n this.name = \"ProvenanceError\";\n }\n}\n\nconst CODE_TO_CLASS: Record<number, typeof IntentGateError> = {\n [-32010]: CapabilityError,\n [-32011]: IntentError,\n [-32012]: PolicyError,\n [-32013]: BudgetError,\n [-32014]: ProvenanceError,\n};\n\n/**\n * Pick the typed exception class for a JSON-RPC error code. Codes in\n * the stage range produce the matching stage class; anything else\n * (parse, invalid request, method not found, internal error,\n * out-of-range custom codes) maps to ProtocolError.\n */\nexport function forCode(code: number): typeof IntentGateError {\n return CODE_TO_CLASS[code] ?? ProtocolError;\n}\n","/**\n * HTTP client for the IntentGate gateway.\n *\n * The {@link Gateway} class wraps the JSON-RPC envelope, the\n * Authorization header, and the X-Intent-Prompt header so callers\n * invoke `gw.toolCall(...)` like any other method and have errors\n * materialize as typed exceptions.\n *\n * Zero runtime deps: uses Node 18+'s native `fetch`. If you need to\n * run on older Node or in an environment without fetch, supply your\n * own fetch-shaped function via the `fetch` constructor option.\n */\n\nimport {\n BudgetError,\n CapabilityError,\n GatewayError,\n IntentError,\n IntentGateError,\n PolicyError,\n ProtocolError,\n forCode,\n} from \"./errors.js\";\n\nconst TOOLS_CALL_METHOD = \"tools/call\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/** One piece of the tool's response, in MCP shape. */\nexport interface ContentBlock {\n type: string;\n text?: string;\n}\n\n/**\n * Per-call gateway decision metadata, lifted from the `_intentgate`\n * vendor extension on the JSON-RPC result. Always present on a\n * successful tool_call; the gateway populates it on every allow.\n */\nexport interface IntentGateMetadata {\n decision: string;\n reason: string;\n check: string;\n latencyMs: number;\n}\n\n/** Successful tool-call response. */\nexport interface ToolCallResult {\n content: ContentBlock[];\n /** Tool's own `isError` flag — distinct from gateway transport errors. */\n isError: boolean;\n intentgate: IntentGateMetadata | null;\n}\n\nexport interface ToolCallOptions {\n /** Tool arguments. The gateway logs only the keys, never the values. */\n arguments?: Record<string, unknown>;\n\n /**\n * The user's original prompt. Sent in `X-Intent-Prompt`; the gateway\n * feeds it to the intent extractor and verifies the requested tool\n * is consistent with the extracted intent. Optional, but strongly\n * recommended in production — without it the intent check is\n * skipped (or denies in strict mode).\n */\n intentPrompt?: string;\n\n /**\n * JSON-RPC request id. When unset, the Gateway uses a sequential\n * per-instance counter — fine for most agents.\n */\n requestId?: number | string;\n\n /**\n * Optional list of memory entry IDs that influenced this tool call.\n * When supplied together with `memoryStore`, the SDK looks up the\n * corresponding signed envelopes and packs them into the\n * `X-Intent-Memory-Provenance` header. The gateway re-derives the\n * session signing key from the capability token's jti, verifies\n * each HMAC, and walks the chain — closing the sophisticated AAI03\n * (Memory Poisoning) case. Used only when the gateway has\n * provenance enabled; otherwise the header is ignored. See\n * `MemoryStore`.\n */\n memoryProvenance?: readonly string[];\n\n /**\n * MemoryStore instance the SDK queries for the envelopes named in\n * `memoryProvenance`. Required iff `memoryProvenance` is non-empty.\n */\n memoryStore?: import(\"./memory.js\").MemoryStore;\n}\n\nexport interface GatewayOptions {\n /**\n * Capability token from `igctl mint` or your tenant's mint service.\n * When omitted, no Authorization header is sent and the gateway\n * will reject with CapabilityError if it's in strict mode.\n */\n token?: string;\n\n /** Per-request timeout in milliseconds. Default 10s. */\n timeoutMs?: number;\n\n /**\n * Pluggable fetch implementation. Defaults to the global\n * `fetch` (Node 18+, browsers, and most modern runtimes). Useful\n * for test injection, custom transports, or shared connection\n * pooling.\n */\n fetch?: typeof fetch;\n}\n\n/**\n * Thin client for the IntentGate gateway.\n *\n * @example\n * ```ts\n * import { Gateway } from \"@intentgate-app/intentgate\";\n *\n * const gw = new Gateway(\"http://localhost:8080\", {\n * token: process.env.INTENTGATE_TOKEN,\n * });\n * const result = await gw.toolCall(\"read_invoice\", {\n * arguments: { id: \"123\" },\n * intentPrompt: \"Process today's AP invoices\",\n * });\n * ```\n */\nexport class Gateway {\n private readonly url: string;\n private readonly token: string | undefined;\n private readonly timeoutMs: number;\n private readonly fetchImpl: typeof fetch;\n private nextId = 1;\n\n constructor(url: string, opts: GatewayOptions = {}) {\n if (!url) {\n throw new Error(\"Gateway: url is required\");\n }\n // Trailing-slash tolerant; we always append explicit paths.\n // Loop instead of regex (`url.replace(/\\/+$/, \"\")`) so we silence\n // CodeQL's polynomial-regex-on-uncontrolled-data warning. The\n // regex wasn't actually exploitable here (anchored, single-char\n // class, no backtracking), but a plain loop has no ReDoS class\n // at all.\n let cleaned = url;\n while (cleaned.endsWith(\"/\")) cleaned = cleaned.slice(0, -1);\n this.url = cleaned;\n this.token = opts.token;\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!this.fetchImpl) {\n throw new Error(\n \"Gateway: no fetch available; pass `fetch` in options or run on Node 18+\",\n );\n }\n }\n\n /**\n * Invoke a tool through the gateway.\n *\n * Resolves with a {@link ToolCallResult} for an allowed call. Throws\n * one of the typed errors (CapabilityError / IntentError /\n * PolicyError / BudgetError / ProtocolError / GatewayError) when\n * the gateway denies, the request fails to reach the gateway, or\n * the response isn't well-formed JSON-RPC.\n */\n async toolCall(tool: string, opts: ToolCallOptions = {}): Promise<ToolCallResult> {\n if (!tool) {\n throw new Error(\"toolCall: tool is required\");\n }\n\n const id = opts.requestId ?? this.nextId++;\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: TOOLS_CALL_METHOD,\n params: {\n name: tool,\n arguments: opts.arguments ?? {},\n },\n });\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.token) {\n headers[\"Authorization\"] = `Bearer ${this.token}`;\n }\n if (opts.intentPrompt) {\n headers[\"X-Intent-Prompt\"] = opts.intentPrompt;\n }\n if (opts.memoryProvenance && opts.memoryProvenance.length > 0) {\n if (!opts.memoryStore) {\n throw new Error(\n \"toolCall: memoryProvenance is non-empty but memoryStore is undefined; \" +\n \"supply a MemoryStore so the SDK can look up the envelopes\",\n );\n }\n // Look up envelopes (verifies each locally), serialize the\n // wire entries, then base64url-encode the JSON array. Matches\n // the gateway's parser shape in\n // gateway/internal/handlers/mcp_provenance.go.\n const wireEntries = opts.memoryStore.provenanceFor(opts.memoryProvenance);\n headers[\"X-Intent-Memory-Provenance\"] = Buffer.from(JSON.stringify(wireEntries)).toString(\n \"base64url\",\n );\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let resp: Response;\n try {\n resp = await this.fetchImpl(`${this.url}/v1/mcp`, {\n method: \"POST\",\n body,\n headers,\n signal: controller.signal,\n });\n } catch (cause) {\n // AbortError surfaces as a DOMException in browsers and a\n // plain Error in Node; either way `name === \"AbortError\"`.\n const isAbort = cause instanceof Error && cause.name === \"AbortError\";\n const msg = isAbort\n ? `gateway timed out after ${this.timeoutMs}ms`\n : `transport error reaching gateway: ${stringifyCause(cause)}`;\n throw new GatewayError(msg, { cause });\n } finally {\n clearTimeout(timer);\n }\n\n if (!resp.ok) {\n const text = await safeText(resp);\n throw new GatewayError(`gateway returned HTTP ${resp.status}`, {\n data: text || resp.statusText,\n });\n }\n\n let payload: unknown;\n try {\n payload = await resp.json();\n } catch (cause) {\n throw new GatewayError(\"non-JSON response from gateway\", { cause });\n }\n\n return parseResponse(payload);\n }\n}\n\nfunction stringifyCause(cause: unknown): string {\n if (cause instanceof Error) return cause.message;\n return String(cause);\n}\n\nasync function safeText(resp: Response): Promise<string> {\n try {\n const t = await resp.text();\n return t.slice(0, 500);\n } catch {\n return \"\";\n }\n}\n\nfunction parseResponse(payload: unknown): ToolCallResult {\n if (!isObject(payload)) {\n throw new ProtocolError(\"response is not a JSON object\");\n }\n\n // Error branch: surface as the typed stage exception.\n const err = payload[\"error\"];\n if (err != null) {\n if (!isObject(err)) {\n throw new ProtocolError(\"error field is not an object\");\n }\n const code = typeof err[\"code\"] === \"number\" ? err[\"code\"] : 0;\n const message = typeof err[\"message\"] === \"string\" ? err[\"message\"] : \"gateway error\";\n const data = err[\"data\"];\n const Cls = forCode(code) as new (\n message: string,\n opts?: { code?: number; data?: unknown },\n ) => IntentGateError;\n throw new Cls(message, { code, data });\n // (Cls is one of CapabilityError | IntentError | PolicyError |\n // BudgetError | ProtocolError; the union is collapsed in the\n // type system because forCode returns the base type, but every\n // member shares the same constructor signature.)\n }\n\n const result = payload[\"result\"];\n if (!isObject(result)) {\n throw new ProtocolError(\"response missing 'result' object\", { data: payload });\n }\n\n const rawContent = Array.isArray(result[\"content\"]) ? result[\"content\"] : [];\n const content: ContentBlock[] = [];\n for (const b of rawContent) {\n if (!isObject(b)) continue;\n content.push({\n type: typeof b[\"type\"] === \"string\" ? b[\"type\"] : \"\",\n text: typeof b[\"text\"] === \"string\" ? b[\"text\"] : undefined,\n });\n }\n\n let intentgate: IntentGateMetadata | null = null;\n const ig = result[\"_intentgate\"];\n if (isObject(ig)) {\n intentgate = {\n decision: typeof ig[\"decision\"] === \"string\" ? ig[\"decision\"] : \"\",\n reason: typeof ig[\"reason\"] === \"string\" ? ig[\"reason\"] : \"\",\n check: typeof ig[\"check\"] === \"string\" ? ig[\"check\"] : \"\",\n latencyMs: typeof ig[\"latency_ms\"] === \"number\" ? ig[\"latency_ms\"] : 0,\n };\n }\n\n return {\n content,\n isError: result[\"isError\"] === true,\n intentgate,\n };\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\n// Re-export the error classes here too so a consumer that only\n// imports from \"./client\" still gets the typed catch surface they\n// need. The package's index.ts is the canonical entry point and\n// re-exports these as well.\nexport {\n BudgetError,\n CapabilityError,\n GatewayError,\n IntentError,\n IntentGateError,\n PolicyError,\n ProtocolError,\n};\n","/**\n * Pure-TypeScript capability-token helpers.\n *\n * The IntentGate gateway issues capability tokens with a Macaroons-\n * style chained-HMAC signature: a token holder can derive a strictly\n * more restrictive child token by appending a caveat and HMAC'ing it\n * under the parent's signature **without ever touching the master\n * key**. That is the defining property of capability tokens, and the\n * reason this module ships in the SDK.\n *\n * Use case. A parent agent receives a token allowing tools `[a, b,\n * c]`, spawns a sub-agent for one task, and wants the sub-agent's\n * token to allow only `[a]`. The parent calls {@link attenuate} and\n * hands the resulting token string to the sub-agent. The gateway\n * (which has the master key) accepts the attenuated token and rejects\n * any sub-agent call that would have needed `b` or `c`.\n *\n * What we don't do here:\n *\n * - **No master key access.** By design — that's what makes\n * attenuation safe. To mint a brand-new root token, use the\n * gateway's `POST /v1/admin/mint` endpoint, not this module.\n * - **No semantic narrowing check.** Adding a \"broader\" caveat\n * doesn't widen the chain because the parent's narrower caveat\n * fires first on the gateway side. We don't second-guess the\n * caller; policy belongs in the gateway, not the SDK.\n *\n * # Wire format\n *\n * We mirror the Go gateway's serialization byte-for-byte on the one\n * place it matters: the new caveat's canonical JSON, which seeds the\n * HMAC step. Anywhere else, JSON ordering doesn't affect correctness\n * because the gateway re-marshals from its parsed Go struct during\n * `Verify`. Every implementation in this package matches the Python\n * SDK byte-for-byte against the same fixtures, so a token attenuated\n * by either SDK verifies on the same gateway.\n */\n\nimport { createHmac } from \"node:crypto\";\n\n/**\n * Caveat-type identifiers, kept in sync with the Go consts in\n * gateway/internal/capability/token.go.\n */\nexport const CaveatType = {\n EXPIRY: \"exp\",\n TOOL_ALLOW: \"tool_allow\",\n TOOL_DENY: \"tool_deny\",\n AGENT_LOCK: \"agent_lock\",\n MAX_CALLS: \"max_calls\",\n} as const;\n\n/**\n * A structured restriction recorded in a token's chain. Only fields\n * relevant to the {@link type} are emitted; the rest are omitted from\n * the JSON output (matching Go's `omitempty` tags).\n *\n * Field order on the wire: `t, tools, agent, exp, max_calls`. This\n * matches Go's encoding/json declaration-order behavior and seeds\n * the HMAC step that derives the child's signature.\n */\nexport interface Caveat {\n type: string;\n tools?: string[];\n agent?: string;\n /** Unix seconds. */\n expiry?: number;\n maxCalls?: number;\n}\n\nexport class AttenuationError extends Error {\n constructor(message: string, opts?: { cause?: unknown }) {\n super(message, { cause: opts?.cause });\n this.name = \"AttenuationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// ---- base64url ---------------------------------------------------\n\n/** Decode an unpadded RawURLEncoding (RFC 4648 §5) base64url string. */\nfunction b64urlDecode(s: string): Uint8Array {\n // Restore standard alphabet + padding for atob/Buffer.\n const standard = s.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const pad = standard.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (standard.length % 4));\n try {\n return new Uint8Array(Buffer.from(standard + pad, \"base64\"));\n } catch (cause) {\n throw new AttenuationError(`invalid base64url: ${stringifyCause(cause)}`, { cause });\n }\n}\n\n/** Encode bytes as unpadded RawURLEncoding base64url. */\nfunction b64urlEncode(b: Uint8Array): string {\n return Buffer.from(b)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\");\n}\n\n// ---- canonical caveat bytes -------------------------------------\n\n/**\n * The exact byte sequence Go's `encoding/json` produces for a Caveat.\n *\n * **CRITICAL**: this is the input to the HMAC step that derives the\n * child's signature. Mismatch here = gateway rejects the child.\n *\n * Constraints, all matched by Go, Python SDK, and this implementation:\n *\n * - Field order: `t, tools, agent, exp, max_calls`.\n * - No whitespace between separators (`{\"t\":\"x\",\"tools\":[\"a\"]}`).\n * - Empty/zero fields omitted (Go's `json:\",omitempty\"`).\n * - ASCII output: only forbidden characters are escaped, not\n * \"interesting\" ASCII like `<`. Both Go and Node behave this way\n * by default, and the fixture tests assert byte equality across\n * all three implementations.\n *\n * The implementation builds a fresh object with keys inserted in\n * canonical order; ECMA-262 specifies that JSON.stringify on a plain\n * object iterates own string keys in insertion order, so this is\n * deterministic.\n */\nfunction canonicalCaveatBytes(c: Caveat): Uint8Array {\n // Build the on-the-wire object in field order. Skip empty/zero\n // values to match Go's `omitempty`.\n const obj: Record<string, unknown> = {};\n // `t` has no omitempty in Go: always present, even if empty.\n obj[\"t\"] = c.type;\n if (c.tools && c.tools.length > 0) {\n obj[\"tools\"] = [...c.tools];\n }\n if (c.agent) {\n obj[\"agent\"] = c.agent;\n }\n if (c.expiry) {\n obj[\"exp\"] = Math.trunc(c.expiry);\n }\n if (c.maxCalls) {\n obj[\"max_calls\"] = Math.trunc(c.maxCalls);\n }\n // JSON.stringify with no indent argument produces no whitespace —\n // this is the equivalent of Python's `separators=(',', ':')` and\n // matches Go's default Marshal output.\n const json = JSON.stringify(obj);\n return new TextEncoder().encode(json);\n}\n\n// ---- decode / attenuate -----------------------------------------\n\n/**\n * Decode a base64url(JSON) token into its parsed object. No signature\n * check (the gateway does that). Useful for inspecting the chain —\n * `decodeToken(t).cav` lists the caveats bound to the token.\n */\nexport function decodeToken(token: string): Record<string, unknown> {\n const raw = b64urlDecode(token);\n let parsed: unknown;\n try {\n parsed = JSON.parse(new TextDecoder(\"utf-8\", { fatal: true }).decode(raw));\n } catch (cause) {\n throw new AttenuationError(`token JSON is malformed: ${stringifyCause(cause)}`, {\n cause,\n });\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new AttenuationError(\"token JSON is not an object\");\n }\n return parsed as Record<string, unknown>;\n}\n\nexport interface AttenuateOptions {\n /** Narrow to this tool whitelist (caveat type `tool_allow`). */\n addTools?: string[];\n\n /** Add a deny list (caveat type `tool_deny`). Additive on top of any parent deny. */\n denyTools?: string[];\n\n /** Cap remaining calls (caveat type `max_calls`). The chain enforces the minimum. */\n maxCalls?: number;\n\n /** Set absolute expiry (Unix seconds). Caveat type `exp`. */\n expiresAt?: number;\n\n /** Convenience: now + N seconds. Caveat type `exp`. */\n expiresInSeconds?: number;\n\n /** User-supplied caveats appended last (advanced). */\n extra?: Caveat[];\n}\n\n/**\n * Append narrowing caveats to a parent token and return a new token\n * string that the gateway accepts as a cryptographic descendant of\n * the parent.\n *\n * Each option groups one common attenuation pattern. Multiple options\n * combine; each generates one caveat in this order:\n *\n * 1. `addTools` → `tool_allow` caveat\n * 2. `denyTools` → `tool_deny` caveat\n * 3. `maxCalls` → `max_calls` caveat\n * 4. `expiresAt` / → `exp` caveat (absolute Unix seconds)\n * `expiresInSeconds`\n * 5. `extra` → user-supplied caveats appended last\n *\n * @example\n * ```ts\n * import { attenuate } from \"@intentgate-app/intentgate\";\n *\n * // Parent token: agent allowed [search, read, email] for 1h.\n * // Child: only [search, read], one call max.\n * const child = attenuate(parentToken, {\n * addTools: [\"search\", \"read\"],\n * maxCalls: 1,\n * });\n *\n * // Hand `child` to the sub-agent.\n * ```\n */\nexport function attenuate(token: string, opts: AttenuateOptions = {}): string {\n const parsed = decodeToken(token);\n\n if (typeof parsed[\"sig\"] !== \"string\") {\n throw new AttenuationError(\"token is missing 'sig' field\");\n }\n if (!Array.isArray(parsed[\"cav\"])) {\n throw new AttenuationError(\"token is missing 'cav' field\");\n }\n if (typeof parsed[\"root_jti\"] !== \"string\" || parsed[\"root_jti\"] === \"\") {\n throw new AttenuationError(\n \"token has no root_jti (was it minted by gateway < v0.7?)\",\n );\n }\n if (typeof parsed[\"tenant\"] !== \"string\" || parsed[\"tenant\"] === \"\") {\n throw new AttenuationError(\n \"token has no tenant (was it minted by gateway < v0.9?)\",\n );\n }\n\n // Tenant is signed in the chain seed by the gateway and propagates\n // through every HMAC step unchanged — attenuation cannot pivot\n // tenants. We don't re-validate that here because the cryptographic\n // chain enforces it; the explicit check above just gives a friendly\n // error for v0.8 tokens that pre-date the tenant claim.\n\n const cavs: Record<string, unknown>[] = [...(parsed[\"cav\"] as Record<string, unknown>[])];\n let sig = b64urlDecode(parsed[\"sig\"]);\n\n const newCaveats: Caveat[] = [];\n if (opts.addTools && opts.addTools.length > 0) {\n newCaveats.push({ type: CaveatType.TOOL_ALLOW, tools: [...opts.addTools] });\n }\n if (opts.denyTools && opts.denyTools.length > 0) {\n newCaveats.push({ type: CaveatType.TOOL_DENY, tools: [...opts.denyTools] });\n }\n if (opts.maxCalls !== undefined) {\n if (opts.maxCalls < 0) {\n throw new AttenuationError(\"maxCalls must be >= 0\");\n }\n newCaveats.push({ type: CaveatType.MAX_CALLS, maxCalls: Math.trunc(opts.maxCalls) });\n }\n if (opts.expiresAt !== undefined || opts.expiresInSeconds !== undefined) {\n const exp =\n opts.expiresAt ?? Math.floor(Date.now() / 1000) + (opts.expiresInSeconds ?? 0);\n newCaveats.push({ type: CaveatType.EXPIRY, expiry: Math.trunc(exp) });\n }\n if (opts.extra && opts.extra.length > 0) {\n newCaveats.push(...opts.extra);\n }\n\n if (newCaveats.length === 0) {\n throw new AttenuationError(\n \"attenuate() requires at least one narrowing argument \" +\n \"(addTools, denyTools, maxCalls, expiresInSeconds, expiresAt, or extra)\",\n );\n }\n\n // Walk the new caveats forward, hopping the HMAC chain one step\n // per caveat. The Go gateway re-walks the same chain in `Verify`.\n for (const c of newCaveats) {\n const cb = canonicalCaveatBytes(c);\n sig = new Uint8Array(createHmac(\"sha256\", sig).update(cb).digest());\n // Append the same on-the-wire object to the cav array. Use\n // canonicalCaveatBytes' object-build logic to stay consistent\n // with what we just HMAC'd.\n cavs.push(JSON.parse(new TextDecoder().decode(cb)) as Record<string, unknown>);\n }\n\n // Re-encode. Go decodes JSON order-independently during Verify, so\n // any field ordering on the outer envelope is fine — separators\n // only matter for the per-caveat canonical bytes inside the HMAC.\n const child: Record<string, unknown> = { ...parsed };\n child[\"cav\"] = cavs;\n child[\"sig\"] = b64urlEncode(sig);\n return b64urlEncode(new TextEncoder().encode(JSON.stringify(child)));\n}\n\nfunction stringifyCause(cause: unknown): string {\n if (cause instanceof Error) return cause.message;\n return String(cause);\n}\n","/**\n * Memory provenance primitives for the IntentGate TypeScript SDK.\n *\n * This module implements the SDK side of the AAI03 (Memory Poisoning)\n * defense. The agent wraps its memory backend (vector DB, Redis,\n * in-memory dict, anything) with {@link MemoryStore}, which signs\n * every write with an HMAC-SHA256 keyed by a per-session signing key\n * derived (via HKDF) from the capability token. At tool-call time the\n * agent declares which memory entries influenced the call via the\n * `memoryProvenance` parameter on `Gateway.toolCall`; the gateway\n * re-derives the session key and verifies each entry.\n *\n * # Cross-implementation contract\n *\n * The byte encoding of an {@link Envelope} (see {@link canonical})\n * MUST match the Go gateway's `internal/provenance.Canonical`\n * byte-for-byte AND match the Python SDK's `intentgate.memory.canonical`\n * byte-for-byte. The KDF MUST be HKDF-SHA256 with info=\n * `intentgate-memory-v1`. The HMAC MUST be HMAC-SHA256.\n *\n * Drift in any of these contracts means the SDK and the gateway\n * silently disagree on signatures — a class of bug caught by the\n * cross-implementation KAT test in `tests/memory.test.ts`. If you\n * change anything in this file, run that test against the Go gateway's\n * `TestDeriveSessionKey_KnownAnswer` and the Python SDK's\n * `test_hkdf_kat_matches_go_gateway` to confirm the wire contract\n * still holds.\n *\n * # Zero runtime dependencies\n *\n * Uses only `node:crypto` (createHmac, createHash, hkdfSync,\n * timingSafeEqual, randomUUID). No third-party crypto package. The\n * Node 18+ baseline is documented in package.json.\n */\n\nimport { createHmac, createHash, hkdfSync, timingSafeEqual, randomUUID } from \"node:crypto\";\n\n// Version tag baked into the HKDF info parameter. Bumping this forces\n// a key-derivation cutover: old and new keys are computed from the\n// same master + jti but produce different bytes. Future versions\n// could accept multiple labels during a grace window; v1 is the only\n// one defined today.\nconst DERIVATION_INFO = Buffer.from(\"intentgate-memory-v1\");\n\n/** Length of a derived session signing key in bytes. Matches the Go\n * gateway's SessionKeySize and the Python SDK's SESSION_KEY_SIZE. */\nexport const SESSION_KEY_SIZE = 32;\n\n/** Length of SHA-256 / HMAC-SHA256 output in bytes. */\nconst HASH_SIZE = 32;\n\n/** The conventional PrevHash value for the first entry in a session.\n * Named so the special-case is obvious at the call site. */\nexport const ZERO_HASH: Buffer = Buffer.alloc(HASH_SIZE);\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * Raised when the SDK cannot produce or verify a memory envelope.\n * Distinct from the gateway-side `ProvenanceError` in `errors.ts`\n * (which is raised by `Gateway.toolCall` when the gateway rejected\n * the provenance check). This class is for SDK-internal failures —\n * a tampered entry detected at read time, a malformed envelope, etc.\n */\nexport class MemoryProvenanceError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MemoryProvenanceError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// ---------------------------------------------------------------------------\n// HKDF — wraps node:crypto's built-in hkdfSync\n// ---------------------------------------------------------------------------\n\n/**\n * Derive the per-session memory signing key.\n *\n * Matches the gateway's `provenance.DeriveSessionKey` and the Python\n * SDK's `derive_session_key`: HKDF-SHA256 with salt = `sessionId` (as\n * UTF-8 bytes), info = `intentgate-memory-v1`, length = 32.\n *\n * @throws if `masterKey` is empty or `sessionId` is empty.\n */\nexport function deriveSessionKey(masterKey: Buffer | Uint8Array, sessionId: string): Buffer {\n if (!masterKey || masterKey.length === 0) {\n throw new Error(\"deriveSessionKey: masterKey is empty\");\n }\n if (!sessionId) {\n throw new Error(\"deriveSessionKey: sessionId is empty\");\n }\n const out = hkdfSync(\n \"sha256\",\n masterKey,\n Buffer.from(sessionId, \"utf8\"),\n DERIVATION_INFO,\n SESSION_KEY_SIZE,\n );\n // node:crypto returns an ArrayBuffer; wrap as a Node Buffer for\n // ergonomic byte ops downstream (slice, equals, etc.).\n return Buffer.from(out);\n}\n\n// ---------------------------------------------------------------------------\n// Envelope + canonical bytes\n// ---------------------------------------------------------------------------\n\n/** One signed memory entry. Stored opaquely by the customer's memory\n * backend; produced by `MemoryStore.write`; verified by the gateway. */\nexport interface Envelope {\n /** Stable identifier for the entry. */\n id: string;\n /** The capability token's `jti` whose signing key signed this. */\n sessionId: string;\n /** Creation time as Unix milliseconds. */\n timestamp: number;\n /** Application-level payload bytes. */\n data: Buffer;\n /** SHA-256 of the canonical bytes of the previous entry in this\n * session, or ZERO_HASH for the first entry. */\n prevHash: Buffer;\n /** HMAC-SHA256 of canonical(envelope) under the session key. */\n hmac: Buffer;\n}\n\n/**\n * Produce the byte sequence the envelope's HMAC covers.\n *\n * Encoding is a length-prefixed concatenation of the immutable fields\n * in order: sessionId (utf-8), id (utf-8), timestamp (big-endian\n * uint64), prevHash, data. Lengths are big-endian uint32.\n *\n * The encoding is deliberately NOT JSON — same byte sequence the Go\n * gateway produces in `provenance.Canonical` and the Python SDK\n * produces in `canonical`. Cross-verified by the KAT test.\n *\n * The `hmac` field is excluded (a signature cannot cover itself).\n */\nexport function canonical(env: Pick<Envelope, \"id\" | \"sessionId\" | \"timestamp\" | \"data\" | \"prevHash\">): Buffer {\n const sid = Buffer.from(env.sessionId, \"utf8\");\n const eid = Buffer.from(env.id, \"utf8\");\n\n // Total size: 4 + len(sid) + 4 + len(eid) + 8 + 4 + len(prevHash) + 4 + len(data)\n const total = 4 + sid.length + 4 + eid.length + 8 + 4 + env.prevHash.length + 4 + env.data.length;\n const out = Buffer.alloc(total);\n let off = 0;\n\n out.writeUInt32BE(sid.length, off);\n off += 4;\n sid.copy(out, off);\n off += sid.length;\n\n out.writeUInt32BE(eid.length, off);\n off += 4;\n eid.copy(out, off);\n off += eid.length;\n\n // Mirror Go's int64 → uint64 reinterpretation. JS numbers don't\n // safely represent the full int64 range, but Unix milliseconds\n // fit comfortably below Number.MAX_SAFE_INTEGER for ~285,000\n // years past 1970. We use writeBigUInt64BE with BigInt conversion\n // so the encoded bytes match Go's binary.BigEndian.PutUint64\n // regardless of sign.\n out.writeBigUInt64BE(BigInt(env.timestamp) & 0xffffffffffffffffn, off);\n off += 8;\n\n out.writeUInt32BE(env.prevHash.length, off);\n off += 4;\n env.prevHash.copy(out, off);\n off += env.prevHash.length;\n\n out.writeUInt32BE(env.data.length, off);\n off += 4;\n env.data.copy(out, off);\n\n return out;\n}\n\n/**\n * Return a copy of `env` with the `hmac` field populated.\n *\n * Used at memory-write time by `MemoryStore.write` and by tests.\n * Computes `HMAC-SHA256(sessionKey, canonical(env))`.\n *\n * @throws if `sessionKey` is empty.\n */\nexport function sign(sessionKey: Buffer, env: Omit<Envelope, \"hmac\">): Envelope {\n if (!sessionKey || sessionKey.length === 0) {\n throw new Error(\"sign: sessionKey is empty\");\n }\n const mac = createHmac(\"sha256\", sessionKey);\n mac.update(canonical(env));\n return { ...env, hmac: mac.digest() };\n}\n\n/**\n * Check `env.hmac` against `sessionKey`. Returns `undefined` on a\n * valid signature; throws {@link MemoryProvenanceError} otherwise.\n * Comparison uses `timingSafeEqual` — constant-time with respect to\n * signature contents.\n */\nexport function verify(sessionKey: Buffer, env: Envelope): void {\n if (!sessionKey || sessionKey.length === 0) {\n throw new Error(\"verify: sessionKey is empty\");\n }\n if (env.hmac.length !== HASH_SIZE) {\n throw new MemoryProvenanceError(\n `hmac field is ${env.hmac.length} bytes; expected ${HASH_SIZE}`,\n );\n }\n const expected = createHmac(\"sha256\", sessionKey).update(canonical(env)).digest();\n if (!timingSafeEqual(expected, env.hmac)) {\n throw new MemoryProvenanceError(\"hmac mismatch\");\n }\n}\n\n/**\n * Check a list of envelopes as a per-session chain.\n *\n * Each entry's HMAC must verify and each entry's `prevHash` must\n * equal SHA-256 of the canonical bytes of the previous entry. The\n * first entry's `prevHash` must equal {@link ZERO_HASH}.\n *\n * Empty chain is valid (let policy decide whether absence of memory\n * provenance is a deny condition for the tool).\n */\nexport function verifyChain(sessionKey: Buffer, chain: readonly Envelope[]): void {\n if (chain.length === 0) {\n return;\n }\n for (let i = 0; i < chain.length; i++) {\n const env = chain[i];\n if (!env) continue;\n try {\n verify(sessionKey, env);\n } catch (e) {\n if (e instanceof MemoryProvenanceError) {\n throw new MemoryProvenanceError(`entry ${i}: ${e.message}`);\n }\n throw e;\n }\n let expectedPrev: Buffer;\n if (i === 0) {\n expectedPrev = ZERO_HASH;\n } else {\n const prev = chain[i - 1];\n if (!prev) continue;\n expectedPrev = createHash(\"sha256\").update(canonical(prev)).digest();\n }\n if (!timingSafeEqual(expectedPrev, env.prevHash)) {\n throw new MemoryProvenanceError(\n `entry ${i}: prev_hash does not match previous entry's canonical hash`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// MemoryStore — agent-side facade\n// ---------------------------------------------------------------------------\n\n/** Customer-supplied write hook for a backing store. */\nexport type MemoryWriteHook = (entryId: string, env: Envelope) => void;\n\n/** Customer-supplied read hook. Must throw if entry not found. */\nexport type MemoryReadHook = (entryId: string) => Envelope;\n\n/**\n * Sign-on-write, verify-on-read wrapper around a memory backend.\n *\n * The customer plugs their underlying memory store (Pinecone, Redis,\n * pgvector, an in-memory Map, anything) into this wrapper by\n * supplying two callables: a write-hook and a read-hook. The wrapper\n * signs entries on write and verifies them on read, so a tampered\n * entry surfaces immediately at the agent's read site rather than\n * waiting until the gateway rejects the tool call.\n *\n * The default storage backend is an in-memory Map — suitable for SDK\n * tests, demos, and small agents. Production agents pass their real\n * backend's read/write callables.\n */\nexport class MemoryStore {\n private readonly sessionId: string;\n private readonly key: Buffer;\n private readonly fallback = new Map<string, Envelope>();\n private readonly writeHook?: MemoryWriteHook;\n private readonly readHook?: MemoryReadHook;\n private chainHead: Buffer = ZERO_HASH;\n\n /**\n * @param sessionId The `jti` of the capability token this store is bound to.\n * Used as the HKDF salt to derive the signing key.\n * @param memorySigningKey The 32-byte signing key returned by\n * `POST /v1/admin/mint` when `with_memory_signing_key: true`.\n * @param options Optional `writeHook` / `readHook` callables; when\n * absent the wrapper uses an in-memory Map fallback.\n */\n constructor(\n sessionId: string,\n memorySigningKey: Buffer | Uint8Array,\n options: { writeHook?: MemoryWriteHook; readHook?: MemoryReadHook } = {},\n ) {\n if (!sessionId) {\n throw new Error(\"MemoryStore: sessionId is required\");\n }\n if (memorySigningKey.length !== SESSION_KEY_SIZE) {\n throw new Error(\n `MemoryStore: memorySigningKey must be ${SESSION_KEY_SIZE} bytes, got ${memorySigningKey.length}`,\n );\n }\n this.sessionId = sessionId;\n this.key = Buffer.from(memorySigningKey);\n this.writeHook = options.writeHook;\n this.readHook = options.readHook;\n }\n\n /**\n * Sign `data` into a new envelope and store it. Returns the entry\n * ID, which the caller passes to `Gateway.toolCall` via the\n * `memoryProvenance` list.\n *\n * `data` may be a Buffer, a string (utf-8 encoded), or any JSON-\n * serializable value (encoded with sorted keys + no whitespace so\n * equivalent inputs produce identical envelope bytes).\n */\n write(data: Buffer | string | Record<string, unknown> | unknown[]): string {\n let payload: Buffer;\n if (Buffer.isBuffer(data)) {\n payload = data;\n } else if (typeof data === \"string\") {\n payload = Buffer.from(data, \"utf8\");\n } else {\n payload = Buffer.from(stableStringify(data), \"utf8\");\n }\n\n const entryId = randomUUID().replaceAll(\"-\", \"\");\n const env = sign(this.key, {\n id: entryId,\n sessionId: this.sessionId,\n timestamp: Date.now(),\n data: payload,\n prevHash: this.chainHead,\n });\n\n if (this.writeHook !== undefined) {\n this.writeHook(entryId, env);\n } else {\n this.fallback.set(entryId, env);\n }\n\n this.chainHead = createHash(\"sha256\").update(canonical(env)).digest();\n return entryId;\n }\n\n /**\n * Fetch and verify the envelope identified by `entryId`.\n *\n * @throws if the entry is missing (`Error`) or if the HMAC fails\n * ({@link MemoryProvenanceError}, indicating the entry was\n * tampered with after writing).\n */\n read(entryId: string): Envelope {\n let env: Envelope | undefined;\n if (this.readHook !== undefined) {\n env = this.readHook(entryId);\n } else {\n env = this.fallback.get(entryId);\n if (env === undefined) {\n throw new Error(`MemoryStore: entry ${entryId} not found`);\n }\n }\n verify(this.key, env);\n return env;\n }\n\n /**\n * Build the wire-format provenance entries for a tool call. Each\n * entry is verified before inclusion — if any envelope was tampered\n * with at the storage layer, {@link MemoryProvenanceError} is\n * raised here rather than at the gateway.\n *\n * The returned objects use base64url (no padding) encoding for byte\n * fields — same shape the Go gateway parses.\n */\n provenanceFor(entryIds: readonly string[]): Array<{\n id: string;\n session_id: string;\n ts: number;\n data: string;\n prev_hash: string;\n hmac: string;\n }> {\n return entryIds.map((eid) => {\n const env = this.read(eid);\n return {\n id: env.id,\n session_id: env.sessionId,\n ts: env.timestamp,\n data: env.data.toString(\"base64url\"),\n prev_hash: env.prevHash.toString(\"base64url\"),\n hmac: env.hmac.toString(\"base64url\"),\n };\n });\n }\n\n /** Number of entries in the fallback in-memory store. */\n get size(): number {\n return this.fallback.size;\n }\n}\n\n/**\n * Deterministic JSON stringify with sorted keys and no whitespace.\n * Used by MemoryStore.write so two equivalent objects produce\n * byte-identical envelopes. Mirrors Python's\n * `json.dumps(d, sort_keys=True, separators=(\",\", \":\"))`.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== \"object\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return \"[\" + value.map(stableStringify).join(\",\") + \"]\";\n }\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return (\n \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + stableStringify(obj[k])).join(\",\") + \"}\"\n );\n}\n"],"mappings":"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","names":["stringifyCause","createHmac"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@intentgate-app/intentgate",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "TypeScript SDK for the IntentGate authorization gateway. Three lines to wrap any agent's tool call with capability + intent + policy + budget checks. Zero runtime dependencies (uses native fetch and node:crypto).",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "IntentGate contributors",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/IntentGate-app/intentgate-sdk-typescript"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/IntentGate-app/intentgate-sdk-typescript",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/IntentGate-app/intentgate-sdk-typescript/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"intentgate",
|
|
17
|
+
"ai-agents",
|
|
18
|
+
"authorization",
|
|
19
|
+
"mcp",
|
|
20
|
+
"capability-tokens",
|
|
21
|
+
"macaroons",
|
|
22
|
+
"opa",
|
|
23
|
+
"agent-security"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.cjs",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"require": "./dist/index.cjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest",
|
|
48
|
+
"lint": "eslint .",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.0.0",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
55
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
56
|
+
"eslint": "^9.0.0",
|
|
57
|
+
"tsup": "^8.0.0",
|
|
58
|
+
"typescript": "^5.5.0",
|
|
59
|
+
"vitest": "^4.1.7"
|
|
60
|
+
}
|
|
61
|
+
}
|