/** * Permission policies: what an agent's tools may do, decided per call from what each call declares. * * Danger belongs to what a tool does, not to its name. A tool declares capabilities — a path it * writes, a host it calls, a command it runs — and a policy grants filesystem paths, network hosts, * and shell commands, and decides every call: allow it, deny it, or ask a person first. A call is * denied when any of its capabilities is, asked about when any needs approval, and allowed only when * every one is granted. */ import type { Principal } from '../types/principal.js'; export { capabilitiesOf, isSensitiveCapability, type ParsedCapability, parseCapability } from './capabilities.js'; /** What a policy decides for one call: run it, refuse it, or interrupt for a person's approval. */ export type PermissionDecision = 'allow' | 'ask' | 'deny'; /** One tool call, as a policy sees it. */ export interface PermissionRequest { /** The tool's name. */ tool: string; /** The call's arguments. */ args: Record; /** What the call declares it does, or `undefined` when the tool declares nothing. */ capabilities: readonly string[] | undefined; /** Who the run is for, when it has a principal, so a policy of your own can decide by role or scope. */ principal?: Readonly; } /** A policy's decision, with the reason a person or a model reads. */ export interface PermissionVerdict { /** The decision. */ decision: PermissionDecision; /** Why, naming the capability that decided it. */ reason: string; /** The capability that decided it, when one did. */ capability?: string; } /** Anything that decides tool calls. `createAgent({ permissions })` takes one. */ export interface PermissionPolicyLike { /** Decides one call. */ decide(request: PermissionRequest): PermissionVerdict | Promise; } /** What a policy grants. Anything not granted is denied unless `ungranted` says otherwise. */ export interface PermissionRules { /** * Paths a tool may read and write, as globs: `*` within one path segment, `**` across segments, so * `/workspace/**` is the workspace and everything in it. A write grant also allows reading. */ filesystem?: { read?: readonly string[]; write?: readonly string[]; }; /** Hosts a tool may reach: `api.github.com`, `*.openai.com` for its subdomains, or `*` for any. */ network?: { allow?: readonly string[]; }; /** * Commands a tool may run, each the start of a command line: `git` allows every git command, and * `npm test` only that. A command line that chains, pipes, redirects, or substitutes is never * granted by these, only by `*`. */ shell?: { allow?: readonly string[]; }; /** Running code a tool was given. Defaults to `deny`; a sandboxed interpreter is the place for `ask` or `allow`. */ code?: PermissionDecision; /** Decisions for the application's own capabilities, by kind or by full capability: `{ payments: 'ask' }`. */ custom?: Readonly>; /** * Capabilities that need a person's approval even when granted, as patterns: `shell`, * `filesystem:write`, `network:*.stripe.com`, `payments`. */ ask?: readonly string[]; /** A tool that declares no capabilities. Defaults to `deny`: a policy cannot judge what it cannot see. */ undeclared?: PermissionDecision; /** A capability no grant covers. Defaults to `deny`. */ ungranted?: 'ask' | 'deny'; /** Decisions per tool name, applied before anything else. */ tools?: Readonly>; /** What a relative path is resolved against. Defaults to `/`. */ root?: string; } /** * Builds a policy from what it grants. * * ```ts * const permissions = permissionPolicy({ * filesystem: { read: ['/workspace/**'], write: ['/workspace/output/**'] }, * network: { allow: ['api.github.com', '*.openai.com'] }, * shell: { allow: ['git', 'npm test'] }, * ask: ['shell', 'filesystem:write'], * }); * const agent = createAgent({ client, tools, permissions, checkpointer }); * ``` */ export declare function permissionPolicy(rules: PermissionRules): PermissionPolicy; /** A policy built from `PermissionRules`. Deterministic: the same call always gets the same decision. */ export declare class PermissionPolicy implements PermissionPolicyLike { /** What the policy grants. */ readonly rules: PermissionRules; constructor( /** What the policy grants. */ rules: PermissionRules); /** Decides one call from its declared capabilities. */ decide(request: PermissionRequest): PermissionVerdict; /** Decides one capability: granted or not, then whether it needs approval. */ decideOne(capability: string): PermissionVerdict; private shown; private root; private granted; } /** * A path made absolute and normalized, with `.` and `..` resolved, so `/workspace/../etc` is * `/etc` before any grant sees it. Backslashes count as separators. `null` for a path that could * never be safe to judge, such as one holding a NUL. */ export declare function normalizePath(path: string, root?: string): string | null;