Zero-trust capability delegation for MCP multi-agent systems.
In today's agent systems, delegation is trust by accident. AgentBond makes it trust by contract.
When an orchestrator agent delegates work to a worker agent, what stops the worker from calling tools it was never authorized to use? From accessing resources outside its scope? From re-delegating its permissions to another agent?
The MCP spec defines the tool protocol. It does not define what a worker is allowed to do with it.
AgentBond fills that gap.
Every agent in AgentBond has a declared role. Every role has a defined scope. Every scope is enforced.
| Role | Name in AgentBond | Responsibility |
|---|---|---|
| Security Orchestrator | orchestrator.py |
Reasons about minimum necessary permissions, issues capability token |
| Worker | worker.py |
Executes assigned task within token scope, reports denials |
| Gatekeeper | delegation/enforcer.py |
Enforces four rules before any tool executes, no exceptions |
| Auditor | audit/log.py |
Records every delegation and attempt in order, immutable |
This pattern is consistent across VPL Solutions products:
- Dead Letter Oracle — Gatekeeper evaluates replay safety before any message is replayed
- Meridian — Confidence gate enforces retrieval quality before any answer is returned
- AgentBond — Enforcement layer gates every tool call before it reaches the underlying tool
The thread: every agent has a declared role, every role has a defined scope, every scope is enforced before action executes.
AgentBond is not an orchestration framework. It is the enforcement layer that sits beneath one.
| Layer | Examples | What it does |
|---|---|---|
| Orchestration | LangGraph, n8n, AutoGen | Defines how agents connect and sequence work |
| Enforcement | AgentBond | Governs what each agent is permitted to do |
| Code generation | Codegen, Cursor | Produces agent code — unrelated to runtime enforcement |
LangGraph defines the graph. AgentBond enforces what each node in that graph can actually call. A LangGraph worker node that receives a capability token cannot exceed the scope that token grants — regardless of what the graph wires up. These are complementary, not competing.
The orchestrator issues a capability token — a signed JWT scoped to specific tools, specific resources, and a TTL. The worker presents the token when invoking tools. The enforcement layer checks four rules before any tool executes:
- Token signature valid
- Token not expired
- Tool name in
allowed_tools - Resource arguments match
resource_scope
Re-delegation is blocked unless the token explicitly permits it.
Every delegation and every invocation attempt is recorded in a structured audit log.
Orchestrator issues token:
worker=worker-agent-001
allowed_tools=[read_customer_record]
resource_scope={customer_id: "123"}
ttl=300s, re_delegation=false
[1] DELEGATION orchestrator -> worker-agent-001
[2] ATTEMPT ALLOW read_customer_record(customer_id=123)
[3] ATTEMPT DENY write_customer_record TOOL_NOT_IN_SCOPE
[4] ATTEMPT DENY read_customer_record(456) RESOURCE_OUT_OF_SCOPE
[5] ATTEMPT DENY delegate_capability(rogue) RE_DELEGATION_DENIED
Run it:
python main.pyFour tools exposed via AgentGateway:
| Tool | Type | Description |
|---|---|---|
delegate_capability |
Primitive | Issue a scoped JWT capability token |
invoke_tool |
Primitive | Enforce token, dispatch to underlying tool |
get_audit_log |
Primitive | Return all delegation and attempt events |
run_delegation_demo |
Orchestration | One-call demo: 4 scenarios, full audit trail |
Underlying tools (read_customer_record, write_customer_record, get_order_history) are not on the MCP surface. They are only reachable through invoke_tool.
git clone https://github.com/tvprasad/agentbond
cd agentbond
pip install -r requirements.txt
cp .env.example .envAGENTBOND_SECRET_KEY — signs and verifies all capability tokens (HMAC-SHA256). Must be at least 32 bytes. PyJWT will warn if shorter.
Generate a secure key:
# Python (cross-platform)
python -c "import secrets; print(secrets.token_hex(32))"
# openssl (macOS / Linux)
openssl rand -hex 32Paste the output as the value in .env:
AGENTBOND_SECRET_KEY=<your-generated-key>
A fixed example key is provided in .env.example as a comment for reference (agentbond-demo-secret-key-2026-vpl-001). Do not use it in any environment beyond local development.
ANTHROPIC_API_KEY — required only for the LLM agent demo (python main.py). Not required for the test suite or the AgentGateway demo.
Obtain from: https://console.anthropic.com/settings/api-keys
ANTHROPIC_API_KEY=sk-ant-...
python main.pypython -m mcp_serveragentgateway -f agentgateway/config.yaml
# Playground at http://localhost:15000/ui
# Tools at http://localhost:3000/Open the playground, connect to http://localhost:3000/, select run_delegation_demo, invoke with {}. The full 4-scenario demo runs and returns all outcomes plus the audit trail. No CLI required.
JWT, HMAC-SHA256, signed with AGENTBOND_SECRET_KEY.
{
"iss": "orchestrator-agent-001",
"sub": "worker-agent-001",
"jti": "<uuid4>",
"allowed_tools": ["read_customer_record"],
"resource_scope": {"customer_id": "123"},
"re_delegation": false,
"exp": 1234567890,
"iat": 1234567590
}Inspect any token at jwt.io.
AgentBond is published to aregistry.ai as a discoverable MCP server.
The registry entry describes AgentBond's tool surface, enforcement rules, token schema, and runtime invocation — making it discoverable by other agents and teams building on the MCP ecosystem.
Registry metadata: agentregistry-entry.yaml
To use AgentBond from the registry:
# Install agentregistry CLI
brew install solo-io/tap/arctl # macOS
# or download from https://aregistry.ai
# Pull AgentBond
arctl mcp pull agentbond
# Run via AgentGateway
agentgateway -f agentgateway/config.yamlagentbond/
delegation/
token.py JWT issue + verify (PyJWT, HMAC-SHA256)
enforcer.py 4-rule enforcement + re-delegation check
audit/
log.py DelegationAudit: DELEGATION + ATTEMPT events
mcp_server/
models.py Pydantic I/O contracts
underlying.py Deterministic tools (not on MCP surface)
tools.py 4 MCP tool functions
server.py FastMCP registrations
agent/
orchestrator.py Claude reasons about permissions, issues capability token
worker.py Claude tool_use loop; enforcement blocks out-of-scope calls
agentgateway/
config.yaml Port 3000, stdio transport
Four Architecture Decision Records written before any implementation:
| ADR | Decision |
|---|---|
| ADR-001 | Build AgentBond: confused deputy problem is real, unaddressed by MCP spec |
| ADR-002 | PyJWT + HMAC-SHA256: universally understood, inspectable at jwt.io |
| ADR-003 | Enforce inside invoke_tool: audit-precise, self-contained, fully testable |
| ADR-004 | AgentGateway port 3000, run_delegation_demo as first-class orchestration tool |
| ADR-014 | LLM-backed agents — Claude Haiku for orchestrator and worker |
| ADR-015 | Publish AgentBond to agentregistry — YAML metadata entry, Open Source track |
AgentBond addresses a class of problems that arise whenever autonomous agents act on behalf of users or systems in regulated or high-stakes environments:
Healthcare and PBM platforms — A clinical AI agent orchestrator delegates research tasks to sub-agents. Each sub-agent receives a scoped token: allowed to read patient records for a specific patient ID, not write them, not re-delegate to another process. Every access is auditable against HIPAA requirements.
Enterprise AI copilots — A ServiceNow-integrated ops copilot delegates investigation steps to specialist agents (log analysis, metric retrieval, remediation). Each delegation is time-bounded and resource-scoped. No agent can exceed its mandate mid-incident.
Federated multi-agent systems — In a federated architecture where agents span trust boundaries (different teams, cloud accounts, or organizations), capability tokens are the contract that crosses those boundaries. The token is self-describing: any enforcement layer can validate it without calling back to the issuer.
Secure agentic pipelines in regulated industries — Financial services, federal contracting, and defense use cases require that every automated action be traceable to an authorized delegation chain. AgentBond provides that chain as a first-class artifact.
The current implementation handles the core delegation contract. Documented extension points for future iterations:
| Extension | Where it connects |
|---|---|
| Multi-hop delegation chains | parent_delegation_id claim is already stored in the JWT. A chain validator would walk the chain and verify each hop. |
| Token revocation | Add a revocation registry (Redis or a simple DB) checked inside check() before rule 3. The enforcement interface does not need to change. |
| External policy engine | Replace the inline rule checks in enforcer.py with a call to OPA or a custom policy service. EnforcementResult is already the abstraction boundary. |
| Scope narrowing on re-delegation | When re_delegation=True, enforce that the child token's allowed_tools is a strict subset of the parent's. Currently the parent permitting re-delegation is sufficient. |
| Audit persistence | DelegationAudit is in-memory. Swap entries() storage for a database write without changing the calling code. |
pytest -v37 tests: token (8), enforcer (10), tools (12), demo flow (3). LLM-free — no API key required for the test suite.
Python 3.12+, FastMCP (mcp==1.26.0), Pydantic v2, PyJWT, python-dotenv, Anthropic SDK. Enforcement layer is LLM-free — the demo agents use Claude Haiku.
Apache 2.0
Built by Prasad Tiruveedi, VPL Solutions LLC
Submitted to MCP_HACK//26, Secure & Govern MCP track
Thanks to Venkat, Satish, Vijaya, and Ajay for their feedback.