This guide covers AI agent tool allowlists with production-focused examples and trade-offs.
Coding agents with unrestricted shell access are remote unattended engineers with root-adjacent habits. Default-deny filesystem and command allowlists turn “agent helpfulness” into something you can defend in a security review.⚡ TL;DR: Allowlist write paths (src/**,tests/**) and commands (pnpm test,tsc,git status). Denygit push --force,npm publish,curl|bash, cloud destructive APIs, and reads of.env. Elevation requires a human token. Implement as a policy check before every tool call — see Claude Code Hooks and LLM Coding Agents on AWS: Safe Tool Sandboxes.
Policy object evaluated on every tool call — AI agent tool allowlists
export type ToolRequest =
| { type: "read"; path: string }
| { type: "write"; path: string }
| { type: "shell"; argv: string[] };
const WRITE_ALLOW = [/^src\//, /^tests\//, /^packages\/[^/]+\/src\//];
const READ_DENY = [/^\.env/, /^\.aws\//, /id_rsa$/, /credentials\.json$/];
const SHELL_ALLOW: { bin: string; args?: RegExp }[] = [
{ bin: "pnpm", args: /^(test|lint|typecheck|exec tsc)\b/ },
{ bin: "git", args: /^(status|diff|log|add|commit|checkout -b)\b/ },
{ bin: "rg", args: /.*/ },
];
const SHELL_DENY = [
/push\s+--force/,
/\bpublish\b/,
/curl\s+.*\|\s*(ba)?sh/,
/kubectl\s+delete/,
/aws\s+iam\s+/,
/rm\s+-rf\s+\//,
];
export function authorize(req: ToolRequest): { allow: boolean; reason: string } {
if (req.type === "read") {
if (READ_DENY.some((re) => re.test(req.path))) {
return { allow: false, reason: `read_denied:${req.path}` };
}
return { allow: true, reason: "ok" };
}
if (req.type === "write") {
if (!WRITE_ALLOW.some((re) => re.test(req.path))) {
return { allow: false, reason: `write_not_allowlisted:${req.path}` };
}
return { allow: true, reason: "ok" };
}
const line = req.argv.join(" ");
if (SHELL_DENY.some((re) => re.test(line))) {
return { allow: false, reason: `shell_denied:${line}` };
}
const bin = req.argv[0];
const rest = req.argv.slice(1).join(" ");
const ok = SHELL_ALLOW.some((r) => r.bin === bin && (r.args?.test(rest) ?? true));
return ok ? { allow: true, reason: "ok" } : { allow: false, reason: `shell_not_allowlisted:${line}` };
}
Elevation path for rare exceptions
async function runTool(req: ToolRequest, ctx: { elevationToken?: string }) {
const decision = authorize(req);
if (decision.allow) return execute(req);
if (ctx.elevationToken && await verifyElevation(ctx.elevationToken, req)) {
audit.elevated(req);
return execute(req);
}
throw new Error(`policy_denied:${decision.reason}`);
}
❌ A sticky “YOLO mode” for the whole session.
Filesystem jail in sandboxes
When tools run remotely, combine allowlists with the sandbox patterns from LLM Coding Agents on AWS: ephemeral compute, no long-lived credentials, egress allowlists. Local IDE agents still need the same argv policy — hooks as in Claude Code Hooks.Suggested default denials
| Category | Examples |
|---|---|
| Git | push --force, git filter-branch, rewrite of main |
| Packages | npm publish, twine upload |
| Cloud | aws iam, terraform apply, kubectl delete |
| Supply chain | curl \| bash, unpinned npx from HTTP |
| Secrets | read .env*, *.pem, ~/.aws |
Closing checklist
- [ ] Default-deny shell; explicit allowlist of bins + arg patterns
- [ ] Write allowlist limited to source/test trees
- [ ] Secret paths denied on read
- [ ] Elevation is single-use, fingerprint-scoped, audited
- [ ] CI policy unit tests for deny cases (force-push, publish, curl|sh)
- [ ] Remote sandboxes add egress + credential constraints
Related reading
- Claude Code Hooks: Gate Risky Shell Commands Before CI Runs
- LLM Coding Agents on AWS: Safe Tool Sandboxes with Lambda
- AI Code Review Bots: IAM, Secrets, and Least-Privilege Pipelines
- Bedrock Guardrails: Block Prompt Injection Inside Internal Dev Tools
Related: KMS Decrypt Grants for Agent Tools: Least Privilege Without Env Keys · Day 62: SSRF and Tool Allowlists · Secure AI Sandboxes: Ephemeral ECS Tasks for Agent Tool Execution
Related: AI Coding Agent Tool Schemas: Strict JSON Contracts That Survive Retries · Lambda Destinations: Route Failed Agent Tool Invokes Without Silent Drops · Day 53: Avoiding Agent Ping-Pong
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.

Pingback: Lambda Outbound Proxies: Egress Allowlists That Block SSRF Paths - CheatCoders