Help us shape the future of Go! Take the 2026 Go Developer Survey

rinwall

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: Apache-2.0

README

RinWall

A firewall for what your AI agents are allowed to do.

RinWall sits between your agent and the tools it calls. Before any call goes through, it asks one question: can this be undone?

  • Reads go straight through.
  • Changes that can be undone go through, and are rolled back automatically if a later step in the same run fails.
  • Actions that can't be undone (sending, paying, deleting, publishing) wait until a person approves that exact request.

The agent never holds your credentials, and every decision is written to a tamper-evident audit log.

A real recording, not a mock-up: scripts/record_demo.py replays it against the real binaries.

Status: v0.1, a working reference implementation. Built, tested, and verified against real clients and infrastructure, but not yet run in anyone's production except our own test stacks, and not yet reviewed by a third party. Issues get a response within three business days, security reports sooner (SECURITY.md). Apache-2.0.

Try it in front of your MCP server

1. Install. One download, no dependencies. Pick your platform: darwin_arm64 (Apple Silicon), darwin_amd64, linux_amd64, linux_arm64, or windows_amd64 (a .zip).

curl -fsSL https://github.com/RinwallDev/rinwall/releases/latest/download/rinwall_darwin_arm64.tar.gz | tar xz
cd rinwall_darwin_arm64

Or, with Go installed: go install github.com/RinwallDev/rinwall/cmd/rinwall@latest.

2. Run it in front of your server. Leave this terminal open; you'll need what it prints.

./rinwall --mcp https://your-server.example.com/mcp

If your server needs a token, put it in an environment variable and name the variable: --mcp-auth-env MY_SERVER_TOKEN.

3. Point your agent at RinWall instead of the server. For Claude Code:

claude mcp add --transport http rinwall http://127.0.0.1:8080/mcp

Cursor, Claude Desktop, and your own agent code are in INTEGRATIONS.md.

What you'll see. At startup RinWall lists your server's tools sorted by what can be undone, and prints a reviewer token:

  Scanned 3 tools and classified them by what they can undo:

     1 irreversible        needs a human to approve, every time
         mcp_close_account
     1 compensable         executes, and is undone automatically if the run fails
         mcp_update_customer_tier
     1 read-only/retryable executes freely

  Review pending calls:  http://127.0.0.1:8080/admin
  To approve something, paste this reviewer token into that page:
    eyJhbGci...

Use your agent normally. When it tries something irreversible, the call waits and the agent is told so. Open http://127.0.0.1:8080/admin, paste the token, and approve or deny.

This mode needs no configuration and is meant for trying RinWall out. It has no authentication, so it only listens on your own machine (127.0.0.1) and refuses any other address. PRODUCTION.md covers the real setup.

No MCP server to try it on? The repository includes a small one with a read, an undoable change, and an irreversible action:

git clone https://github.com/RinwallDev/rinwall && cd rinwall
go run ./cmd/mockupstream &
go run ./cmd/rinwall --mcp http://127.0.0.1:8000/mcp

Other setups

Your agent... What to do
calls MCP tools from your own code Point its MCP client at http://127.0.0.1:8080/mcp, as in step 3.
calls an HTTP API Describe the API's endpoints in a short catalog file; RinWall can't read them from the API itself yet. GETTING_STARTED.md has a worked example.
runs tools as functions inside its own code Not supported directly yet: RinWall needs something on the network to sit in front of. Expose the functions as a small API or MCP server. A library that wraps functions in place is on the roadmap.
is going to production PRODUCTION.md: real identity, a secrets manager, multiple replicas, a reviewed catalog. All configuration, no code.

Check a server before you trust it

The scanner on its own answers "what could an agent do with this server?" without running anything. It sends only the two requests that list tools, and calls none of them:

./rinwall-blastradius --mcp https://some-server.example.com/mcp

We ran it across 800 public MCP servers. More than one in four exposes at least one action that can't be undone: the write-up.

Learn more

  • ARCHITECTURE.md: how it works and why, in plain English.
  • THREAT_MODEL.md: what it defends against, what it doesn't, and its known weak points.
  • docs/REFERENCE.md: every endpoint, option, and guarantee, with walkthroughs you can run.
  • CHANGELOG.md: what changed in each release, and how to check it.

Contributing

Issues and pull requests are welcome; CONTRIBUTING.md explains what a change needs. Report security issues privately, as SECURITY.md describes, not in a public issue. Licensed under Apache-2.0.

Directories

Path Synopsis
cmd
auditverify command
Command auditverify is the operator/auditor-facing tool for the audit log's tamper-evidence guarantee (internal/audit's hash chain): point it at any exported audit.log and it reports whether the chain is intact, or names the exact line/sequence number where it breaks.
Command auditverify is the operator/auditor-facing tool for the audit log's tamper-evidence guarantee (internal/audit's hash chain): point it at any exported audit.log and it reports whether the chain is intact, or names the exact line/sequence number where it breaks.
blastradius command
Command blastradius answers one question, with no setup and no integration: how much damage can this agent's tools actually do?
Command blastradius answers one question, with no setup and no integration: how much damage can this agent's tools actually do?
devtoken command
Command devtoken mints a dev-only signed identity JWT for local testing.
Command devtoken mints a dev-only signed identity JWT for local testing.
loadtest command
Command loadtest is the concurrent-load + latency benchmark harness.
Command loadtest is the concurrent-load + latency benchmark harness.
mockupstream command
Command mockupstream plays "the real enterprise service": it never trusts the proxy blindly, it verifies each capability token itself - a biscuit token's full signature chain plus its appended checks (internal/capability.Verify).
Command mockupstream plays "the real enterprise service": it never trusts the proxy blindly, it verifies each capability token itself - a biscuit token's full signature chain plus its appended checks (internal/capability.Verify).
rinwall command
Command proxy is the JIT capability firewall itself: loads the tool registry and policy bundle, then serves both the REST and MCP adapters against the same transport-agnostic handler.
Command proxy is the JIT capability firewall itself: loads the tool registry and policy bundle, then serves both the REST and MCP adapters against the same transport-agnostic handler.
internal
adapter/mcp
Package mcp exposes the handler as an MCP server over two transports: Streamable HTTP (POST /mcp, spec 2025-06-18, back-compatible with 2024-11-05/2025-03-26 clients) and stdio (stdio.go), for clients that launch a local server process rather than connect to a URL.
Package mcp exposes the handler as an MCP server over two transports: Streamable HTTP (POST /mcp, spec 2025-06-18, back-compatible with 2024-11-05/2025-03-26 clients) and stdio (stdio.go), for clients that launch a local server process rather than connect to a URL.
adapter/rest
Package rest is one of the two adapters (see internal/adapter/mcp for the other): the conventional reverse-proxy path for agents calling REST/function-calling APIs directly rather than through an MCP server.
Package rest is one of the two adapters (see internal/adapter/mcp for the other): the conventional reverse-proxy path for agents calling REST/function-calling APIs directly rather than through an MCP server.
adminui
Package adminui embeds the minimal reviewer console served at GET /admin.
Package adminui embeds the minimal reviewer console served at GET /admin.
approval
Package approval implements the three-tier mechanism for Class C (irreversible) tools, replacing naive "approve or deny every call" HITL - which trains reviewers to rubber-stamp - with a tiered design where only the irreducible remainder ever reaches a live person.
Package approval implements the three-tier mechanism for Class C (irreversible) tools, replacing naive "approve or deny every call" HITL - which trains reviewers to rubber-stamp - with a tiered design where only the irreducible remainder ever reaches a live person.
audit
Package audit is the append-only event log every decision lands in: a local JSONL file by default, or a Postgres table in multi-instance mode (postgres.go).
Package audit is the append-only event log every decision lands in: a local JSONL file by default, or a Postgres table in multi-instance mode (postgres.go).
authn
Package authn verifies the delegated human's identity.
Package authn verifies the delegated human's identity.
capability
Real Vault dynamic AWS credentials, alongside dbsecrets.go.
Real Vault dynamic AWS credentials, alongside dbsecrets.go.
classify
Package classify infers a tool's reversibility class from its name, description, and schema - the single biggest onboarding barrier this system had.
Package classify infers a tool's reversibility class from its name, description, and schema - the single biggest onboarding barrier this system had.
compliance
Package compliance turns the raw material this proxy already collects - the tamper-evident audit log (internal/audit) and the reversibility registry (internal/registry) - into the thing a SOC2 auditor or a customer's compliance team actually wants: a structured summary over a time period, not a JSONL file they have to grep themselves.
Package compliance turns the raw material this proxy already collects - the tamper-evident audit log (internal/audit) and the reversibility registry (internal/registry) - into the thing a SOC2 auditor or a customer's compliance team actually wants: a structured summary over a time period, not a JSONL file they have to grep themselves.
discover
Package discover turns a live MCP server into a runnable tool catalog with no human in the loop, which is what makes a one-command start possible at all.
Package discover turns a live MCP server into a runnable tool catalog with no human in the loop, which is what makes a one-command start possible at all.
handler
AWS-backed tool execution - the real Vault dynamic-secrets path (aws/sts/<role>, a genuine sts:AssumeRole against the actual AWS account) alongside the existing biscuit/HTTP and DB paths.
AWS-backed tool execution - the real Vault dynamic-secrets path (aws/sts/<role>, a genuine sts:AssumeRole against the actual AWS account) alongside the existing biscuit/HTTP and DB paths.
mcpclient
Package mcpclient is the client half of MCP - what this proxy needs to forward a call ONWARD to an upstream MCP server, as opposed to internal/adapter/mcp which is the server half that agents connect to.
Package mcpclient is the client half of MCP - what this proxy needs to forward a call ONWARD to an upstream MCP server, as opposed to internal/adapter/mcp which is the server half that agents connect to.
metrics
Package metrics records per-stage durations from internal/handler and exposes p50/p95 via cmd/rinwall's /metrics endpoint, so the latency claims in docs/REFERENCE.md are numbers rather than assertions.
Package metrics records per-stage durations from internal/handler and exposes p50/p95 via cmd/rinwall's /metrics endpoint, so the latency claims in docs/REFERENCE.md are numbers rather than assertions.
policy
Package policy embeds OPA directly in the proxy process - no network hop to a separate policy service, no per-call serialization round trip.
Package policy embeds OPA directly in the proxy process - no network hop to a separate policy service, no per-call serialization round trip.
provenance
Real implementation, validated against the live Anthropic API before being wired in here: forced tool-use (not a plain text response asking for JSON) is what guarantees structured output - a plain-text prompt asking for JSON came back markdown-fenced in testing, which forced tool-use avoids entirely.
Real implementation, validated against the live Anthropic API before being wired in here: forced tool-use (not a plain text response asking for JSON) is what guarantees structured output - a plain-text prompt asking for JSON came back markdown-fenced in testing, which forced tool-use avoids entirely.
proxytypes
Package proxytypes is the transport-agnostic core representation an intercepted tool call is normalized into, regardless of whether it arrived over the REST adapter or the MCP adapter.
Package proxytypes is the transport-agnostic core representation an intercepted tool call is normalized into, regardless of whether it arrived over the REST adapter or the MCP adapter.
registry
Package registry holds the one contract every mutating tool must satisfy before an agent is ever allowed to call it: a declared reversibility class and an allowlist argument schema.
Package registry holds the one contract every mutating tool must satisfy before an agent is ever allowed to call it: a declared reversibility class and an allowlist argument schema.
risk
Package risk computes a continuous score used ONLY to add friction, never to grant access on its own - the earlier design critique was explicit that an ML/heuristic risk score is a soft, adversarially-attackable signal, and must never be a standalone ALLOW condition for a mutating call.
Package risk computes a continuous score used ONLY to add friction, never to grant access on its own - the earlier design critique was explicit that an ML/heuristic risk score is a soft, adversarially-attackable signal, and must never be a standalone ALLOW condition for a mutating call.
saga
Persistence for the saga Store - same reasoning as internal/approval's: a proxy restart mid-run must not silently lose the ability to compensate steps that already executed.
Persistence for the saga Store - same reasoning as internal/approval's: a proxy restart mid-run must not silently lose the ability to compensate steps that already executed.
usage
Package usage turns the audit log's real, per-call judge token usage into a cost report - both judges this project has: the text provenance judge (internal/provenance, PROVENANCE_JUDGE_USAGE entries) and the screenshot-reasoning one (internal/visualprovenance, VISUAL_PROVENANCE_JUDGE_USAGE entries).
Package usage turns the audit log's real, per-call judge token usage into a cost report - both judges this project has: the text provenance judge (internal/provenance, PROVENANCE_JUDGE_USAGE entries) and the screenshot-reasoning one (internal/visualprovenance, VISUAL_PROVENANCE_JUDGE_USAGE entries).
validate
Package validate implements allowlist-only payload validation: recursively canonicalize known encodings, then check the decoded value against a strict per-field schema.
Package validate implements allowlist-only payload validation: recursively canonicalize known encodings, then check the decoded value against a strict per-field schema.
visualprovenance
Real implementation, validated against the live Anthropic API with three deliberately-constructed test screenshots before this file was written - a legitimate order-review page, a fake "System Notice" payment-approval dialog embedded in an email, and a page where the stated intent ("clicking Cancel") didn't match the actual button at the target coordinate ("Delete Account").
Real implementation, validated against the live Anthropic API with three deliberately-constructed test screenshots before this file was written - a legitimate order-review page, a fake "System Notice" payment-approval dialog embedded in an email, and a page where the stated intent ("clicking Cancel") didn't match the actual button at the target coordinate ("Delete Account").

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL