Skip to content

Repository files navigation

Patroclus Logo

Patroclus

Scoped, time-limited authorization infrastructure for AI agents.

In the Iliad, Achilles delegated his armor and authority to Patroclus with explicit scope: drive the Trojans from the ships, then return. Patroclus exceeded his scope, pursued too far, and the consequences were catastrophic. Patroclus (the project) ensures that never happens to your AI agents.


What is this?

Patroclus is a self-hostable authorization control plane for AI agents. It sits between agents and the resources they need to access — APIs, MCP servers, databases, cloud services — and enforces scoped, time-limited, revocable permissions with human-in-the-loop approval workflows.

Agents today are handed static API keys and long-lived tokens. Patroclus replaces that with just-in-time access: an agent requests access to a specific resource for a specific action, policies are evaluated in real-time, and either a short-lived scoped credential is issued or a human approval is triggered.

Capabilities

Core Authorization

  • Just-in-time token issuance — agents get scoped, short-lived JWTs (5–15 min) only when policy allows it. No standing permissions.
  • Default-deny — no matching policy means deny, always
  • Per-call policy evaluation — every action checked against policy in real-time
  • Hot-reloadable policies — create/update policies without server restart

Delegated Authorization

  • Human delegation — humans delegate scoped permissions to agents with constraints (max spend, time windows, etc.)
  • Multi-agent delegation — agents sub-delegate with monotonic attenuation (scopes can only narrow, never widen)
  • Delegation depth limits — configurable max chain depth
  • Cascade revocation — revoking a parent grant atomically invalidates all children and issued tokens

Approval Workflow

  • Human-in-the-loop — sensitive actions trigger approval requests routed to resource owners or admins
  • Single-use approval tokens — approved requests get one-time, action-scoped tokens
  • Approval lifecycle — pending → approved/denied, with expiry and status lookup

Advanced Policy Engine

  • YAML rules with pattern matching (dev-*, api:*, *)
  • Rate limiting — per agent/action/resource sliding window
  • Budget caps — deny after cumulative spend exceeds limit
  • Progressive trust decay — auto-tighten permissions after idle time
  • Workflow sequencing — require prior action in session trajectory
  • Max actions per session — cap total actions in a session
  • Pluggable backends — OPA/Rego and Cedar ready (interface defined)

Session Management

  • Per-session trajectory — tracks all actions in a session (capped at 1000)
  • Kill switch — emergency agent termination kills all sessions + revokes tokens
  • Spend tracking — record and accumulate spend per session
  • Trust level — starts at 1.0, decays after configurable idle threshold

Credential Vault

  • AES-256-GCM encryption at rest for upstream provider credentials
  • OAuth provider integrations — GitHub, Google, Slack refresh token exchange
  • Token vending — agents get scoped access tokens, never see raw secrets
  • Per-principal isolation — each principal's credentials stored separately

Token Security

  • JWT RS256 with agent-specific claims (sub, act, scope, aud, jti)
  • Audience binding (RFC 8707) — tokens bound to specific resources
  • Replay protection — JTI tracking with in-memory revocation store
  • Token revocation — by JTI, with DB persistence
  • DPoP ready — proof-of-possession support (interface defined)

Audit & Compliance

  • Hash-chained audit log — SHA-256 chain, tamper-evident
  • Chain verifier — patroclus verify-chain recomputes the chain and reports the first broken link (exit code 1 on tamper, --json for machines)
  • Every decision logged — allow, deny, require_approval with full context; dry-run /v1/agent/check decisions audited with a dry_run flag
  • Attribution-complete — every action traces to human or system authority
  • Delegation chain in log — full chain captured, not reconstructed

MCP Gateway Integration

  • Relay integration — Relay MCP gateway calls Patroclus before every tool dispatch
  • Per-tool authorization — each MCP tools/call checked against policy
  • Fail-closed — if Patroclus is unreachable, tool calls are denied

IdP Federation

  • OIDC integration — Okta, Azure AD, Google Workspace, Auth0, any OIDC provider
  • Group-based policy mapping — IdP groups map to Patroclus policies (e.g., "Engineering" group → dev access policy)
  • Token exchange — RFC 8693 token exchange from IdP token → Patroclus delegation token
  • Auto-provisioning — principals auto-created on first IdP login

Agent Supply Chain Security

  • Forge integration — Forge verifies agent signatures, generates SBOMs, scans for vulnerabilities, and calculates trust scores
  • Trust-based policies — Patroclus policies can reference Forge trust scores (min_trust_score)
  • Blocking — agents with critical vulnerabilities are blocked from registration

Operational Hardening

  • Non-blocking SQLite access — all database calls run on tokio's blocking pool (spawn_blocking) with WAL + busy_timeout tuning; optional r2d2 read pool via [database] read_pool_size — see docs/DATABASE_CONCURRENCY.md
  • Prometheus metrics — /metrics exposes authz decision counters, request latency histograms, session/approval-depth gauges and token issuance — see docs/METRICS.md

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        PATROCLUS                                     │
│                                                                      │
│  ┌──────────┐   ┌──────────────┐   ┌─────────────┐   ┌──────────┐  │
│  │  Agent    │──▶│  Request     │──▶│  Policy     │──▶│ Decision │  │
│  │  Runtime  │   │  Gateway     │   │  Engine     │   │  Router  │  │
│  └──────────┘   └──────────────┘   └─────────────┘   └─────┬────┘  │
│                       │                                      │       │
│                       │              ┌────────────┐    ┌─────▼────┐  │
│                       │              │  Approval  │    │  Token   │  │
│                       │              │  Service   │◀──│  Issuer  │  │
│                       │              └──────┬─────┘    └─────┬────┘  │
│                       │                     │                │       │
│  ┌──────────┐    ┌────▼─────┐   ┌───────────┴──┐    ┌───────▼────┐ │
│  │  Human   │◀───│  Notify  │   │  Audit Log    │   │  Credential│ │
│  │  Approver│───▶│  Service │   │  (Hash-chain) │   │  Vault     │ │
│  └──────────┘    └──────────┘   └──────────────┘   └────────────┘ │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │     Policy Store (YAML)  │  Session Store  │  Resource Registry│   │
│  └──────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

Quick Start

# Build
cargo build --release

# Initialize config
./target/release/patroclus init

# Generate RSA keys for token signing
./target/release/patroclus generate-keys -o keys

# Start the server
./target/release/patroclus serve --config config.toml

# Verify the audit hash chain (tamper detection)
./target/release/patroclus verify-chain --db patroclus.db

Configuration

Configuration lives in config.toml (see patroclus init) and can be overridden by environment variables. Layering: file < environment — an environment variable always wins over the file value.

Environment variables

Every config field can be overridden with PATROCLUS_<SECTION>__<FIELD> (double underscore as the nesting separator, case-insensitive). Values are parsed as TOML scalars (numbers, booleans, and [...] arrays); anything else is taken as a literal string. Unknown variables are ignored with a warning. This is the supported channel for injecting secrets (key paths, IdP client secrets) in container deployments without baking them into the file.

Variable Overrides Example
PATROCLUS_SERVER__HOST server.host 0.0.0.0
PATROCLUS_SERVER__PORT server.port 8484
PATROCLUS_SERVER__CORS_ALLOWED_ORIGINS server.cors_allowed_origins ["https://console.example.com"]
PATROCLUS_DATABASE__PATH database.path /var/lib/patroclus/patroclus.db
PATROCLUS_DATABASE__READ_POOL_SIZE database.read_pool_size 4
PATROCLUS_TOKEN__ISSUER token.issuer https://patroclus.example.com
PATROCLUS_TOKEN__PRIVATE_KEY_PATH token.private_key_path /run/secrets/private.pem
PATROCLUS_TOKEN__PUBLIC_KEY_PATH token.public_key_path /run/secrets/public.pem
PATROCLUS_TOKEN__DEFAULT_TTL_SECONDS token.default_ttl_seconds 900
PATROCLUS_TOKEN__MAX_TTL_SECONDS token.max_ttl_seconds 3600
PATROCLUS_POLICY__ENGINE policy.engine yaml
PATROCLUS_POLICY__DEFAULT_DECISION policy.default_decision deny
PATROCLUS_POLICY__MAX_DELEGATION_DEPTH policy.max_delegation_depth 3
PATROCLUS_VAULT__ENCRYPTION_KEY_PATH vault.encryption_key_path /run/secrets/vault.key

Related (non-config) variables used by other subsystems:

Variable Purpose
PATROCLUS_ADMIN_TOKEN Static admin bearer token for /v1/admin/* (required in release builds)
PATROCLUS_INSECURE_DEV 1 permits unauthenticated admin routes / insecure dev keys (never production)
PATROCLUS_LOG_FORMAT json switches logs to JSON

Example:

PATROCLUS_SERVER__PORT=9000 \
PATROCLUS_DATABASE__PATH=/data/patroclus.db \
PATROCLUS_ADMIN_TOKEN="$(openssl rand -hex 32)" \
./target/release/patroclus serve --config config.toml

Python SDK

pip install -e sdk/python
from patroclus_sdk import PatroclusClient, authorized_action

client = PatroclusClient("http://localhost:8484")

# Register agent
agent = client.register_agent("my-agent", owner_id=principal["id"])

# Create policy
client.create_policy("dev-access", """
- name: allow-dev-reads
  actions: ["read"]
  resources: ["dev-*"]
  scopes: ["*"]
  decision: allow
  reason: Dev read access permitted
""")

# Check access
result = client.request_access(agent["id"], "read", "dev-db", ["db:read"])
if result.allowed:
    print(f"Token: {result.token}")  # JWT with 15-min TTL

# Or use the decorator
@authorized_action(client, action="read", resource="dev-db", scopes=["db:read"])
def fetch_users(agent_id, patroclus_token=None):
    return call_database(patroclus_token)

Real Agent Demo

# Start Patroclus
./target/release/patroclus serve

# Run the agent (requires OPENROUTER_API_KEY)
OPENROUTER_API_KEY=your-key python examples/agent.py

The agent:

  1. Registers itself with Patroclus
  2. Creates a policy
  3. Asks the LLM (via OpenRouter) what actions to take
  4. Before each action, checks with Patroclus for authorization
  5. If allowed, gets a scoped JWT token
  6. If denied, reports the reason (rate limit, policy deny, etc.)
  7. If approval required, creates an approval request

API Overview

Category Endpoints
Agent-facing POST /v1/agent/request-access, POST /v1/agent/check, POST /v1/agent/delegate
Principal-facing POST /v1/principal/delegate, GET /v1/principal/approvals, POST /v1/principal/approvals/{id}/approve
Admin POST /v1/admin/agents, POST /v1/admin/policies, GET /v1/admin/audit
Sessions GET /v1/sessions, POST /v1/sessions/{id}/kill, POST /v1/admin/agents/{id}/kill
Vault POST /v1/vault/credentials, POST /v1/vault/vend
Health GET /health

See docs/LLD.md for the full API specification.

Token Model

{
  "iss": "https://patroclus.example.com",
  "sub": "user:alice@example.com",
  "act": { "sub": "agent:agent_001", "delegation_depth": 0 },
  "scope": "db:read:prod-db/users",
  "aud": "resource:prod-db",
  "exp": 1723643820,
  "jti": "01J5Q3Z...",
  "constraints": { "max_rows": 1000 }
}

Policy Example

- name: allow-dev-reads
  actions: ["read", "query"]
  resources: ["dev-*", "test-*"]
  scopes: ["*"]
  decision: allow
  reason: Dev read access permitted

- name: rate-limited-api
  actions: ["call"]
  resources: ["api-*"]
  scopes: ["*"]
  decision: allow
  reason: API access permitted
  rate_limit_per_minute: 5

- name: budget-capped-deploy
  actions: ["deploy"]
  resources: ["cloud-*"]
  decision: allow
  max_spend: 100.0

- name: require-approval-prod
  actions: ["write", "deploy"]
  resources: ["prod-*"]
  decision: require_approval
  reason: Production operations require human approval

- name: workflow-sequenced
  actions: ["execute_trade"]
  resources: ["trading-*"]
  decision: allow
  require_prior_action: "load_profile"

Test Results

Suite Tests Status
Rust unit (session) 10 ✅
Rust integration (Phase 1–4) 40 ✅
Rust integration (Phase 5) 14 ✅
Python SDK 17 ✅
Total 81 All passing
# Run all Rust tests
cargo test

# Run Python SDK tests (requires running server)
cd sdk/python && python -m pytest tests/

Ecosystem

Patroclus is part of the AI governance ecosystem governed through Governance Hub:

Project Role
Hive Agent runtime & orchestration — which agent does the work
Patroclus Authorization infrastructure — is the agent allowed to do this
Relay MCP gateway & tool proxy — route the agent's tool calls
Miser Cost optimization — which model is cheapest for this
Sentiel Observability, DLP & compliance — what are agents doing?
Aegis Network egress & attestation — is the agent's network safe?
Forge Agent supply chain security — is the agent code trusted?
Argus Human/agent OIDC identity provider — who is calling?
Governance Hub Unified admin console and sole product UI

See docs/ECOSYSTEM_PLAN.md for the full integration plan.

Documentation

Future Roadmap

Near-term

  • OPA/Rego policy backend
  • Cedar policy backend
  • PostgreSQL backend (production database)
  • Redis for distributed session state and rate limiting
  • Signed revocation feed (offline verification without callback)
  • DPoP proof-of-possession (RFC 9449)
  • TypeScript/Node SDK
  • Go SDK

Medium-term

  • Admin dashboard (React/Next.js)
  • CLI tool for policy management
  • Helm chart for Kubernetes deployment
  • OAuth 2.1 well-known endpoints (/.well-known/oauth-authorization-server)
  • Dynamic client registration (RFC 7591)
  • Temporal policies (trajectory-aware, like Amazon Bedrock AgentCore)
  • Anomaly detection (behavioral baseline deviation)
  • W3C Verifiable Credentials support

Long-term

  • Multi-tenancy (tenant isolation)
  • SPIFFE/SPIRE workload identity integration
  • Enterprise IdP federation (Okta, Azure AD, Google)
  • Agent-to-agent trust protocol (IATP)
  • Compliance framework mapping (EU AI Act, SOC2, HIPAA)
  • SDK for LangChain, CrewAI, OpenAI Agents SDK, Google ADK

Technology Stack

Component Technology
Language Rust (edition 2024)
Web framework Axum 0.8
Database SQLite (rusqlite, bundled)
Token format JWT RS256 (jsonwebtoken)
Encryption AES-256-GCM (aes-gcm)
Policy engine YAML rules (OPA/Cedar ready)
Python SDK httpx

License

MIT

About

Agentic Infrastructure done right.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages