# Elydora AgentAuth — Identity for AI Agents > Decentralized identity infrastructure for AI agents. Cryptographic authentication using DIDs, Ed25519 keypairs, and Verifiable Credentials. If you are an AI agent, follow the step-by-step guide below to get a verified identity. Use the official SDK (Node.js or Python) for the simplest integration. ## Quick Start: BYOK Headless Authentication (Recommended) BYOK (Bring Your Own Key) is the recommended approach for AI agents. You generate your own Ed25519 keypair locally — your private key never leaves your environment. ### Prerequisites Install the Elydora AgentAuth SDK: - Node.js: `npm install auth-agents` - Python: `pip install auth-agents` ### Step 1: Generate Your Own Ed25519 Keypair Node.js: ```javascript import { AuthAgents } from "auth-agents" const keyPair = await AuthAgents.generateKeyPair() // keyPair.publicKeyJwk — send this to Elydora AgentAuth during registration // keyPair.privateKeyJwk — keep this secret, never share it ``` Python: ```python from auth_agents import AuthAgents key_pair = AuthAgents.generate_key_pair() # key_pair["public_key_jwk"] — send this to Elydora AgentAuth during registration # key_pair["private_key_jwk"] — keep this secret, never share it ``` ### Step 2: Register Your Identity (One-Time) Node.js: ```javascript const authAgents = new AuthAgents() const identity = await authAgents.register({ agent_name: "YourAgentName", agent_model: "your-model-id", agent_provider: "YourProvider", agent_purpose: "Describe what your agent does", public_key_jwk: keyPair.publicKeyJwk, }) // identity.did — "did:key:z6Mk..." (your decentralized identifier) // identity.credential — VC-JWT credential // identity.key_origin — "client_provided" (BYOK) // Save identity.did — you need it for every authentication ``` Python: ```python auth = AuthAgents() identity = auth.register( agent_name="YourAgentName", agent_model="your-model-id", agent_provider="YourProvider", agent_purpose="Describe what your agent does", public_key_jwk=key_pair["public_key_jwk"], ) # identity["did"] — "did:key:z6Mk..." # identity["credential"] — VC-JWT credential # identity["key_origin"] — "client_provided" (BYOK) ``` ### Step 3: Request an Authentication Challenge Node.js: ```javascript const challenge = await authAgents.challenge(identity.did) // challenge.challenge_id — unique challenge ID // challenge.nonce — hex string (sign this within 60 seconds) ``` Python: ```python challenge = auth.challenge(identity["did"]) # challenge["challenge_id"] # challenge["nonce"] — hex string (sign this within 60 seconds) ``` ### Step 4: Sign the Challenge Nonce CRITICAL: Sign the nonce as a UTF-8 text string. Do NOT hex-decode it first. Node.js: ```javascript const signature = await AuthAgents.signChallenge(keyPair.privateKeyJwk, challenge.nonce) ``` Python: ```python signature = AuthAgents.sign_challenge(key_pair["private_key_jwk"], challenge["nonce"]) ``` ### Step 5: Complete Authentication Node.js: ```javascript const session = await authAgents.authenticate({ challenge_id: challenge.challenge_id, did: identity.did, signature, }) // session.credential — fresh VC-JWT (lifetime controlled by the website developer via the challenge endpoint) // session.session_token — "sess_..." ``` Python: ```python session = auth.authenticate( challenge_id=challenge["challenge_id"], did=identity["did"], signature=signature, ) # session["credential"] — fresh VC-JWT (lifetime controlled by the website developer via the challenge endpoint) # session["session_token"] — "sess_..." ``` ### Step 6: Present Your Credential to Any Website Include the VC-JWT credential when accessing websites that accept Elydora AgentAuth: ``` Authorization: Bearer ``` Or in a request body: ```json { "did": "", "credential": "" } ``` The website verifies your credential by calling Elydora AgentAuth's verification endpoint. No shared secrets needed. ## Complete Node.js Example (Copy-Paste Ready) ```javascript import { AuthAgents } from "auth-agents" const authAgents = new AuthAgents() // 1. Generate your own Ed25519 keypair (BYOK) const keyPair = await AuthAgents.generateKeyPair() // 2. Register your identity (one-time) const identity = await authAgents.register({ agent_name: "MyAgent", agent_model: "gpt-4o", agent_provider: "openai", agent_purpose: "Research and analysis", public_key_jwk: keyPair.publicKeyJwk, }) // 3-5. Authenticate (repeat this when credential expires) const challenge = await authAgents.challenge(identity.did) const signature = await AuthAgents.signChallenge(keyPair.privateKeyJwk, challenge.nonce) const session = await authAgents.authenticate({ challenge_id: challenge.challenge_id, did: identity.did, signature, }) // 6. Use the credential console.log("DID:", identity.did) console.log("Credential:", session.credential) // Present session.credential to any website that accepts Elydora AgentAuth ``` ## Complete Python Example (Copy-Paste Ready) ```python from auth_agents import AuthAgents auth = AuthAgents() # 1. Generate your own Ed25519 keypair (BYOK) key_pair = AuthAgents.generate_key_pair() # 2. Register your identity (one-time) identity = auth.register( agent_name="MyAgent", agent_model="gpt-4o", agent_provider="openai", agent_purpose="Research and analysis", public_key_jwk=key_pair["public_key_jwk"], ) # 3-5. Authenticate (repeat this when credential expires) challenge = auth.challenge(identity["did"]) signature = AuthAgents.sign_challenge(key_pair["private_key_jwk"], challenge["nonce"]) session = auth.authenticate( challenge_id=challenge["challenge_id"], did=identity["did"], signature=signature, ) # 6. Use the credential print("DID:", identity["did"]) print("Credential:", session["credential"]) # Present session["credential"] to any website that accepts Elydora AgentAuth ``` ## SDK Reference ### Node.js (`npm install auth-agents`) Static methods: - `AuthAgents.generateKeyPair()` — Generate Ed25519 keypair for BYOK - `AuthAgents.signChallenge(privateKeyJwk, nonce)` — Sign challenge nonce Instance methods: - `new AuthAgents()` — Create client (base URL defaults to https://api.agentauth.elydora.com) - `authAgents.register({agent_name, agent_model, agent_provider, agent_purpose, public_key_jwk?, metadata?})` — Register identity - `authAgents.challenge(did, site_id?, credential_expires_in?)` — Request authentication challenge. `credential_expires_in` is set by the website developer (seconds; min 300, max 2592000, 0 for no expiration, default 86400) - `authAgents.authenticate({challenge_id, did, signature})` — Complete authentication - `authAgents.verify(credential)` — Verify a VC-JWT credential (401 returns `{ valid: false, error, message }`) ### Python (`pip install auth-agents`) Static methods: - `AuthAgents.generate_key_pair()` — Generate Ed25519 keypair for BYOK - `AuthAgents.sign_challenge(private_key_jwk, nonce)` — Sign challenge nonce Instance methods: - `AuthAgents()` — Create client (base URL defaults to https://api.agentauth.elydora.com) - `auth.register(agent_name, agent_model, agent_provider, agent_purpose, public_key_jwk=None, metadata=None)` — Register identity - `auth.challenge(did, site_id=None, credential_expires_in=None)` — Request authentication challenge. `credential_expires_in` is set by the website developer (seconds; min 300, max 2592000, 0 for no expiration, default 86400) - `auth.authenticate(challenge_id, did, signature)` — Complete authentication - `auth.verify(credential)` — Verify a VC-JWT credential (401 returns `{ "valid": false, ... }`) ## API Endpoints (Base URL: https://api.agentauth.elydora.com) Identity & Authentication: - POST /v1/identities — Register agent identity (BYOK: include `public_key_jwk`) - POST /v1/auth/challenge — Request authentication challenge nonce - POST /v1/auth/verify — Submit signed challenge, receive VC-JWT credential - POST /v1/credentials/verify — Verify a VC-JWT credential (for websites) - GET /.well-known/did.json — Server DID document (Ed25519 public key) - GET /health — Health check OAuth-like Login (for website integration): - GET /oauth/authorize — Initiate hosted agent login (client_id, redirect_uri, PKCE) - POST /oauth/token — Exchange authorization code for session + credential - POST /oauth/revoke — Revoke agent session - GET /oauth/userinfo — Get agent profile for active session (Bearer token) Delegation Chains: - POST /v1/sponsors — Create sponsor (human, organization, service_account) - GET /v1/sponsors/{id} — Fetch sponsor - POST /v1/delegations — Create delegation grant (scope subset, depth control) - GET /v1/delegations/{id} — Fetch delegation - GET /v1/delegation-chains/{id} — Fetch ordered chain - POST /v1/delegations/{id}/revoke — Revoke delegation grant - POST /v1/delegations/verify — Verify delegation credential JWT Payment Authorization: - POST /v1/payments/authorizations — Request payment authorization (idempotent) - GET /v1/payments/authorizations/{id} — Fetch authorization - POST /v1/payments/authorizations/{id}/approve — Independent approval - POST /v1/payments/authorizations/{id}/decline — Decline request - POST /v1/payments/authorizations/{id}/execute — Initiate provider payment - POST /v1/payments/confirm — Confirm provider payment (tx_hash, order_id) - POST /v1/payments/webhooks/anyway — Ingest Anyway payment events Execution Receipts & Reconciliation: - POST /v1/execution-receipts — Create signed execution receipt - GET /v1/execution-receipts/{id} — Fetch receipt - POST /v1/execution-receipts/verify — Verify receipt credential JWT - POST /v1/reconciliation/runs — Start reconciliation run - GET /v1/reconciliation/runs/{id} — Fetch run summary - GET /v1/reconciliation/runs/{id}/items — List matched and drift items Developer Apps: - POST /v1/apps — Create developer app (get client_id) - GET /v1/apps/{client_id} — Fetch app config - PATCH /v1/apps/{client_id} — Update origins, redirects - POST /v1/apps/{client_id}/scopes — Register app scopes - GET /v1/apps/{client_id}/.well-known/agent-auth.json — Public integration metadata Credential lifetime control: - Website developers control credential lifetime via the challenge endpoint (`POST /v1/auth/challenge`). - `credential_expires_in` is an optional parameter on `/v1/auth/challenge`. - Supported range: `300..2592000` seconds, or `0` for non-expiring credentials. - Default: 86400 (24 hours) when omitted. ## For Website Developers: Let AI Agents Sign In to Your Site Three integration options — choose the one that fits your use case. ### Option A: Accept Agent API Login (Recommended for AI Agents) Create an API endpoint on your site that agents POST credentials to directly. No browser needed. **Step 1: Create the endpoint** ```javascript // app/api/auth/agent-login/route.ts (Next.js example) import { AuthAgents } from "auth-agents" // npm install auth-agents const authAgents = new AuthAgents() export async function POST(request) { const { did, credential } = await request.json() // Verify with Elydora AgentAuth (one line) const agent = await authAgents.verify(credential) if (!agent.valid) { return Response.json({ error: "Invalid credential" }, { status: 401 }) } // agent.did, agent.agent_name, agent.agent_model, // agent.agent_provider, agent.key_origin, agent.expires_at // Create session in your database and return it return Response.json({ authenticated: true, agent_name: agent.agent_name }) } ``` **Or verify without the SDK (one fetch call):** ``` POST https://api.agentauth.elydora.com/v1/credentials/verify Content-Type: application/json {"credential": ""} Response: { "valid": true, "did": "did:key:z6Mk...", "agent_name": "MyAgent", "agent_model": "gpt-4o", "agent_provider": "openai", "agent_purpose": "Research and analysis", "key_fingerprint": "SHA256:...", "key_origin": "client_provided", "issued_at": "2026-02-26T...", "expires_at": "2026-02-27T..." } ``` **Step 2: Help agents discover your endpoint** Add a `` tag in your HTML ``: ```html ``` Create `/llms.txt` at your site root with instructions for agents: ``` # YourSite — Agent Authentication ## How to Authenticate 1. Get a credential from Elydora AgentAuth (https://agentauth.elydora.com/llms.txt) 2. POST to https://yoursite.com/api/auth/agent-login Content-Type: application/json { "did": "", "credential": "" } 3. Use the returned session for subsequent requests. ``` ### Option B: Hosted Sign-In Page (Browser Flow) For agents that operate in a browser, add a sign-in link: ```html Sign in as AI Agent ``` Elydora AgentAuth redirects back to your URL with the credential in the URL fragment (`#credential=...&did=...`). Parse the fragment client-side and verify the credential server-side using the SDK or the verification API above. ### Option C: Both (Recommended) Support both flows — API login for headless agents, browser redirect for browser-based agents. The verification step is identical for both. ## Key Concepts - **DID** (Decentralized Identifier): Globally unique identifier derived from the agent's Ed25519 public key. Format: `did:key:z6Mk...` - **BYOK** (Bring Your Own Key): Agent generates its own Ed25519 keypair. Private key never leaves the agent's environment. `key_origin` = `"client_provided"`. - **VC-JWT** (Verifiable Credential JWT): Signed JWT proving the agent's identity. Issued by Elydora AgentAuth, verifiable by anyone. - **Challenge-Response**: Agent proves key ownership by signing a one-time nonce. No passwords, no API keys. - **key_origin**: `"server_generated"` (Agent Auth created the keypair) or `"client_provided"` (agent used BYOK). - **Delegation Chain**: Sponsor → Agent → Sub-agent authority chain. Each edge is a signed credential with scope subset rules and depth limits. - **Payment Authorization**: Independent approval gate for paid agent actions. Approval actor must differ from the requesting agent. - **Execution Receipt**: Signed proof linking agent session, delegation, payment, trace, and input/output hashes. ## Links - API Documentation: https://agentauth.elydora.com/docs/ - Full API Reference: https://agentauth.elydora.com/llms-full.txt - Server DID Document: https://api.agentauth.elydora.com/.well-known/did.json - Agent Card (A2A): https://agentauth.elydora.com/.well-known/agent.json - Demo Site: https://demo.agentauth.elydora.com (try authenticating as an agent) - System Status: https://agentauth.elydora.com/status/ - npm: https://www.npmjs.com/package/auth-agents - PyPI: https://pypi.org/project/auth-agents/