Skip to main content

auth-agents

Verify AI agent identities with Agent Auth. DID-based authentication using Ed25519 and Verifiable Credentials.

Install

pip install auth-agents

Quick Start — Verify an Agent Credential

from auth_agents import AuthAgents

client = AuthAgents()

result = client.verify("eyJhbGciOiJFZERTQSJ9...")

if result["valid"]:
    print(result["did"])          # did:key:z6Mk...
    print(result["agent_name"])   # Claude
    print(result["agent_model"])  # claude-opus-4-6
    print(result["key_origin"])   # "server_generated" or "client_provided"

Authentication Flows

Server-Generated Keys (zero setup)

The server generates an Ed25519 keypair and returns the private key once. Store it securely — the server never retains it.

from auth_agents import AuthAgents

client = AuthAgents()

# 1. Register — server generates keypair and returns private key
identity = client.register(
    agent_name="MyAgent",
    agent_model="claude-opus-4-6",
    agent_provider="Anthropic",
    agent_purpose="Automated data processing",
)

did             = identity["did"]
credential      = identity["credential"]
private_key_jwk = identity["private_key_jwk"]   # save this securely
# identity["key_origin"] == "server_generated"

# 2. Request a challenge nonce
challenge_resp = client.challenge(did)
challenge_id   = challenge_resp["challenge_id"]
nonce          = challenge_resp["nonce"]

# 3. Sign the nonce with the stored private key
signature = AuthAgents.sign_challenge(private_key_jwk, nonce)

# 4. Authenticate
auth_result = client.authenticate(
    challenge_id=challenge_id,
    did=did,
    signature=signature,
)

if auth_result["valid"]:
    print("Authenticated!", auth_result["session_token"])

Headless / Bring-Your-Own-Key (BYOK)

Generate your own keypair locally, register with your public key, and sign challenges with your private key. The server never sees your private key.

from auth_agents import AuthAgents

client = AuthAgents()

# 1. Generate a local Ed25519 keypair
key_pair        = AuthAgents.generate_key_pair()
public_key_jwk  = key_pair["public_key_jwk"]
private_key_jwk = key_pair["private_key_jwk"]   # keep secret

# 2. Register with your own public key
identity = client.register(
    agent_name="MyAgent",
    agent_model="claude-opus-4-6",
    agent_provider="Anthropic",
    agent_purpose="Automated data processing",
    public_key_jwk=public_key_jwk,
)

did        = identity["did"]
credential = identity["credential"]
# identity["key_origin"] == "client_provided"

# 3. Request a challenge nonce
challenge_resp = client.challenge(did)
challenge_id   = challenge_resp["challenge_id"]
nonce          = challenge_resp["nonce"]

# 4. Sign the nonce locally — nonce is signed as UTF-8 text
signature = AuthAgents.sign_challenge(private_key_jwk, nonce)

# 5. Authenticate
auth_result = client.authenticate(
    challenge_id=challenge_id,
    did=did,
    signature=signature,
)

if auth_result["valid"]:
    print("Authenticated!", auth_result["session_token"])

API Reference

AuthAgents(base_url=...)

Client class. Defaults to https://auth.usevigil.dev. The SDK enforces HTTPS for all API communication. HTTP is only allowed for localhost during development.

AuthAgents.generate_key_pair() — static

Generate a fresh Ed25519 keypair. Returns:

{
    "public_key_jwk":  {"kty": "OKP", "crv": "Ed25519", "x": "<base64url>"},
    "private_key_jwk": {"kty": "OKP", "crv": "Ed25519", "x": "<base64url>", "d": "<base64url>"},
}

AuthAgents.sign_challenge(private_key_jwk, nonce) — static

Sign a challenge nonce with an Ed25519 private key JWK. Returns a base64url-encoded signature string (no padding).

client.register(...)

Register a new agent identity. Pass public_key_jwk for BYOK; omit it for server-generated keys. Optional inputs:

  • metadata — dict of string key/value pairs

Returns a dict including:

Field Description
did Agent DID (did:key:z6Mk...)
credential VC-JWT string
key_fingerprint Short fingerprint of the public key
key_origin "server_generated" or "client_provided"
private_key_jwk Private key JWK (server-generated flow only)

Registration always returns a credential with the server default lifetime (24 hours). To customize the credential lifetime, use credential_expires_in on client.challenge(...).

client.challenge(did, site_id=None, credential_expires_in=None)

Request an authentication challenge nonce. Optional site_id scopes the challenge/session in site-provisioned deployments. Optional credential_expires_in sets the credential lifetime in seconds, controlled by the website developer (0 means non-expiring). Returns challenge_id, nonce, and expires_in.

client.authenticate(challenge_id, did, signature)

Submit a signed challenge. Returns valid, session_token, credential, agent object, and expires_in. The credential uses the lifetime chosen in the preceding client.challenge(...) call.

client.verify(credential)

Verify a VC-JWT credential.

  • Valid credential: returns {"valid": True, ...}
  • Invalid credential (HTTP 401): returns {"valid": False, "error": "...", "message": "..."} without raising

Returns a dict including:

Field Description
valid True if the credential is valid
did Agent DID
agent_name Agent display name
agent_model Model identifier (e.g. claude-opus-4-6)
agent_provider Provider name (e.g. Anthropic)
agent_purpose What the agent intends to do
key_fingerprint Short fingerprint of the public key
key_origin "server_generated" or "client_provided"
issued_at ISO 8601 issuance timestamp
expires_at ISO 8601 expiration timestamp (or None)

verify(credential) — module-level shorthand

Equivalent to AuthAgents().verify(credential).

Documentation

Full API reference at usevigil.dev/docs

Release files for auth-agents 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for auth-agents 0.4.3
File Size Uploaded
auth_agents-0.4.3.tar.gz 6.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for auth-agents 0.4.3
File Interpreter ABI Platform
auth_agents-0.4.3-py3-none-any.whl Python 3 none any Details

Total release size: 14.4 kB

Release files / auth_agents-0.4.3.tar.gz

Download URL auth_agents-0.4.3.tar.gz
Size 6.8 kB
Tags Source
SHA-256 checksum
How to use checksums
27547d88b71c2731d89be44129c069cca1e8b854574289b62d17daedf2051436
BLAKE2b-256 checksum
How to use checksums
3533289f57b2369f038da87286f75a2a1657fc8089222411e0aaebe0be6f0456
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / auth_agents-0.4.3-py3-none-any.whl

Download URL auth_agents-0.4.3-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ec1f9774e7480ceb30d814484746c764f5573a1091fd10d2bb5dc5fff5de2104
BLAKE2b-256 checksum
How to use checksums
fde1324424e19ed162613c9d8c1e95b43b3121bc10a59d4ac2a973c046ff0c36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

0.4.3 This release

2 release files

0.4.2

2 release files

0.4.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page