Skip to main content

Agent Auth (AAuth) — Quickstart

This quickstart walks through the essential steps to set up AAuth (the agent identity protocol: an agent proves who it is by signing each request with its own private key instead of sending a shared secret): generate a key pair, register an agent and a resource, then make your first authenticated call. AAuth uses Ed25519 keys (a modern elliptic-curve signature scheme — short keys, fast, widely supported) and sends every call as a signed HTTP request (a cryptographic signature over specific parts of the request — method, path, selected headers, body digest — giving a replay-proof, per-request proof that the agent holds its key).

Prerequisites​

  • Access to a LumoAuth organization (e.g., acme-corp); agent identity (AAuth) is available on every plan, nothing to switch on
  • Node.js 18+ or Python 3.9+
  • Basic familiarity with OAuth 2.0 concepts
  • A server environment that can generate Ed25519 or RSA key pairs

Step 1: Generate a key pair​

AAuth requires cryptographic keys. Generate an Ed25519 key pair:

// Node.js
const crypto = require('crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519', {
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});

// Convert public key to raw bytes for JWK
const publicKeyBytes = Buffer.from(
publicKey.replace(/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\n/g, ''),
'base64'
).slice(-32);

const jwks = {
keys: [{
kty: 'OKP',
crv: 'Ed25519',
x: publicKeyBytes.toString('base64url'),
use: 'sig',
kid: 'key-1'
}]
};

console.log('JWKS:', JSON.stringify(jwks, null, 2));
console.log('\nPrivate Key (save securely):');
console.log(privateKey);
# Python
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
import base64
import json

# Generate key pair
private_key = ed25519.Ed25519PrivateKey.generate()
public_key = private_key.public_key()

# Export public key
public_bytes = public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw
)

jwks = {
"keys": [{
"kty": "OKP",
"crv": "Ed25519",
"x": base64.urlsafe_b64encode(public_bytes).decode().rstrip('='),
"use": "sig",
"kid": "key-1"
}]
}

print('JWKS:', json.dumps(jwks, indent=2))
print('\nSave your private key securely!')
Key storage

Keep private keys on the server, never in source control or client-side code. Prefer an HSM or secret manager in production.

Step 2: Register your agent​

Register your agent in the Organization Portal, or use the Admin API for programmatic registration. In the portal, go to AI Agents → Agents and click Register agent. The form is a three-step wizard: Who is this agent (name and description), How it proves its identity (choose AAuth and give the identifier and keys) and What it may do (capabilities, acting for people, budget).

FieldExample valueDescription
Agent nameMy First AgentHuman-readable agent name (step 1)
DescriptionTesting AAuth protocolOptional description (step 1)
Agent identifierhttps://my-agent.example.com(Step 2) Identifier that uniquely names your agent. The form describes it as local@domain form (like an email address) and does not enforce a format; whatever you enter must match the agent_identifier your code uses exactly
JWKS (inline)Paste your JWKS from Step 1(Step 2) Your agent's public keys (or give a JWKS URL where the agent publishes them)
Pre-authorized scopesread and write, one per line(Step 3) Scopes this agent gets without anyone being asked, in the Acting for people section

Step 2 of the Register agent wizard with AAuth selected and the agent identifier and inline JWKS filled in

On step 3, in Acting for people, switch on:

  • ✅ User-in-the-loop authorization
  • ✅ Delegation to sub-agents

The Acting for people section of step 3 with User-in-the-loop authorization and Delegation to sub-agents switched on

Click Next to reach the review, then Register agent.

Redirect URIs (for example https://my-agent.example.com/oauth/callback, where authorization codes are sent) are not part of the registration form. Add them afterwards by editing the AAuth registration (Redirect URIs field).

Step 3: Register a resource​

Register the protected API your agent will call. Go to AI Agents → Agents, open the AAuth resources tab and click Register resource:

FieldExample value
Resource nameReporting API
Resource identifierhttps://api.example.com (any unique https:// URL)
JWKS URIhttps://api.example.com/.well-known/jwks.json
ScopesOne row per scope: the name agents ask for and a description shown on the consent screen, for example read and write
Default auth levelAuthorized

Click Register resource. Registered resources are listed on the AAuth resources tab of the Agents page.

The Register AAuth resource form with the resource name, identifier, JWKS URI and scopes filled in

Step 4: Make your first request​

Choose a language or framework for a complete, copy-paste example:

Framework / LanguageGuide
Python (LumoAuth SDK)View example →
JavaScript / Node.jsView example →
LangChain / LangGraphView example →
CrewAIView example →
OpenAI Agents SDKView example →

Next steps​

Standards used on this page​

Plain nameStandard
Signed HTTP requests (HTTP message signatures)RFC 9421

See the standards reference for what each one covers and how LumoAuth uses it.