Skip to content

Repository files navigation

agent-policy-engine

Safety guardrails for tool-using AI agents. Evaluate every tool call as allow / deny / quarantine — with spend limits, allowlists, command-safety checks, path protection, rate limits, and prompt-injection defense via authority levels. Zero runtime dependencies, pure TypeScript, works with any agent framework (LangChain, the Vercel AI SDK, the Anthropic/OpenAI SDKs, or your own loop).

Node TypeScript Zero deps License

A policy engine and safety guardrails for tool-using AI agents — evaluate every tool call as allow / deny / quarantine with spend limits, allowlists, command-safety, path protection, rate limits, and authority levels.

Why

Autonomous, tool-using LLM agents can spend real money, run shell commands, modify their own files, and act on untrusted input. A single prompt injection or a runaway loop can drain a treasury or wreck a machine. agent-policy-engine puts a deterministic checkpoint in front of every tool call:

  • Three outcomes, not two. Each call resolves to allow, deny, or quarantine (needs human confirmation) — so high-value actions can pause instead of being silently blocked or blindly executed.
  • Spend limits. Per-transfer caps, hourly/daily rolling windows, per-turn transfer counts, and inference budgets stop iterative credit drain.
  • Allowlists. x402 / payment domains must be explicitly allowlisted; an empty allowlist disables payments entirely (deny-by-default).
  • Command safety. Shell-metacharacter injection detection plus a forbidden-command pattern list (self-destruction, credential harvesting, DB destruction).
  • Path protection. Deny writes to protected files, reads of secrets (wallets, .env, keys), and path-traversal escapes.
  • Prompt-injection defense via authority levels. Input from untrusted/external sources is derived to a lower authority and blocked from destructive tools and protected-file self-modification.
  • First-deny-wins. Rules are priority-ordered; the first deny stops evaluation, so a cheap validation check short-circuits before an expensive one.

Install

npm i github:Princeu3/agent-policy-engine

npm registry release coming soon. (Until then, install straight from GitHub.)

Quick start

import {
  PolicyEngine,
  createDefaultRules,
  SpendTracker,
} from "agent-policy-engine";

// Build an engine with the batteries-included rule set.
const engine = new PolicyEngine(createDefaultRules());
const sessionSpend = new SpendTracker(); // in-memory by default

// Evaluate a tool call BEFORE you execute it.
const decision = engine.evaluate({
  tool: { name: "transfer_credits", category: "financial", riskLevel: "dangerous" },
  args: { to_address: "0x1234567890123456789012345678901234567890", amount_cents: 6000 },
  turnContext: {
    inputSource: "agent",       // where this turn's input came from
    turnToolCallCount: 0,
    sessionSpend,
  },
});

if (decision.action === "deny") {
  throw new Error(`${decision.reasonCode}: ${decision.humanMessage}`);
} else if (decision.action === "quarantine") {
  // pause for human confirmation
} else {
  // allow: execute the tool, then record the spend
  sessionSpend.recordSpend({ toolName: "transfer_credits", amountCents: 6000, category: "transfer" });
}

Tune the limits with a custom treasury policy:

import { createDefaultRules, DEFAULT_TREASURY_POLICY } from "agent-policy-engine";

const rules = createDefaultRules({
  ...DEFAULT_TREASURY_POLICY,
  maxSingleTransferCents: 2000,
  x402AllowedDomains: ["api.example.com"],
});

API

new PolicyEngine(rules, store?)

  • rules: PolicyRule[] — evaluated in ascending priority.
  • store?: PolicyStore — optional sink for decision audit rows (recordDecision(row)). Defaults to a no-op, so the engine runs with zero wiring. Inject your own to persist to a DB.

engine.evaluate(request): PolicyDecision

Runs applicable rules in priority order. First deny wins and stops evaluation. A quarantine is remembered but does not stop other rules (a later deny can still override it). Returns the overall action, reasonCode, humanMessage, derived authorityLevel, a SHA-256 argsHash, and the lists of rules evaluated/triggered.

engine.logDecision(decision, turnId?)

Persists a decision via the injected store. Never throws — logging failures can't block tool execution.

PolicyEngine.deriveAuthorityLevel(inputSource)

heartbeat / undefinedexternal; creator / agentagent; system / wakeupsystem. External input is the low-trust bucket used by the authority rules.

createDefaultRules(treasuryPolicy?)

Returns the full bundled rule set: validation, command-safety, path-protection, financial, authority, and rate-limit rules. Each factory (createValidationRules, createCommandSafetyRules, createPathProtectionRules, createFinancialRules, createAuthorityRules, createRateLimitRules) is also exported so you can compose your own set.

new SpendTracker(store?) / InMemorySpendStore

Hourly/daily window spend aggregation used by the financial rules. InMemorySpendStore is the default; implement SpendStore to back it with a real database. checkLimit(amount, category, policy) returns whether an amount fits the hourly and daily caps.

Rate limits (optional wiring)

Rate-limit rules count recent allowed decisions via the optional PolicyContext.recentDecisionCount(toolName, windowMs) hook on the request. Wire it to your decision store to activate; when absent, rate-limit rules stay inactive rather than failing closed.

Helper predicates are also exported: isForbiddenCommand, getForbiddenCommandMatch, isProtectedFile, isSensitiveFile, DEFAULT_PROTECTED_FILES, and DEFAULT_TREASURY_POLICY.

Attribution

Extracted, refactored, and decoupled by Prince Upadhyay (@Princeu3) from the MIT-licensed Conway-Research/automaton project. The extraction removes project-specific coupling (Conway APIs, SQLite schema, internal types) and re-packages the reusable guardrail logic as a standalone, zero-dependency library. See NOTICE for details.

Keywords

ai-agents · llm-agents · guardrails · policy-engine · tool-use · agent-safety · spend-limits · prompt-injection · authorization · allowlist · rate-limiting · autonomous-agents · agent-security · typescript · llm

License

MIT © 2026 Prince Upadhyay

About

A policy engine and safety guardrails for tool-using AI agents — evaluate every tool call as allow / deny / quarantine with spend limits, allowlists, command-safety, path protection, rate limits, and authority levels.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages