SkillAgentSearch skills...

AgentGuard

No description available

Install / Use

/learn @ThodorisTsampouris/AgentGuard
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

AgentGuard

Zero-trust sandbox for autonomous AI agents.

AgentGuard wraps any AI agent (LangChain, CrewAI, AutoGen, custom scripts) with safety rails. One command change:

# Before (dangerous — agent has full system access)
python my_agent.py

# After (sandboxed)
agentguard run -- python my_agent.py

AgentGuard intercepts every shell command, file modification, and network request the agent makes. Safe actions are auto-allowed, dangerous actions are auto-blocked, and everything else prompts the human for approval.

How It Works

AgentGuard has four defense layers that work together:

┌─────────────────────────────────────────────────────────────┐
│ Layer 0: Filesystem Jail (sandbox-exec on macOS)            │
│   Kernel-level enforcement. Restricts file writes and       │
│   network at the syscall level. Agent cannot bypass from    │
│   userspace. Blocks Python's open(), requests.post(), etc.  │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: Network Proxy                                      │
│   Transparent HTTP/HTTPS proxy. Every network call the      │
│   agent makes is checked against the policy. Per-destination │
│   allow/deny with full visibility in the TUI.               │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: PATH Shims                                         │
│   Shell script shims that intercept commands like git,      │
│   pip, curl, rm. Each shim asks the daemon for permission   │
│   before running the real binary.                           │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: Policy Engine + Approval Daemon                    │
│   YAML-based rules evaluate every intercepted action.       │
│   Auto-allow safe commands, auto-block dangerous ones,      │
│   prompt the human for everything else.                     │
└─────────────────────────────────────────────────────────────┘

No single layer is the security boundary. They work together — defense in depth.

Quick Start

Build

go build -o agentguard ./cmd/agentguard/
go build -o agentguard-check ./cmd/agentguard-check/

Both binaries must be in the same directory.

Create a Policy

agentguard init

This creates .agentguard/policy.yaml in the current directory. Edit it to match your needs.

Run an Agent (Interactive TUI)

agentguard run -- python my_agent.py

The TUI takes over the terminal and shows:

  • Live activity stream (every intercepted action)
  • Approval prompts for ambiguous commands (press Y/N/A/B)
  • Network allow/deny events from the proxy
  • Sandbox violation events
  • Agent stdout/stderr (toggle with Tab)

Run an Agent (Headless)

For interactive tools like Claude Code that need the terminal:

agentguard run --headless -- claude

The agent gets the terminal directly. AgentGuard runs silently in the background. All events are logged to ~/.agentguard/logs/headless.log. Monitor in another terminal:

tail -f ~/.agentguard/logs/headless.log

CLI Reference

agentguard run [flags] -- <command> [args...]
    --policy <path>     Use a specific policy file
    --headless          No TUI — agent gets the terminal
    --default-allow     Auto-allow PROMPT decisions in headless mode (default: auto-deny)
    --no-sandbox        Disable sandbox-exec (shims and proxy still active)

agentguard init         Create a default policy file
agentguard version      Print version

Policy File

Policies are YAML files that define what the agent can and cannot do. AgentGuard checks three locations (in order):

  1. ./.agentguard/policy.yaml (project-local)
  2. ~/.agentguard/policy.yaml (user global)
  3. Built-in defaults

Example Policy

version: 1

deny:
  # Block dangerous commands
  - command: "rm"
    args: "-rf *"
    reason: "Recursive forced deletion is too dangerous"
  - command: "sudo"
    args: "*"
    reason: "Privilege escalation is not allowed"
  - command: "chmod"
    args: "777 *"
    reason: "World-writable permissions are dangerous"

  # Block reading sensitive files (enforced by sandbox-exec)
  - file:
      path: "*.env"
      action: "read"
      reason: "Don't let agent read .env files"
  - file:
      path: "*.pem"
      action: "read"
      reason: "Don't let agent read private keys"

allow:
  # Safe read-only commands
  - command: "ls"
  - command: "cat"
  - command: "pwd"
  - command: "echo"
  - command: "grep"
  - command: "head"
  - command: "tail"
  - command: "wc"

  # Read-only git
  - command: "git"
    args: "status"
  - command: "git"
    args: "log *"
  - command: "git"
    args: "diff *"

  # Allow writes to workspace
  - file:
      path: "/tmp/workspace/**"
      action: "write"

  # Allow specific API endpoints
  - network:
      destination: "api.anthropic.com:443"
  - network:
      destination: "api.github.com:443"

Rule Evaluation Order

  1. Specific deny rules — checked first. If matched, action is blocked immediately.
  2. Allow rules — checked second. If matched, action is permitted.
  3. Catch-all deny rules (e.g. deny network *) — checked third. Acts as a default deny.
  4. No match — the human is prompted (TUI) or auto-denied (headless).

Rule Types

Command rules — match shell commands by name and argument pattern:

- command: "git"
  args: "push *"
  reason: "Pushing requires approval"

File rules — match file operations (enforced by sandbox-exec):

- file:
    path: "*.env"
    action: "read"     # "read" or "write"
    reason: "Protect secrets"

Network rules — match network destinations (enforced by proxy + sandbox-exec):

- network:
    destination: "api.anthropic.com:443"

Use * as a wildcard in command args, file paths, and network destinations.

TUI Controls

| Key | Action | When | |-----|--------|------| | Y | Allow the pending request | Approval prompt visible | | N | Deny the pending request | Approval prompt visible | | A | Allow + remember for this session ("Always Allow") | Approval prompt visible | | B | Deny + remember for this session ("Block Forever") | Approval prompt visible | | Tab | Toggle agent stdout/stderr panel | Always | | Up/Down | Scroll activity stream | Always | | Q | Quit (kills the agent) | Always |

What Each Layer Catches

| Agent action | Shims | Proxy | sandbox-exec | |---|---|---|---| | subprocess.run(["rm", "-rf", "/"]) | Yes | - | - | | subprocess.run(["git", "push"]) | Yes | - | - | | requests.post("https://evil.com") | - | Yes | Yes | | urllib.request.urlopen("https://api.com") | - | Yes | Yes | | open(".env", "r") | - | - | Yes | | open("/etc/shadow", "w") | - | - | Yes | | /usr/bin/curl https://evil.com (absolute path) | - | Yes | Yes |

Architecture

agentguard/
├── cmd/
│   ├── agentguard/              # Main CLI binary
│   └── agentguard-check/        # Shim helper binary
├── internal/
│   ├── policy/                  # Policy engine (YAML parsing, rule evaluation)
│   ├── events/                  # Event system (JSONL audit log, pub/sub)
│   ├── daemon/                  # Central daemon (Unix socket, approval queue)
│   │   └── client/              # Client library for shims
│   ├── shim/                    # Shim generator (PATH-based interception)
│   ├── proxy/                   # Transparent network proxy
│   ├── spawner/                 # Orchestration + macOS sandbox integration
│   └── ui/tui/                  # Terminal UI (Bubble Tea)
├── configs/
│   └── default_policy.yaml      # Reference policy file
├── .gitignore
├── go.mod
├── LICENSE
└── README.md

Component Overview

| Component | Package | Purpose | |---|---|---| | Policy Engine | internal/policy | Parses YAML rules, evaluates requests → ALLOW / DENY / PROMPT | | Event System | internal/events | Append-only JSONL audit log + real-time pub/sub for TUI | | Daemon | internal/daemon | Unix socket server, approval queue with timeouts, session management | | TUI | internal/ui/tui | Bubble Tea terminal UI with activity stream and approval modal | | Shim Generator | internal/shim | Generates shell script shims, resolves real binary paths | | Network Proxy | internal/proxy | Transparent HTTP/HTTPS proxy enforcing per-destination policy | | Spawner | internal/spawner | Orchestrates everything: policy → daemon → shims → proxy → sandbox → agent → TUI | | macOS Sandbox | internal/spawner/jail_darwin.go | sandbox-exec with Seatbelt profiles for kernel-level enforcement |

Audit Log

Every intercepted action is logged to ~/.agentguard/logs/YYYY-MM-DD.jsonl:

{"id":"a1b2c3","timestamp":"2026-03-22T14:30:00Z","session_id":"abc123","source":"shim","command":"git","args":["push","origin","main"],"decision":"deny","decided_by":"human","response_time_ms":3200}
{"id":"d4e5f6","timestamp":"2026-03-22T14:30:01Z","session_id":"abc123","source":"proxy","network_dst":"api.anthropic.com:443","decision":"allow","decided_by":"policy"}

Query with standard tools:

# All denied actions today
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decision == "deny")'

# All network requests
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.source == "proxy")'

# Commands that required human approval
cat ~/.agentguard/logs/2026-03-22.jsonl | jq 'select(.decided_by == "human")'

Platform Support

| Platform | Shims | Proxy | sandbox-exec | File read deny | |---|---|---|---|---| | macOS (Apple Silicon) | Yes | Yes | Yes | Yes | | macOS (Intel) | Yes | Yes | Yes | Yes | | Linux | Yes | Yes | No (future: namespaces + seccomp) | No | | Windows | Yes | Yes | No (future: Job Objects) | No |

Security Model

Threat model: The agent is untrusted. It may try to:

  • Execute dangerous commands (rm -rf /, sudo)
  • Exfiltrate data via network calls
  • Read sensitive files (.env, private keys)
  • Bypass the sandbox via ab
View on GitHub
GitHub Stars6
CategoryDevelopment
Updated11d ago
Forks0

Languages

Go

Security Score

80/100

Audited on Mar 29, 2026

No findings