Skip to main content
Glama
README.md
# Agent Governance Gateway

> **An AI agent having a *capability* is not the same as it having *authority*.**
> This system separates the two.

Authorization & governance infrastructure for autonomous AI agents. Drop it into any folder where an agent already runs — Claude Code, ChatGPT Enterprise/Codex, Cursor, Windsurf — and every tool call is answered, and recorded: *who is the agent · what is it trying to do · to what resource · what authority does it have · what policy applies · does it need a human · who approved · what happened · can an examiner prove it.* Privileged actions are escalated to a named human approver, executed outside the agent's context, and the output is fed back so the agent continues.

A private, in-tenant model (e.g. ChatGPT Enterprise on Entra) fixes *data residency*. It does **not** govern what the agent *does* — reading files outside its remit, writing to prod, or being prompt-injected into exfiltrating to an attacker host. That is an **authorization** problem, and it is what this governs.

**For the banking/MUFG framing, start with [docs/MUFG_BRIEF.md](docs/MUFG_BRIEF.md); to see it run, [docs/DEMO.md](docs/DEMO.md).**

## Architecture

**The Folder Connector** bridges the sandbox into your project:

- **Claude Code hooks** intercept tool calls, escalate privileged operations to a human approver, and return captured output inside a `deny` decision so the tool never runs with agent privileges
- **MCP server** (`run_privileged`, `check_request`, `sandbox_status`) provides the same loop over the Model Context Protocol — works with Claude Code, Codex, Cursor, Windsurf
- **Folder queue** (`.sandbox/escalations/`) is the bus: atomic file operations (`os.replace`, `os.rename`) coordinate approval across four unrelated processes (hook subprocess, MCP server, approver terminal, dashboard)
- **Policy engine** classifies shell commands, file writes, network requests, and reads — four escalation triggers with human-in-the-loop as the top tier

## Quick Start

```bash
# Install the connector
python -m pip install -e ".[dev]"

# Initialize a folder
sandbox init . --claude --mcp

# In one terminal: watch for escalations
sandbox watch .

# In another: use Claude Code or the MCP tools as normal
# Privileged commands will appear in the `watch` terminal for approval
```

## How It Works

1. **Agent tries to run a command** — Claude Code's PreToolUse hook intercepts it
2. **Hook classifies and escalates** — shell commands not in the allowlist go to the folder queue
3. **Human approves in `sandbox watch`** — the approver executes the command **outside** the agent
4. **Output returns to the model** — wrapped in `permissionDecision:"deny"` with stdout in the reason string
5. **Agent continues** — it received the result, never had privilege itself

The MCP channel works identically: `run_privileged` returns a tool result with captured output.

## Milestones

- ✅ **Milestone 0** — Foundations (bug fixes, path containment, audit rehydration)
- ✅ **Milestone 1** — The loop (PreToolUse hook, folder queue, CLI approval)
- ✅ **Milestone 2** — MCP channel (run_privileged, check_request, sandbox_status)
- ✅ **Milestone 3** — Folder record (restorable originals, chained audit, PostToolUse)
- ✅ **Milestone 4** — Other triggers (full classifier, remembered decisions, SessionStart context)
- ✅ **Milestone 5** — Surfaces (REST routes, uninstall, docs)

**All milestones complete.** See [docs/CONNECTOR.md](docs/CONNECTOR.md) for the full technical reference.

## Testing

```bash
# Run all tests (117 passing)
python -m pytest -q

# Test the loop with a real hook subprocess and background approver
python -m pytest tests/integration/test_connector_loop.py -v

# Test the MCP channel
python -m pytest tests/integration/test_mcp_tools.py -v
```

## Project Structure

```
src/sandbox/
├── connector/           # Folder connector (queue, hooks, policy, MCP)
├── launcher/            # M1 jailed launcher (job objects, jail, shims)
├── audit/               # Chained audit log with tamper detection
├── broker/              # Non-AI privilege executor
├── fs/                  # Path containment and validation
├── agents/              # Multi-agent sandbox orchestrator
├── api/                 # FastAPI routes and WebSocket
└── ...
```

## Key Design Decisions

- **The folder is the bus**: Atomic file operations on NTFS coordinate four independent processes (no in-memory state, no open ports, survives restarts)
- **`deny` carries the output**: Tool never executes in the agent; output is pasted back in the reason string
- **CLI-first approval**: Headless, works over SSH, no browser dependency
- **Fail-closed**: Internal errors block rather than silently allow
- **Non-removable self-protection**: `.sandbox/**` in write denials and `\.sandbox` in shell denials are re-injected on every policy load — agent cannot remove its own constraints

## License

[To be determined]

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct capability: shell execution, file access, network fetch, request status, and sandbox overview. There is no overlap in purpose, and descriptions clearly delineate boundaries.

Naming Consistency4/5

Most tools follow a verb_noun pattern (run_privileged, request_path_access, fetch_url, check_request), but sandbox_status breaks the pattern by being noun_noun. The deviation is minor and the intent remains clear.

Tool Count5/5

With 5 tools, the server is well-scoped for its purpose of gated external operations. Each tool earns its place without redundancy or excess.

Completeness5/5

The surface covers all core operations (run, file, fetch) and provides status retrieval via check_request and sandbox_status. No obvious dead ends or missing lifecycle steps for the stated escalation workflow.

Maintenance

ActivityMaintained
ResponsivenessSyncing