|
1 | | -<p align="center"> |
2 | | - <img src="public/assets/brand/agentwall-logo-primary.svg" alt="Agentwall" width="360" /> |
3 | | -</p> |
4 | | - |
5 | | -# Agentwall |
6 | | - |
7 | | -**Runtime control for agentic AI.** |
8 | | - |
9 | | -Agentwall sits between AI agents and real-world action surfaces: shell commands, tools, network egress, browser actions, communication channels, identity, and content delivery. |
10 | | - |
11 | | -It answers one question before an agent acts: |
12 | | - |
13 | | -> Should this action be allowed, denied, redacted, or routed to a human? |
14 | | -
|
15 | | -## Why it exists |
16 | | - |
17 | | -Agent prompts are not a security boundary. Agentwall enforces policy at runtime, where the risk becomes real. |
18 | | - |
19 | | -Core principles: |
20 | | - |
21 | | -- Least privilege by default |
22 | | -- Default-deny egress |
23 | | -- Human approval for high-risk actions |
24 | | -- Communication-channel containment |
25 | | -- Static command preflight before shell execution |
26 | | -- Tamper-evident audit trails for operator review |
| 1 | +<p align="center"><img src=".github/assets/logo.jpg" width="120" alt="Agentwall"></p> |
27 | 2 |
|
28 | | -## What ships now |
| 3 | +<h1 align="center">Agentwall</h1> |
29 | 4 |
|
30 | | -- Policy evaluation API |
31 | | -- DLP scanning for secrets and PII |
32 | | -- Approval queue and operator controls |
33 | | -- Telegram/channel guardrails |
34 | | -- Damage Control bash/command preflight |
35 | | -- Local Security Command Center dashboard |
36 | | -- Watchdog and runtime health signals |
37 | | -- Structured audit events and decision evidence |
| 5 | +<p align="center">Runtime firewall and operator console for AI agents.</p> |
38 | 6 |
|
39 | | -## Dashboard |
40 | | - |
41 | | -Agentwall runs a local operator dashboard: |
| 7 | +<p align="center"> |
| 8 | + <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-22d3ee?style=flat-square&labelColor=0b0f14" alt="License: MIT"></a> |
| 9 | + <img src="https://img.shields.io/badge/TypeScript-5.x-22d3ee?style=flat-square&labelColor=0b0f14&logo=typescript&logoColor=22d3ee" alt="TypeScript"> |
| 10 | + <img src="https://img.shields.io/badge/Node-%E2%89%A520-22d3ee?style=flat-square&labelColor=0b0f14&logo=node.js&logoColor=22d3ee" alt="Node >= 20"> |
| 11 | + <img src="https://img.shields.io/badge/Fastify-5.x-22d3ee?style=flat-square&labelColor=0b0f14&logo=fastify&logoColor=22d3ee" alt="Fastify 5"> |
| 12 | + <img src="https://img.shields.io/badge/status-active-22d3ee?style=flat-square&labelColor=0b0f14" alt="Status: active"> |
| 13 | + <a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-22d3ee?style=flat-square&labelColor=0b0f14" alt="PRs welcome"></a> |
| 14 | +</p> |
42 | 15 |
|
43 | | -```text |
44 | | -http://127.0.0.1:3015/dashboard |
| 16 | +--- |
| 17 | + |
| 18 | +Agentwall sits between AI agents and the surfaces where their actions become real — shell commands, tools, network egress, browser actions, communication channels, identity, and content delivery. Before an agent acts, it answers one question: **should this action be allowed, redacted, routed to a human, or denied?** Prompts are not a security boundary; Agentwall enforces policy at runtime, where the risk is, and leaves a tamper-evident record an operator can review. |
| 19 | + |
| 20 | +## Features |
| 21 | + |
| 22 | +- **Deterministic policy engine** — every request is scored across six action planes (`network`, `tool`, `content`, `browser`, `identity`, `governance`) into one of four decisions (`allow` / `redact` / `approve` / `deny`). The highest-severity matching rule wins, and every decision returns the matched rule IDs, human reasons, risk level, and MITRE ATT&CK-mapped detections. |
| 23 | +- **Provenance- and flow-aware** — trust labels (`trusted` / `untrusted` / `derived`) and flow labels (`secret_material`, `pii`, `credential_access`, `destructive_action`, `payment`, `private_network_target`, …) drive high-risk detection, so untrusted content can't quietly escalate into privileged egress. |
| 24 | +- **DLP secret & PII scanning** — built-in detectors for AWS keys, GitHub PATs/OAuth tokens, OpenAI keys, Slack tokens, private keys, and JWTs, plus SSNs, credit cards, emails, and phone numbers — with inline redaction. |
| 25 | +- **Egress / SSRF firewall** — default-deny egress with scheme/port/host allowlists; blocks private, loopback, and link-local ranges and cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`). |
| 26 | +- **Human approval gate** — `auto` / `always` / `never` modes, a persistent approval queue, operator and channel notifications, and HMAC-signed, TTL-bound **capability tickets** minted on allow. |
| 27 | +- **Damage Control command preflight** — static analysis of shell/bash commands before execution, combined with the policy decision so risky commands escalate to a human. |
| 28 | +- **Communication-channel containment** — scoped guardrails for agent bots in shared Telegram/Slack/Discord chats: deny filesystem mutation and secret egress, redact PII in outbound replies. |
| 29 | +- **Runtime FloodGuard** — per-session and per-actor rate limits, pending-approval caps, cost budgets, one-command shield mode, and temporary session boosts. |
| 30 | +- **Tamper-evident audit** — SHA-256 hash-chained audit events plus OpenTelemetry (OTLP/HTTP) decision traces for downstream observability. |
| 31 | +- **Operator console & org control plane** — a local Fastify dashboard with live SSE updates, session containment (pause / resume / terminate), and a single-pane federation summary across multiple Agentwall instances via authenticated peer polling. |
| 32 | +- **Manifest integrity** — detects drift in tool/agent manifests against approved fingerprints. |
| 33 | + |
| 34 | +## Architecture |
| 35 | + |
| 36 | +The request → policy → decision → audit flow for a single agent action: |
| 37 | + |
| 38 | +```mermaid |
| 39 | +flowchart TD |
| 40 | + A["Agent action request"] -->|"POST /evaluate"| B["Fastify server"] |
| 41 | + B --> C{"FloodGuard<br/>rate & cost limits"} |
| 42 | + C -->|throttled| Z["Blocked & audited"] |
| 43 | + C -->|ok| D{"Session paused<br/>or terminated?"} |
| 44 | + D -->|contained| Z |
| 45 | + D -->|active| E["Policy engine"] |
| 46 | +
|
| 47 | + subgraph INPUTS["Evaluation inputs"] |
| 48 | + direction LR |
| 49 | + F["DLP scan<br/>secrets & PII"] |
| 50 | + G["Egress / SSRF<br/>inspector"] |
| 51 | + H["Provenance &<br/>flow labels"] |
| 52 | + I["Built-in & YAML<br/>policy rules"] |
| 53 | + end |
| 54 | + INPUTS --> E |
| 55 | +
|
| 56 | + E --> J{"Decision"} |
| 57 | + J -->|allow| K["Issue capability ticket<br/>HMAC + TTL"] |
| 58 | + J -->|redact| L["Return redacted content"] |
| 59 | + J -->|approve| M["Approval queue"] |
| 60 | + J -->|deny| N["Block action"] |
| 61 | +
|
| 62 | + M --> O["Operator console<br/>& channel notifier"] |
| 63 | + O -->|"approve / deny"| J |
| 64 | +
|
| 65 | + K --> P["Emit audit event"] |
| 66 | + L --> P |
| 67 | + N --> P |
| 68 | + P --> Q["SHA-256 hash chain"] |
| 69 | + P --> R["OTLP decision trace"] |
| 70 | + P --> S["Runtime state<br/>dashboard & org summary"] |
45 | 71 | ``` |
46 | 72 |
|
47 | | -The dashboard is built around three surfaces: |
48 | | - |
49 | | -1. **Local Runtime**: service health, default-deny posture, approval mode, flood controls |
50 | | -2. **Communication Guardrails**: scoped channel policies for agent bots in shared conversations |
51 | | -3. **Bash Firewall**: preflight checks for risky shell commands before execution |
52 | | - |
53 | | -Advanced mode exposes policy, audit, federation, sessions, and diagnostic views. |
| 73 | +## Getting started |
54 | 74 |
|
55 | | -## Quickstart |
| 75 | +Requires Node.js ≥ 20. |
56 | 76 |
|
57 | 77 | ```bash |
58 | 78 | git clone https://github.com/reesepj/agentwall.git |
59 | 79 | cd agentwall |
60 | 80 | npm install |
61 | 81 | npm run build |
| 82 | + |
| 83 | +# scaffold config + policy, then start |
62 | 84 | node dist/cli.js init --mode guarded --allow-hosts api.openai.com |
63 | 85 | node dist/cli.js doctor |
64 | 86 | node dist/cli.js start |
65 | 87 | ``` |
66 | 88 |
|
67 | | -Run tests: |
| 89 | +The operator console is served at `/dashboard` on the configured host/port (default `http://127.0.0.1:3000/dashboard`). |
68 | 90 |
|
69 | 91 | ```bash |
70 | | -npm test |
| 92 | +npm run dev # ts-node, no build step |
| 93 | +npm test # Jest test suite |
| 94 | +npm run lint # tsc --noEmit typecheck |
71 | 95 | ``` |
72 | 96 |
|
73 | | -## Example policy posture |
74 | | - |
75 | | -```yaml |
76 | | -policy: |
77 | | - defaultDecision: "deny" |
78 | | -egress: |
79 | | - enabled: true |
80 | | - defaultDeny: true |
81 | | - allowPrivateRanges: false |
82 | | - allowedSchemes: ["https"] |
83 | | - allowedPorts: [443] |
| 97 | +Ask for a decision over HTTP: |
| 98 | + |
| 99 | +```bash |
| 100 | +curl -s http://127.0.0.1:3000/evaluate \ |
| 101 | + -H 'content-type: application/json' \ |
| 102 | + -d '{"agentId":"demo","plane":"network","action":"http_get", |
| 103 | + "payload":{"url":"http://169.254.169.254/latest/meta-data/"}, |
| 104 | + "flow":{"direction":"egress"}}' |
| 105 | +# -> { "decision": "deny", "riskLevel": "critical", "matchedRules": ["net:block-ssrf-private","net:block-metadata-endpoint"], ... } |
84 | 106 | ``` |
85 | 107 |
|
86 | | -## Main endpoints |
| 108 | +Core API surface: |
87 | 109 |
|
88 | 110 | ```text |
89 | | -POST /evaluate |
90 | | -POST /inspect/content |
91 | | -POST /integrations/communication-channel/guardrail |
92 | | -POST /integrations/damage-control/command-preflight |
93 | | -GET /api/dashboard/state |
| 111 | +POST /evaluate # policy decision (+ capability ticket) |
| 112 | +POST /inspect/content # DLP secret/PII scan + redaction |
| 113 | +POST /inspect/network # egress / SSRF inspection |
| 114 | +POST /inspect/manifest # manifest drift detection |
| 115 | +POST /approval/request GET /approval/pending # approval queue |
| 116 | +POST /approval/:id/respond |
| 117 | +POST /integrations/communication-channel/guardrail # channel containment |
| 118 | +POST /integrations/damage-control/command-preflight # bash command firewall |
| 119 | +GET /detections GET /rules # decision catalog & active rules |
| 120 | +GET /api/dashboard/state GET /api/dashboard/events # operator console (state + SSE) |
| 121 | +GET /api/org/summary # federation single-pane summary |
94 | 122 | ``` |
95 | 123 |
|
96 | | -## Docs |
| 124 | +## Tech stack |
| 125 | + |
| 126 | +| Layer | Choice | |
| 127 | +| --- | --- | |
| 128 | +| Language | TypeScript 5 (strict), Node.js ≥ 20 | |
| 129 | +| HTTP server | Fastify 5 | |
| 130 | +| Schema validation | Zod | |
| 131 | +| Logging | pino | |
| 132 | +| Config & policy | YAML (`js-yaml`) | |
| 133 | +| Crypto | Node `crypto` — HMAC capability tickets, SHA-256 audit chain | |
| 134 | +| Telemetry | OpenTelemetry OTLP/HTTP decision traces | |
| 135 | +| Tests | Jest + ts-jest | |
| 136 | +| Tooling | bundled `agentwall` CLI | |
| 137 | + |
| 138 | +## How it works |
97 | 139 |
|
98 | | -- `docs/README.md` |
99 | | -- `docs/architecture.md` |
100 | | -- `docs/product-thesis.md` |
101 | | -- `docs/threat-model.md` |
102 | | -- `docs/tutorials/` |
| 140 | +A few load-bearing design decisions: |
103 | 141 |
|
104 | | -## Boundary |
| 142 | +- **Enforce at the action surface, not in the model.** Agentwall is independent of the agent framework; it gates the moment an action would touch a real resource. |
| 143 | +- **Default-deny.** Unmatched actions and outbound egress are denied unless explicitly allowed, and a watchdog kill-switch fails closed (`deny_all`) when heartbeats go stale. |
| 144 | +- **Explainable decisions.** Results carry matched rule IDs, reasons, and ATT&CK-mapped detections — no opaque scores — so operators and audit logs agree on *why*. |
| 145 | +- **Tamper-evident by construction.** Audit events are hash-chained and capability tickets are signed, so allow decisions are verifiable after the fact. |
| 146 | +- **Operator-first.** Live dashboard, approval queue, FloodGuard shield, and per-session pause/resume/terminate give a human real-time containment controls. |
105 | 147 |
|
106 | | -This repo is the local/open-source runtime control plane. Managed service operations, enterprise connectors, proprietary policy intelligence, and incident automation workflows belong outside the OSS core. |
| 148 | +Policy ships as a built-in rule pack plus hot-reloadable YAML, so posture can be tightened without a redeploy. See `examples/policy.yaml` and the `docs/` directory for threat model, architecture, and tutorials. |
107 | 149 |
|
108 | 150 | ## License |
109 | 151 |
|
110 | | -MIT |
| 152 | +MIT — see [LICENSE](LICENSE). |
0 commit comments