Skip to content

itdar/shield-agent

Repository files navigation

shield-agent

Security middleware for the AI Agent era. Sits transparently between agents and servers to provide authentication, protection, logging, and monitoring.

A ~10MB single binary written in Go. 30 seconds to install, 1 minute to configure.

┌──────────┐         ┌──────────────────────────┐         ┌──────────────┐
│ AI Agent │ ──────> │      shield-agent        │ ──────> │ Target Server│
│ MCP/A2A  │ <────── │  [auth] [guard] [log]    │ <────── │ MCP/A2A/API  │
└──────────┘         │  monitor :9090 /metrics  │         └──────────────┘
                     │  Web UI  :9090 /ui       │
                     └──────────────────────────┘

🌐 English | 한국어 | 日本語 | 中文


Table of Contents


When should you use this?

Situation What shield-agent does
You're exposing an MCP server publicly but need to restrict access Ed25519 signature / token-based authentication
Your agents are making too many API calls Rate limiting + hourly/monthly quotas
You need a record of who called what and when SQLite audit log + Prometheus metrics
You want to block requests from certain IP addresses IP blocklist/allowlist
You want to consolidate multiple MCP servers behind a single endpoint Gateway mode (host/path-based routing)
You want a convenient Web UI for management Built-in dashboard at /ui

What can be protected

Communication path Protocol Mode
Agent → MCP Server JSON-RPC (stdio / SSE / Streamable HTTP) stdio, proxy
Agent → Agent (A2A) Google A2A protocol HTTP middleware
Agent → API Server REST / GraphQL HTTP middleware

Installation

# Homebrew (macOS / Linux)
brew tap itdar/tap && brew install shield-agent

# curl install script
curl -sSL https://raw.githubusercontent.com/itdar/shield-agent/main/scripts/install.sh | sh

# Go install
go install github.com/itdar/shield-agent/cmd/shield-agent@latest

# Docker
docker pull ghcr.io/itdar/shield-agent:latest

# Build from source
git clone https://github.com/itdar/shield-agent.git
cd shield-agent && go build -o shield-agent ./cmd/shield-agent

Quick Start by Use Case

Case 1: Protect a local MCP server (stdio mode)

When you want to wrap a Python/Node.js MCP server to add authentication and logging

# Simplest usage — just wrap the MCP server process
shield-agent python my_mcp_server.py

# Debug with verbose mode
shield-agent --verbose node server.js --port 8080

How it works:

MCP Client ──stdin──> shield-agent ──stdin──> MCP Server (child process)
MCP Client <─stdout── shield-agent <─stdout── MCP Server
                          │
                     middleware chain
                   [auth] [guard] [log]
  • shield-agent runs the MCP server as a child process
  • Intercepts stdin/stdout and applies the middleware chain
  • stderr passes through unchanged
  • Automatically forwards SIGINT/SIGTERM and propagates exit codes

Case 2: Proxy in front of a remote MCP server (proxy mode)

When you want to add a security layer in front of an already-running MCP server

# Streamable HTTP (default)
shield-agent proxy --listen :8888 --upstream http://localhost:8000

# SSE transport
shield-agent proxy --listen :8888 --upstream http://localhost:8000 --transport sse

# HTTPS
shield-agent proxy --listen :8888 --upstream http://localhost:8000 \
  --tls-cert cert.pem --tls-key key.pem

How it works:

MCP Client ──HTTP──> shield-agent :8888 ──HTTP──> MCP Server :8000
                          │
                     middleware chain
                     monitoring :9090

Case 3: Multiple servers behind a single Gateway (Gateway mode)

When you want to place multiple MCP/API servers behind a single shield-agent endpoint

shield-agent.yaml:

upstreams:
  - name: mcp-server-a
    url: http://10.0.1.1:8000
    match:
      host: mcp-a.example.com       # Host header-based routing
    transport: sse

  - name: api-server-b
    url: http://10.0.2.1:3000
    match:
      path_prefix: /api-b           # Path-based routing
      strip_prefix: true

  - name: default-mcp
    url: http://10.0.3.1:8000       # Fallback when nothing else matches
shield-agent proxy --listen :8888

How it works:

Agent A ──mcp-a.example.com──> shield-agent :8888 ──> MCP Server A
Agent B ──/api-b/v1/data─────> shield-agent :8888 ──> API Server B (/v1/data)
Agent C ──other requests─────> shield-agent :8888 ──> Default MCP
  • Routing by Host header or URL path prefix
  • Match priority: Host+Path > Host only > Path only > fallback
  • With strip_prefix: true, the prefix is stripped before forwarding to upstream
  • Upstreams can be added/removed dynamically from the Web UI (/ui)

Case 4: Deploy with Docker Compose

services:
  shield:
    image: ghcr.io/itdar/shield-agent:latest
    command: proxy --listen :8888 --upstream http://mcp-server:8000
    ports:
      - "8888:8888"
      - "9090:9090"
    volumes:
      - ./shield-agent.yaml:/shield-agent.yaml:ro
      - ./keys.yaml:/keys.yaml:ro
      - shield-data:/data
    environment:
      - SHIELD_AGENT_DB_PATH=/data/shield-agent.db

  mcp-server:
    image: your-mcp-server:latest

volumes:
  shield-data:

Case 5: Control agent access with tokens

When you want to issue tokens like API keys to external agents and manage their quotas

# Issue a token
shield-agent token create --name "partner-agent" --quota-hourly 1000
# → Token: a3f8c1...  (shown only once — store it safely)

# List tokens
shield-agent token list

# Check usage
shield-agent token stats <token-id> --since 24h

# Revoke a token (takes effect immediately)
shield-agent token revoke <token-id>

Agents include the token in the request header:

Authorization: Bearer a3f8c1...

Authentication Method Selection Guide

shield-agent supports 3 authentication methods. Choose the one that fits your situation:

┌─────────────────────────────────────────────────────────────────┐
│ Ed25519 + keys.yaml    — high security, small number of agents  │
│ Ed25519 + DID          — open ecosystem, no pre-registration    │
│ Bearer Token           — simple, like an API key, quota support │
└─────────────────────────────────────────────────────────────────┘
Ed25519 + keys.yaml Ed25519 + DID Bearer Token
Who creates the key Agent generates, admin registers Agent generates, no registration needed Admin issues
Pre-registration Required (keys.yaml or Web UI) Not required Token must be distributed
Per-request signing Yes Yes No
Token theft risk Private key must be stolen (hard) Private key must be stolen Token theft is sufficient
Quota/expiry No No Yes (hourly/monthly)
Immediate revocation Delete from keys.yaml Add to blocklist token revoke (instant)
Recommended for 5–10 internal agents Many agents, open ecosystem External partners, API key-style

Registration via keys.yaml

# keys.yaml
keys:
  - id: "agent-1"
    key: "base64-encoded-Ed25519-public-key"

Agent includes this in JSON-RPC params when making requests:

{
  "method": "tools/list",
  "params": {
    "_mcp_agent_id": "agent-1",
    "_mcp_signature": "hex-encoded-signature"
  }
}

Register keys via Web UI (instead of keys.yaml)

From the Web UI at /ui, use the Agent Keys menu to register or remove public keys. Keys are looked up from both keys.yaml and the DB, so either location works.

DID method (no pre-registration required)

When an agent uses an ID in the format did:key:z6Mk..., the public key is extracted directly from the ID. No keys.yaml registration needed — well-suited for large-scale agent environments.

Security modes

Mode Behavior
open (default) Passes through even without a signature, only logs a warning
verified Valid signature required; unregistered DIDs are OK (but can have differential rate limits)
closed Only registered agents can access
# shield-agent.yaml
security:
  mode: verified
  did_blocklist:            # Block only malicious DIDs (not an allowlist)
    - "did:key:z6Mk..."

Deployment Patterns

Pattern 1: Sidecar (one per server)

[Agent] → [shield-agent :8881] → [MCP Server A]
[Agent] → [shield-agent :8882] → [MCP Server B]
  • Simplest architecture
  • Recommended for 2–3 services
  • Each shield-agent handles authentication/logging independently

Pattern 2: Gateway (single central instance)

[Agent A] ──> [shield-agent :8888] ──> [MCP Server A]
[Agent B] ──>       (gateway)     ──> [API Server B]
  • Recommended for 5+ services
  • Auth/tokens/logs managed in one place
  • Host/path routing via upstreams configuration

Pattern 3: nginx + shield-agent

[Agent] → [nginx (TLS)] → [shield-agent :8888 (HTTP)] → [upstream]
  • TLS termination handled by nginx
  • shield-agent operates over HTTP only
  • No need for --tls-cert/--tls-key configuration

Centralized monitoring (even with sidecars)

[shield-agent A :9090/metrics] ──┐
[shield-agent B :9091/metrics] ──┼── Prometheus ──> Grafana
[shield-agent C :9092/metrics] ──┘

When Prometheus scrapes /metrics from each shield-agent, you can centrally view request counts, error rates, and latency across all services even in a sidecar architecture.


Configuration Reference

Priority: CLI flags > environment variables (SHIELD_AGENT_*) > YAML config > defaults

Copy shield-agent.example.yaml to shield-agent.yaml to get started.

Key settings

Setting Default Environment variable Description
security.mode open SHIELD_AGENT_SECURITY_MODE open / verified / closed
security.key_store_path keys.yaml SHIELD_AGENT_KEY_STORE_PATH Path to public key file
security.did_blocklist [] List of DIDs to block
storage.db_path shield-agent.db SHIELD_AGENT_DB_PATH SQLite DB path
storage.retention_days 30 SHIELD_AGENT_RETENTION_DAYS Log retention in days
server.monitor_addr 127.0.0.1:9090 SHIELD_AGENT_MONITOR_ADDR Monitoring/UI address
logging.level info SHIELD_AGENT_LOG_LEVEL debug/info/warn/error
logging.format json SHIELD_AGENT_LOG_FORMAT json / text

Middleware configuration

middlewares:
  - name: auth
    enabled: true
  - name: guard
    enabled: true
    config:
      rate_limit_per_min: 60          # Per-method requests per minute
      max_body_size: 65536            # Maximum request body size (bytes)
      ip_blocklist: ["203.0.113.0/24"]
      ip_allowlist: ["10.0.0.0/8"]    # Empty means allow all
      brute_force_max_fails: 5        # Auto-block after 5 consecutive failures
      validate_jsonrpc: true          # Reject malformed JSON-RPC
  - name: token
    enabled: false                    # Token middleware (enable if needed)
  - name: log
    enabled: true

CLI flags

Flag Description
--config <path> Config file path (default: shield-agent.yaml)
--log-level <level> Log level
--verbose Alias for --log-level debug
--monitor-addr <addr> Monitoring address
--disable-middleware <name> Disable a middleware
--enable-middleware <name> Enable a middleware

SIGHUP hot reload

Change configuration without restarting the process:

kill -HUP $(pgrep shield-agent)

The middleware chain, keys.yaml, and DID blocklist will be reloaded.


Monitoring

Endpoints

Path Description
/healthz Health check (healthy / degraded)
/metrics Prometheus metrics
/ui Web UI dashboard

Prometheus metrics

Metric Type Labels
shield_agent_messages_total Counter direction, method
shield_agent_auth_total Counter status
shield_agent_message_latency_seconds Histogram method
shield_agent_child_process_up Gauge
shield_agent_rate_limit_rejected_total Counter method

Log query CLI

shield-agent logs                              # Last 50 entries
shield-agent logs --last 100                   # Last 100 entries
shield-agent logs --agent <id> --since 1h      # Specific agent, last 1 hour
shield-agent logs --method tools/call           # Specific method
shield-agent logs --format json                # JSON output

Web UI

Access at http://localhost:9090/ui.

  • Initial password: admin (forced change on first login)
  • Dashboard: Real-time request count, error rate, average latency
  • Logs: Filterable audit log table
  • Token management: Issue/revoke tokens, usage statistics
  • Middleware: On/off toggles (persisted across restarts)
  • Agent Keys: Register/remove public keys (manage via Web UI without keys.yaml)
  • Upstreams: Add/edit/remove Gateway mode upstreams

Roadmap

See ROADMAP.md for details.

Phase Status Description
Phase 1 — Core MVP Done Transport, Auth, Guard, Log, Middleware Chain
Phase 2 — Deployment & Installation Done Docker, Homebrew, GoReleaser, CI/CD
Phase 3 — Token & Web UI Done Token management, Web UI dashboard
Phase 3.5 — Gateway & DID Done Multi-upstream routing, DID blocklist, verified mode
Phase 4 — Advanced Planned Agent reputation, protocol auto-detection, WebSocket

License

MIT

About

RUA, A high-performance Go middleware for AI Agent identity verification and traffic interception.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors