Observed since 20 Oct, 22:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
FastAPI middleware for verifying agent requests using the Agentis identity platform
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.
pip install agentis-verify
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": []}
verify_agent() per routeUse 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}
@require_capability() decoratorProtect 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 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
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,
)
| 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")
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 DIDX-Agent-DPoP: a DPoP proof binding the request to the agent's keyagentis-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.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 3 Jun 2026 | 7 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:c2afe17d83b04e93263aec49fcc2f76cbd4a707df49481ba26f4ff36d4a31e53