Skip to main content

AAuth Quickstart — OpenAI Agents SDK

Connect AAuth to an OpenAI Agents SDK agent so that every tool call carries a signed identity. AAuth is the identity protocol for agents: an agent proves who it is by signing each request with its own private key instead of sending a shared secret. The agent's identity is an Ed25519 key pair registered with LumoAuth. The access token is obtained once from the AAuth token endpoint. Every request is a signed HTTP request (a per-request, replay-proof proof that the agent holds its key).

Prerequisites
  • A LumoAuth organization (agent identity is available on every plan, nothing to switch on)
  • Python 3.9+

Complete Steps 1–3 first (generate a key pair, register the agent and the resource). Ideally, verify with the Python SDK quickstart before connecting the Agents SDK.

Install​

pip install 'lumoauth[aauth]' openai-agents

Example​

import asyncio
from agents import Agent, Runner, function_tool
from lumoauth import AAuthClient

# 1. Initialize the AAuth client
private_pem, jwks = AAuthClient.generate_keypair()
aauth = AAuthClient(
agent_identifier="https://my-agent.example.com",
private_key_pem=private_pem,
org_id="acme-corp",
)

# 2. Obtain tokens upfront (see the AAuth Quickstart).
# agent_token is mandatory: the /agent/token endpoint authenticates the
# agent via the Agent-Auth header, so request_authorization requires it.
agent_token = "..." # your `agent+jwt`, bound to this key pair via cnf.jwk
resource_token = "..." # from your resource server
tokens = aauth.request_authorization(
resource_token=resource_token,
scope="read write",
agent_token=agent_token,
)
if tokens.get("authorization_required"):
raise RuntimeError("User consent required - implement OAuth redirect flow first")

# On success the token endpoint returns the agent access token under the
# key "auth_token" (not "access_token").
ACCESS_TOKEN = tokens["auth_token"]

# 3. Define tools that make AAuth-signed API calls
@function_tool
def fetch_document(document_id: str) -> str:
"""Fetch a document from the protected API."""
resp = aauth.signed_request(
"GET",
f"https://api.example.com/v1/documents/{document_id}",
auth_token=ACCESS_TOKEN,
)
if resp.status_code == 200:
return resp.text
return f"Error: HTTP {resp.status_code}"

@function_tool
def create_summary(document_id: str, summary: str) -> str:
"""Create a summary for a document in the protected API."""
resp = aauth.signed_request(
"POST",
f"https://api.example.com/v1/documents/{document_id}/summaries",
auth_token=ACCESS_TOKEN,
data={"text": summary},
)
if resp.status_code in (200, 201):
return "Summary created successfully."
return f"Error: HTTP {resp.status_code}"

# 4. Create the OpenAI Agent
research_agent = Agent(
name="Research Assistant",
instructions=(
"You are a helpful assistant with access to a protected document API. "
"Retrieve documents and create summaries as requested."
),
tools=[fetch_document, create_summary],
)

# 5. Run the agent
async def main():
result = await Runner.run(
research_agent,
"Fetch document doc-42 and create a two-sentence summary.",
)
print(result.final_output)

if __name__ == "__main__":
asyncio.run(main())

How it works​

ComponentRole
AAuthClientManages key material and handles AAuth token exchange
aauth.signed_request(...)Adds the Signature/Signature-Input request-signature headers and the Authorization header
@function_toolDecorates Python functions as OpenAI SDK tools
ACCESS_TOKENShort-lived token issued after agent + resource validation

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.