Skip to main content

FastAPI middleware for verifying agent requests using the Agentis identity platform

Project description

agentis-verify

agentis-verify is a Python middleware package for FastAPI that verifies incoming agent requests against the Agentis identity platform. When an agent makes an HTTP request signed with proveyouragent, this library fetches the agent's public key and verification metadata from Agentis, validates the DPoP signature on the request, and either passes the request through with verified agent details attached, or rejects it with a clear error response. It handles caching of agent lookups, configurable verification tier requirements, and per-capability access control.

Install

pip install agentis-verify

Quickstart

a. Middleware for all routes

Apply AgentisMiddleware once and every route is protected automatically. The verified agent is available at request.state.agent.

from fastapi import FastAPI, Request
from agentis_verify import AgentisMiddleware, AgentisConfig

app = FastAPI()

app.add_middleware(
    AgentisMiddleware,
    config=AgentisConfig(min_verification_tier=2),
    exclude_paths=["/health", "/docs", "/openapi.json"],
)

@app.get("/invoices")
async def list_invoices(request: Request):
    agent = request.state.agent
    return {"agent": agent.verified_name, "invoices": []}

b. verify_agent() per route

Use verify_agent() when you need per-route control or want to check a specific capability inline.

from fastapi import FastAPI, Request
from agentis_verify import verify_agent

app = FastAPI()

@app.get("/invoices")
async def list_invoices(request: Request):
    agent = await verify_agent(request)
    return {"agent": agent.verified_name, "invoices": []}

@app.post("/payments")
async def process_payment(request: Request):
    agent = await verify_agent(request, required_capability="payments:write")
    return {"processed_by": agent.did}

c. @require_capability() decorator

Protect a route with a single decorator. Returns 403 if the agent lacks the capability, 401 if verification fails.

from fastapi import FastAPI, Request
from agentis_verify import require_capability

app = FastAPI()

@app.get("/payments")
@require_capability("payments:write")
async def process_payment(request: Request):
    agent = request.state.agent
    return {"processed_by": agent.did}

Capabilities

Capabilities are returned as strings for agents registered directly, and as structured objects for agents registered with an A2A Agent Card. agentis-verify handles both formats transparently.

# plain string format (direct registration)
agent.capabilities  # ["invoices:read", "payments:write"]

# structured object format (A2A Agent Card registration)
agent.capabilities  # [{"id": "invoices:read", "description": "Read and list invoices"}]

# use has_capability() to check either format
agent.has_capability("invoices:read")  # True in both cases

Configuration

AgentisConfig controls how the middleware behaves:

Option Default Description
base_url "https://agentis-id.vercel.app" Base URL of the Agentis API
cache_ttl_seconds 60 How long to cache agent lookups
timeout_seconds 10 HTTP timeout for Agentis API calls
min_verification_tier 1 Minimum verification tier required
from agentis_verify import AgentisConfig

config = AgentisConfig(
    base_url="https://agentis-id.vercel.app",
    cache_ttl_seconds=120,
    timeout_seconds=5,
    min_verification_tier=2,
)

Error handling

Exception HTTP status Meaning
AgentisVerificationError 401 (or 403 for capability) Verification failed. The reason attribute describes what went wrong.
AgentisUnavailableError 503 The Agentis API could not be reached.

When using the middleware, these are caught automatically and returned as JSON:

{"detail": "Agent is not active (status: suspended)"}

When calling verify_agent() directly, catch them yourself:

from agentis_verify import AgentisVerificationError, AgentisUnavailableError

try:
    agent = await verify_agent(request)
except AgentisVerificationError as e:
    # e.reason has the message, e.status_code is 401 or 403
    raise HTTPException(status_code=e.status_code, detail=e.reason)
except AgentisUnavailableError:
    raise HTTPException(status_code=503, detail="Identity service unavailable")

How it connects to proveyouragent and Agentis

Agents register on Agentis and receive an Ed25519 keypair and a DID (did:web:agentis.dev:agents:abc123). When making HTTP requests, they use proveyouragent to attach two headers:

  • X-Agent-Statement: a JWT software statement containing the agent's DID
  • X-Agent-DPoP: a DPoP proof binding the request to the agent's key

agentis-verify extracts the DID from the statement, fetches the agent's public key from the Agentis API at GET /api/agents/[did], checks that the agent is active and meets the minimum verification tier, then calls proveyouragent.verify_agent_request() to validate the DPoP proof against the public key. If everything passes, the verified agent is attached to request.state.agent and the request proceeds.

Links

Project details


Download files

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

Source Distribution

agentis_verify-0.1.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

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

agentis_verify-0.1.0-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file agentis_verify-0.1.0.tar.gz.

File metadata

  • Download URL: agentis_verify-0.1.0.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for agentis_verify-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b1e2f6b08d0ec02a3d299445d1f3a2d8e1ddc3b8248f24b79c67d7307a31de6c
MD5 effd3f4ad646078b9c4a4e2b3ca253d8
BLAKE2b-256 0f2a9a33362357192b1e76952527a34f9cd4af884e757b6517e4d36e83758669

See more details on using hashes here.

File details

Details for the file agentis_verify-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agentis_verify-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for agentis_verify-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f1fee51eb226fdc778680b1365b8c3cd0d7dafe122ebbd94d78b3d91025fa1e6
MD5 9c06663e785881c14d601901e335a345
BLAKE2b-256 a46853125fb824ef8b4b1066d89184f354d5a19a33e3687c42d691be1cbdfc7e

See more details on using hashes here.

Supported by

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