/** * Consumer-supplied **deny policy** — the deny-side counterpart to * {@link PermissionGrants}. The TypeScript sibling of the Rust engine's * `deny_policy.rs`. * * The engine ships hardcoded circuit-breakers (`rm -rf /`, `curl | sh`, * credential paths, dangerous domains — see {@link decide}) and an allow-only * grant store that can *upgrade* an `Ask`. Neither can express a consumer's own * "never do this" rules: "never touch the prod AWS profile", "the DB writer * endpoint is off-limits", "no writes under `/prod`". This module adds that tier. * * It is **purely additive**: a {@link PermissionHook} with no deny policy behaves * exactly as before. When a policy *is* attached it is evaluated **first**, and a * match is a hard deny of the same tier as the built-in circuit-breakers — no * stored grant waives it, and {@link AutoMode.Bypass} / {@link AutoMode.AcceptEdits} * cannot downgrade it. * * # Two tiers * * 1. **Declarative** ({@link DenyRules}) — TOML, four sections, each a deny list: * * ```toml * schema_version = 1 * [tools] * deny = ["vendor.dangerous_tool", "*.delete_prod"] * [bash] * deny_patterns = ["aws * --profile prod", "kubectl * --context prod"] * [network] * deny_hosts = ["*.prod.internal", "prod-*.rds.amazonaws.com"] * [paths] * deny = ["/prod/**", "/app/secrets/**"] * ``` * * 2. **Predicate** ({@link DenyPredicate}) — a consumer callback for semantic * checks the engine cannot parse from strings ("is this the prod AWS account?", * "writer vs replica endpoint?"). `Some(reason)` → deny. * * Declarative rules run first, then predicates; the first match wins. */ import type { ToolCall } from './permission.js'; /** The declarative half of a {@link DenyPolicy}: four deny lists parsed from TOML. */ export declare class DenyRules { schemaVersion: number; readonly tools: Set; readonly bashPatterns: Set; readonly networkHosts: Set; readonly paths: Set; /** No rules in any section (used for the additive no-op fast path). */ isEmpty(): boolean; /** Parse from a TOML string. Missing sections default to empty. */ static parse(tomlText: string): DenyRules; /** Serialize to TOML. Empty sections omitted; entries sorted for a stable round-trip. */ toTomlString(): string; /** The first declarative rule this call matches, formatted as a deny reason, or `undefined`. */ denyReason(call: ToolCall): string | undefined; /** First `[bash]` pattern that matches any (wrapper/sudo-stripped) subcommand. */ private bashDenied; /** First `[network]` pattern that matches `host` (case-insensitive). */ private hostDenied; } /** * Minimal both-ends-anchored glob: `*` (and any run of `*`, so `**` too) matches * any sequence of characters, including `/`. No `?`, no char classes — deny globs * don't need them, and a tiny matcher stays auditable for a security-critical path. */ export declare function globMatch(pattern: string, text: string): boolean; /** * A consumer-supplied semantic deny check. Runs on every gated tool call; a * returned reason is a hard deny (circuit-breaker tier). Use it for checks the * declarative rules can't express from strings alone — resolving an AWS call to * its account, a DB URL to writer-vs-replica, etc. * * The idiomatic TS seam: a function returning the deny reason, or `undefined` to * let the call fall through to the rest of the permission engine. */ export type DenyPredicate = (call: ToolCall) => string | undefined; /** * Consumer-supplied deny policy: declarative rules + predicate checks. Attach to * the gate via {@link PermissionHook.withDenyPolicy}. An empty policy is a no-op. */ export declare class DenyPolicy { private declarative; private readonly predicates; constructor(declarative?: DenyRules); /** Build the declarative half from a TOML string. Predicates are added via {@link withPredicate}. */ static fromToml(tomlText: string): DenyPolicy; /** Replace the declarative rules. Chainable. */ withDeclarative(rules: DenyRules): this; /** Add a consumer predicate. Chainable. */ withPredicate(predicate: DenyPredicate): this; /** True when there are no rules and no predicates — nothing to deny. */ isEmpty(): boolean; /** * The deny reason for `call`, or `undefined` to let it fall through. Declarative * rules are checked first, then predicates; the first match wins. */ evaluate(call: ToolCall): string | undefined; } //# sourceMappingURL=denyPolicy.d.ts.map