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!')
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).
| Field | Example value | Description |
|---|---|---|
| Agent name | My First Agent | Human-readable agent name (step 1) |
| Description | Testing AAuth protocol | Optional description (step 1) |
| Agent identifier | https://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 scopes | read and write, one per line | (Step 3) Scopes this agent gets without anyone being asked, in the Acting for people section |

On step 3, in Acting for people, switch on:
- ✅ User-in-the-loop authorization
- ✅ Delegation to sub-agents

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:
| Field | Example value |
|---|---|
| Resource name | Reporting API |
| Resource identifier | https://api.example.com (any unique https:// URL) |
| JWKS URI | https://api.example.com/.well-known/jwks.json |
| Scopes | One row per scope: the name agents ask for and a description shown on the consent screen, for example read and write |
| Default auth level | Authorized |
Click Register resource. Registered resources are listed on the AAuth resources tab of the Agents page.

Step 4: Make your first request
Choose a language or framework for a complete, copy-paste example:
| Framework / Language | Guide |
|---|---|
| Python (LumoAuth SDK) | View example → |
| JavaScript / Node.js | View example → |
| LangChain / LangGraph | View example → |
| CrewAI | View example → |
| OpenAI Agents SDK | View example → |
Next steps
- AAuth Protocol spec — full protocol details
- Agent Registry — manage agent registrations, budgets, and capabilities
- JIT Permissions — add per-operation permission escalation
Standards used on this page
| Plain name | Standard |
|---|---|
| Signed HTTP requests (HTTP message signatures) | RFC 9421 |
See the standards reference for what each one covers and how LumoAuth uses it.