Bulwark
AI agent governance: content scanning, audit logs, policy evaluation, session management.
★ 3Apache-2.0ai-ml
Install
Config snippet generator goes here (5 client tabs)
README
# Bulwark
**Open-source governance layer for AI agents.**
Bulwark sits between AI agents and external tools, enforcing policies, managing credentials, inspecting content, and maintaining a complete audit trail. One policy governs all your agents — Claude Code, OpenClaw, Codex, or any MCP/HTTP client.
## Why Bulwark?
AI agents are powerful but ungoverned. They can access any tool, leak any credential, and leave no audit trail. Bulwark fixes this:
- **Policy enforcement** — YAML-based rules control which tools agents can use, with glob patterns, scope-based precedence, and hot-reload
- **Credential management** — Agents never see real secrets. Bulwark injects credentials at the last mile, encrypted at rest with age
- **Content inspection** — Scan requests and responses for secrets, PII, and prompt injection. Block or redact automatically
- **Audit logging** — Every action recorded in a tamper-evident SQLite database with blake3 hash chains
- **Rate limiting** — Token-bucket rate limits per session, operator, tool, or globally. Cost tracking with budget enforcement
- **MCP-native** — Works as an MCP gateway or HTTP forward proxy. Governance metadata on every tool call response
## Install
```bash
# Homebrew (macOS / Linux)
brew install bpolania/tap/bulwark
# Docker
docker pull ghcr.io/bpolania/bulwark
# From source
git clone https://github.com/bpolania/bulwark.git
cd bulwark && cargo build --release
```
## Quick Start: Govern Claude Code with GitHub
This walkthrough connects Claude Code to GitHub through Bulwark. Every tool call is policy-evaluated, audited, and credential-injected — in about 5 minutes.
**Prerequisites:** [Claude Code](https://code.claude.com/) installed, a [GitHub personal access token](https://github.com/settings/tokens), and Node.js/npm (for the GitHub MCP server).
### 1. Initialize and verify
```bash
bulwark init my-project && cd my-project
bulwark doctor
```
`doctor` runs 9 diagnostic checks. All should pass.
### 2. Store your GitHub token
```bash
bulwark cred add github-token --type bearer_token
# Prompts for the token — hidden input, encrypted with age at rest
```
Configure the credential-to-tool binding in your bindings file so Bulwark knows to inject this token for GitHub tool calls.
### 3. Configure the upstream GitHub server
Edit `bulwark.yaml`:
```yaml
mcp_gateway:
upstream_servers:
- name: github
command: "npx"
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
policy:
policies_dir: "./policies"
hot_reload: true
audit:
enabled: true
inspect:
enabled: true
inspect_requests: true
inspect_responses: true
```
Make sure `GITHUB_TOKEN` is set in your shell (`export GITHUB_TOKEN=ghp_...`).
### 4. Write a policy
```bash
cat > policies/base.yaml << 'EOF'
metadata:
name: quickstart-policy
scope: global
rules:
- name: allow-reads
description: "Allow all read operations"
match:
actions: ["read_*", "get_*", "list_*", "search_*"]
verdict: allow
priority: 10
- name: allow-github-writes
description: "Allow creating issues, comments, PRs"
match:
tools: ["github__*"]
actions: ["create_*", "update_*"]
verdict: allow
priority: 10
- name: block-destructive
description: "Block all delete and force-push operations"
match:
actions: ["delete_*", "force_push_*"]
verdict: deny
priority: 20
message: "Destructive operations are blocked by policy"
- name: default-deny
match: {}
verdict: deny
priority: -100
message: "No policy explicitly allows this action"
EOF
bulwark policy validate
```
### 5. Create a session and connect Claude Code
```bash
# Create a session (--ttl is in seconds: 28800 = 8 hours)
bulwark session create --operator $(whoami) --agent-type claude-code --ttl 28800
# → Token: bwk_sess_7f3a...
export BULWARK_SESSION="bwk_sess_7f3a..." # paste your actual token
# Register Bulwark as an MCP server in Claude Code
claude mcp add --transport stdio bulwark \
--env BULWARK_SESSION=$BULWARK_SESSION \
-- bulwark mcp start
```
### 6. Use Claude Code — now governed
Start Claude Code. GitHub tools appear namespaced as `github__list_issues`, `github__create_issue`, etc.
Try it:
> "List the open issues in my repo"
Open a second terminal:
```bash
bulwark audit tail
```
```
22:01:03 github__list_issues ✓ allow 3ms (allow-reads)
```
Every call is logged with the verdict, matched rule, and timing. Now try something destructive:
> "Delete issue #1"
```
22:02:01 github__delete_issue ✗ deny <1ms (block-destructive)
```
Blocked. Sub-millisecond — policy evaluation happens in memory. The agent gets a structured error explaining which rule denied it.
### What just happened
Claude Code connected to Bulwark (not directly to GitHub). For every tool call, Bulwark validated the session, scanned for secrets/PII, evaluated the policy, injected the real GitHub token,