Catalog PyPI
PACKAGE EXPLORERView in registry

agentis-verify

PyPI

FastAPI middleware for verifying agent requests using the Agentis identity platform

Versions collected1
Direct dependencies7From release 0.1.0
Last observed20 Oct, 22:28 UTC

README

Version 0.1.0 documentation

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:

OptionDefaultDescription
base_url"https://agentis-id.vercel.app"Base URL of the Agentis API
cache_ttl_seconds60How long to cache agent lookups
timeout_seconds10HTTP timeout for Agentis API calls
min_verification_tier1Minimum 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

ExceptionHTTP statusMeaning
AgentisVerificationError401 (or 403 for capability)Verification failed. The reason attribute describes what went wrong.
AgentisUnavailableError503The 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.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.03 Jun 20267

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 22:28 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:c2afe17d83b04e93263aec49fcc2f76cbd4a707df49481ba26f4ff36d4a31e53