Skip to main content

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

Project description

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

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

auth_agents-0.4.3.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

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

auth_agents-0.4.3-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file auth_agents-0.4.3.tar.gz.

File metadata

  • Download URL: auth_agents-0.4.3.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for auth_agents-0.4.3.tar.gz
Algorithm Hash digest
SHA256 27547d88b71c2731d89be44129c069cca1e8b854574289b62d17daedf2051436
MD5 ef3bf2872b452029a53cb018253ee46b
BLAKE2b-256 3533289f57b2369f038da87286f75a2a1657fc8089222411e0aaebe0be6f0456

See more details on using hashes here.

File details

Details for the file auth_agents-0.4.3-py3-none-any.whl.

File metadata

  • Download URL: auth_agents-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for auth_agents-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ec1f9774e7480ceb30d814484746c764f5573a1091fd10d2bb5dc5fff5de2104
MD5 c6e523fd701862287f64aa814093f712
BLAKE2b-256 fde1324424e19ed162613c9d8c1e95b43b3121bc10a59d4ac2a973c046ff0c36

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