Skip to main content

CapForge

Agent Capability Manifest (ACM) SDK — a standard for binding AI agent identity to authorized capabilities.

License Python 3.12+ Ruff Mypy CI

Version: 0.5.0 | Phase: 5 (Production Showcase) ✅ | Status: Alpha

CapForge is the OAuth for AI agents — a standard way for agents to declare who they are, what they're allowed to do, who is responsible for them, and what limits they operate within.

pip install capforge
capforge keygen --output my-key
capforge create --spiffe-id spiffe://org/agent/bot --sponsor user@org.com \
                --capability knowledge_base:read --key-file my-key.pem
from capforge import ACM, Capability, Constraints

manifest = ACM.create(
    spiffe_id="spiffe://org/agent/bot",
    sponsor="user@org.com",
    capabilities=[Capability(resource="kb", action="read")],
)
manifest.sign("my-key.pem").save("manifest.json")

loaded = ACM.load("manifest.json")
loaded.verify(trusted_keys=["my-key.pub"])

Why CapForge?

When an AI agent executes in production, there is no standard way to answer:

  • Who is this agent? (identity)
  • What is it allowed to do? (authorization scope)
  • Who is responsible for its actions? (accountability)
  • What are its limits? (constraints)
  • Can I verify this cryptographically? (integrity)

Teams today solve this ad-hoc: hardcoded API keys, custom middleware, manual review. This doesn't scale to multi-agent, cross-organization, or regulated environments. CapForge fills this gap with the Agent Capability Manifest (ACM) — a lightweight, verifiable authorization document format.

Design Philosophy

  • Minimal — Defines only what existing standards (SPIFFE, OPA, RATS, OTel) do not cover.
  • Composable — Composes with existing infrastructure rather than replacing it.
  • Verifiable — Every ACM document is cryptographically signed via Ed25519.
  • Scopable — Delegation chains can only narrow scope, never expand it.
  • Framework-agnostic — Works with LangGraph, CrewAI, AutoGen, or custom agents.

Documentation

Document Purpose
SPECIFICATION.md ACM protocol specification v1.0 (canonical)
SPEC.md Protocol specification (alias)
ARCHITECTURE.md Module design, data flow, design principles
DECISIONS.md 13 Architecture Decision Records
ROADMAP.md Phased milestones through standardization
CHANGELOG.md Version history (v0.1.0 → v0.5.0)
SECURITY.md Security policy and vulnerability reporting
CONTRIBUTING.md Contribution guidelines

Quick Start

1. Install

pip install capforge

2. Generate a signing key

capforge keygen --output ./my-agent-key
# -> Private key: my-agent-key.pem
# -> Public key:  my-agent-key.pub

3. Create and sign an ACM document

capforge create \
  --spiffe-id spiffe://acme-corp.com/agent/support-bot \
  --sponsor alice@acme-corp.com \
  --capability knowledge_base:read \
  --capability tickets:read \
  --capability tickets:write \
  --constraint max_cost_per_session=0.05 \
  --constraint disallowed_tools=delete_user \
  --key-file ./my-agent-key.pem \
  --output manifest.json

4. Verify the signed document

capforge verify manifest.json --trusted-roots my-agent-key.pub
# -> Verification PASSED (signature valid)
# -> Agent:       spiffe://acme-corp.com/agent/support-bot
# -> Sponsor:     alice@acme-corp.com
# -> Capabilities: 3
# -> Expires at:  2026-07-22T12:00:00+00:00

5. Delegate scope to a sub-agent

capforge delegate \
  --parent manifest.json \
  --child-spiffe-id spiffe://acme-corp.com/agent/search-worker \
  --capability knowledge_base:read \
  --output delegated.json

Framework Integrations

CapForge provides tools to protect agent execution across multiple AI frameworks.

LangGraph

Wrap LangChain tools with ACM authorization checks:

from capforge_langgraph import ACMControlledTool, wrap_tools

wrapped = ACMControlledTool(
    tool=search_kb,
    acm=acm,
    resource="knowledge_base",
    action="read",
)
# Every call checks ACM validity + capability
result = wrapped.invoke({"query": "ACM protocol"})

Full example: examples/langgraph/

CrewAI

Wrap CrewAI tools with ACM authorization:

from capforge import ACM
from examples.crewai.acm_controlled_crew import ACMControlledCrewTool

safe_tool = ACMControlledCrewTool(
    tool=SearchKnowledgeBase(),
    acm=acm,
    resource="knowledge_base",
    action="read",
)
result = safe_tool(query="ACM protocol")

Full example: examples/crewai/

FastAPI

Protect API endpoints with ACM dependencies:

from fastapi import Depends
from typing import Annotated

@app.get("/agents/{agent_id}")
async def get_agent(
    agent_id: str,
    acm: Annotated[ACM, Depends(require_capability("agent", "read"))],
):
    return {"agent_id": agent_id, "authorized_by": acm.sponsor}

Full example: examples/fastapi/

OpenAI Agents SDK

Wrap function tools with ACM checks:

class ACMControlledFunctionTool:
    def __call__(self, *args, **kwargs):
        if not self.acm.check(self.resource, self.action).allowed:
            raise PermissionError("ACM denied")
        return self.fn(*args, **kwargs)

Full example: examples/openai_agents/


Python SDK

from capforge import ACM, Capability, Constraints
from datetime import UTC, datetime, timedelta

# Create a new manifest
manifest = ACM.create(
    spiffe_id="spiffe://org/agent/my-bot",
    sponsor="dev@org.com",
    capabilities=[Capability(resource="kb", action="read")],
    constraints=Constraints(max_cost_per_session=0.05),
    issuer="spiffe://org/user/dev",
)

# Sign it
manifest.sign("my-key.pem")

# Save to file
manifest.save("manifest.json")

# Load and verify
loaded = ACM.load("manifest.json")
loaded.verify(trusted_keys=["my-key.pub"])
print(f"Valid: {loaded.is_valid()}")
print(f"Agent: {loaded.spiffe_id}")

# Check capabilities
if loaded.has_capability("kb", "read"):
    print("Agent can read the knowledge base")

# Delegate scope
child = loaded.delegate(
    child_spiffe_id="spiffe://org/agent/sub-worker",
    capabilities=[Capability(resource="kb", action="read")],
    key="my-key.pem",
)
child.save("delegated.json")

SDK Reference

Method Description
ACM.create(spiffe_id, sponsor, capabilities, ...) Create a new manifest
ACM.load(source) Load from file or dict
manifest.save(path) Save to file (returns JSON string)
manifest.sign(key) Sign with Ed25519 key (PEM path or key object)
manifest.verify(trusted_keys=...) Verify temporal validity + optional signature
manifest.delegate(child_id, caps, ...) Create delegated manifest with narrowed scope
manifest.check(resource, action, ...) Runtime authorization decision
manifest.has_capability(resource, action) Check if a capability exists
manifest.get_capability(resource, action) Get a capability by resource and action
manifest.is_valid() Check if within temporal validity window
manifest.to_dict() Export as dictionary
manifest.to_json() Export as JSON string

CLI Reference

Command Description
capforge keygen --output <prefix> Generate Ed25519 key pair
capforge create --spiffe-id --sponsor --capability ... Create and optionally sign an ACM
capforge verify <file> --trusted-roots <pubkey> Verify ACM (temporal + crypto)
capforge validate <file> Validate ACM (temporal + structural only)
capforge info <file> Display human-readable ACM info
capforge delegate --parent --child-spiffe-id --capability Create delegated ACM
capforge --help Show help
capforge --version Show version

Full CLI workflow: examples/cli/


Runtime Policy Engine

CapForge includes a runtime authorization engine that evaluates "may this action execute right now?" — not just "does this capability exist?".

from capforge import ACM, Capability, Constraints

manifest = ACM.create(
    spiffe_id="spiffe://org/agent/bot",
    sponsor="user@org.com",
    capabilities=[Capability(resource="github", action="search")],
    constraints=Constraints(
        max_cost_per_session=0.50,
        max_tokens_per_session=100_000,
        allowed_models=["gpt-5"],
        disallowed_tools=["delete_repo"],
        max_execution_seconds=300,
    ),
    ttl=3600,
)

# Authorized action
result = manifest.check(
    resource="github", action="search",
    tool="search_code", cost=0.02,
    session_cost=0.10, session_tokens=500,
    model="gpt-5", execution_seconds=10,
)

if result.allowed:
    print(f"Allowed. Remaining budget: {result.remaining_budget}")
else:
    print(f"Denied: {result.reason} (constraint: {result.failed_constraint})")

# Unauthorized action
result = manifest.check(resource="github", action="delete_repo")
print(result.allowed)  # False

Full example: examples/policy/


CI/CD Integration

Verify ACM documents as a deployment gate in GitHub Actions:

- name: Verify ACM signature
  run: |
    capforge verify manifests/agent-acm.json \
      --trusted-roots manifests/trusted-roots.pub

- name: Check required capabilities
  run: |
    python -c "from capforge import ACM; m = ACM.load('manifest.json'); ...

Full workflow: examples/github_actions/


Benchmarks

Core operation performance at varying manifest sizes:

Operation n=1 n=10 n=100 n=1000
Manifest load ~5 us ~10 us ~57 us ~837 us
Signature verify ~147 us ~173 us ~307 us ~1838 us
ACM.check() ~3 us ~3 us ~3 us ~3 us
Delegation ~80 us ~81 us ~89 us ~160 us

Run benchmarks: python benchmarks/acm_benchmarks.py


Features

Feature Status
Protocol specification (ACM v1.0)
JSON Schema (Draft 2020-12)
Ed25519 cryptographic signing
Canonical JSON serialization
Temporal validation (expiry, not-before)
Delegation with scope narrowing
ACM.create() factory
ACM.load() from file or dict
manifest.save() to file
manifest.sign() with key or PEM path
manifest.verify() temporal + crypto
manifest.delegate() scope narrowing
Capability lookup (has_capability, get_capability)
Constraint access (constraints_obj property)
Click CLI (6 commands)
Core test suite (56 tests)
ruff + mypy --strict
CI pipeline (GitHub Actions)
LangGraph adapter (capforge_langgraph)
ACMControlledTool — ACM-checked tool wrapper
wrap_tools() — multi-tool wrapper
Adapter tests (10 tests)
Runtime policy engine (ACM.check())
PolicyDecision structured result
Cost budget evaluation
Token budget evaluation
Model restriction checking
Blocked tool checking
Execution timeout checking
Policy tests (34 tests)
CrewAI example
FastAPI example
OpenAI Agents SDK example
CLI workflow example
GitHub Actions CI example
Performance benchmarks

Project Structure

capforge/
├── __init__.py              # Public API exports
├── _acm.py                  # ACM class (create, load, sign, verify, delegate)
├── _model.py                # Pydantic models (Capability, Constraints)
├── _crypto.py               # Ed25519 signing/verification
├── _policy.py               # Runtime policy engine
├── _validator.py            # Temporal + delegation validation
├── _delegation.py           # Delegation scope narrowing
├── _exceptions.py           # Exception hierarchy
├── _version.py              # Package version
├── py.typed                 # PEP 561 type marker
└── cli/
    ├── __init__.py
    └── main.py              # Click CLI (6 commands)

tests/                       # 100 tests total
├── test_acm.py              # 30 tests
├── test_crypto.py           # 14 tests
├── test_validator.py        # 5 tests
├── test_model.py            # 7 tests
├── test_policy.py           # 34 tests
└── test_langgraph_adapter.py # 10 tests

capforge_langgraph/          # LangGraph adapter (separate package)
├── __init__.py
├── _tool_wrapper.py
└── pyproject.toml

examples/                    # Production showcase
├── langgraph/               # LangGraph integration
│   ├── basic_acm_agent.py
│   ├── README.md
│   └── requirements.txt
├── crewai/                  # CrewAI integration
│   ├── acm_controlled_crew.py
│   ├── README.md
│   └── requirements.txt
├── fastapi/                 # FastAPI + ACM dependencies
│   ├── acm_protected_api.py
│   ├── README.md
│   └── requirements.txt
├── openai_agents/           # OpenAI Agents SDK integration
│   ├── acm_controlled_agent.py
│   ├── README.md
│   └── requirements.txt
├── cli/                     # CLI workflow
│   ├── run_cli_examples.sh
│   └── README.md
├── github_actions/          # CI/CD verification
│   ├── verify_acm.yml
│   └── README.md
└── policy/                  # Runtime policy engine
    ├── runtime_checks.py
    ├── README.md
    └── requirements.txt

benchmarks/
├── acm_benchmarks.py        # Performance benchmarks
└── README.md

spec/
├── acm-schema.json           # JSON Schema (Draft 2020-12)
└── examples/
    ├── valid-acm.json
    ├── minimal-acm.json
    └── expired-acm.json

Progress

Area Status
Protocol specification ✅ 100%
JSON Schema ✅ 100%
Pydantic data models ✅ 100%
Ed25519 cryptography ✅ 100%
Temporal validation ✅ 100%
Delegation chain ✅ 100%
Public API (ACM.create, .sign, .verify, etc.) ✅ 100%
Click CLI (6 commands) ✅ 100%
Test suite (100 tests) ✅ 100%
ruff + mypy strict ✅ 100%
CI pipeline ✅ 100%
LangGraph adapter ✅ 100%
Runtime policy engine ✅ 100%
Framework examples (CrewAI, FastAPI, OpenAI) ✅ 100%
CLI workflow example ✅ 100%
GitHub Actions CI example ✅ 100%
Performance benchmarks ✅ 100%

Roadmap

Phase 1 ─── Foundation + Specification               ✓  (v0.1.0)
Phase 2 ─── Cryptography + CLI Enhancement            ✓  (v0.2.0)
Phase 3a ── CapForge SDK                              ✓  (v0.3.0)
Phase 3b ── LangGraph adapter                         ✓
Phase 4 ─── Runtime Policy Engine                     ✓  (v0.4.0)
Phase 5 ─── Production Showcase                       ✓  (v0.5.0)  ← You are here
Phase 6 ─── Standardization                           ⬜

Contributing

See CONTRIBUTING.md for guidelines.

  • Report bugs: GitHub Issues
  • Discuss ideas: GitHub Discussions
  • Security vulnerabilities: See SECURITY.md

License

Apache License 2.0


Built for the AI agent ecosystem.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

capforge-0.4.1.tar.gz (92.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

capforge-0.4.1-py3-none-any.whl (32.7 kB view details)

Uploaded Python 3

File details

Details for the file capforge-0.4.1.tar.gz.

File metadata

  • Download URL: capforge-0.4.1.tar.gz
  • Upload date:
  • Size: 92.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for capforge-0.4.1.tar.gz
Algorithm Hash digest
SHA256 65300bdab095d634a559332b098c381d04c2978ae2b5f2a7bd08a31b3b3ca9e2
MD5 1cb1b393078142ecf62fbd3161b5c526
BLAKE2b-256 cdb87b98973a374a3068a7c5a81d2ac441c3650a861b4b18a852933c8ab1b40b

See more details on using hashes here.

File details

Details for the file capforge-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: capforge-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 32.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for capforge-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4b06eb6cac8cf5dc5acabcad80393a037d9e1dbe72fd61f92e021954ec4edcb6
MD5 15e577fd5653be271ce29bf1d80ac0c0
BLAKE2b-256 77e0a9049b85a3dbc7ef20ed7588f74da29776e5d16c1ee69174328473a6fc1d

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.1

2 files

0.6.0

2 files

This release

0.4.1 This release

2 files

0.4.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page