Add authentication to your Python app
This guide walks you through authenticating a Python backend service or AI agent with LumoAuth using the lumoauth Python SDK. You'll set up client credentials authentication, use the Ask API for authorization, and optionally set up delegation chains.
Before you start
You need:
- A LumoAuth account with a configured tenant (sign up)
- An Agent or OAuth application registered in your tenant with Client ID and Client Secret
- Python 3.9+
From your tenant portal, note your Tenant Slug, Client ID, and Client Secret.
Install the SDK
pip install lumoauth
For cryptographic agent identity (AAuth), install with the extra:
pip install lumoauth[aauth]
Authenticate your agent
The SDK uses the OAuth 2.0 client credentials flow for server-to-server authentication.
from lumoauth import LumoAuthAgent
agent = LumoAuthAgent(
base_url="https://app.lumoauth.dev",
tenant="acme-corp",
client_id="your-client-id",
client_secret="your-client-secret",
)
# Authenticate and get an access token
agent.authenticate(scopes=["read:users", "write:documents"])
print(f"Authenticated. Scopes: {agent.token_scopes}")
You can also use environment variables instead of passing credentials directly:
LUMOAUTH_URL=https://app.lumoauth.dev
LUMOAUTH_TENANT=acme-corp
AGENT_CLIENT_ID=your-client-id
AGENT_CLIENT_SECRET=your-client-secret
agent = LumoAuthAgent() # reads from environment
agent.authenticate()
Use the Ask API
The Ask API provides lightweight preflight authorization checks, designed for LLM tool-calling workflows where you need a quick allow/deny decision before executing an action.
from lumoauth import LumoAuthAgent
agent = LumoAuthAgent()
agent.authenticate()
# Simple boolean check
if agent.is_allowed("read_document", context={"document_id": "doc-123"}):
print("Access granted - reading document")
else:
print("Access denied")
# Detailed response with audit trail
result = agent.ask("delete_user", context={"user_id": "u-456"})
print(result)
# {
# 'allowed': False,
# 'action': 'delete_user',
# 'reason': 'insufficient_permissions',
# 'audit_id': 'aud_abc123',
# 'context': {'user_id': 'u-456'}
# }
Check agent identity and capabilities
from lumoauth import LumoAuthAgent
agent = LumoAuthAgent()
agent.authenticate()
# Get full agent identity
info = agent.get_agent_info()
print(f"Agent: {info['id']}")
print(f"Capabilities: {info['capabilities']}")
# Check for specific capability
if agent.has_capability("web_search"):
print("Agent can perform web searches")
# Monitor budget
budget = agent.get_budget_status()
print(f"Budget policy: {budget}")
if agent.is_budget_exhausted():
print("Daily token budget reached - pausing operations")
Act on behalf of users with delegation chains
Use RFC 8693 token exchange to perform actions on behalf of a user. This is useful for AI agents that need user-scoped permissions.
from lumoauth import LumoAuthAgent, DelegationChain
agent = LumoAuthAgent()
agent.authenticate()
chain = DelegationChain(agent, redirect_uri="https://myapp.com/consent")
# Step 1: Generate a consent URL for the user
consent_url = chain.get_consent_url(
"session-1",
scopes=["profile", "documents"],
)
print(f"Redirect user to: {consent_url}")
# Step 2: After user grants consent, handle the callback
chain.handle_consent_callback("session-1", authorization_code="CODE_FROM_CALLBACK")
# Step 3: Exchange for a delegated token
delegated_token = chain.exchange("session-1", scopes=["read:documents"])
# Step 4: Make API calls on behalf of the user
response = chain.request("session-1", "GET", "/api/v1/documents")
print(response.json())
# Clean up when done
chain.revoke("session-1")
Integrate with MCP servers
Exchange your agent token for an MCP server-scoped token:
from lumoauth import LumoAuthAgent
agent = LumoAuthAgent()
agent.authenticate()
mcp_token = agent.get_mcp_token("my-mcp-server")
# Use mcp_token to authenticate with the MCP server
Use in a FastAPI app
from fastapi import FastAPI, Depends, HTTPException
from lumoauth import LumoAuthAgent
app = FastAPI()
agent = LumoAuthAgent()
agent.authenticate()
def check_permission(action: str):
def dependency():
agent.ensure_authenticated()
if not agent.is_allowed(action):
raise HTTPException(status_code=403, detail="Forbidden")
return Depends(dependency)
@app.get("/api/documents", dependencies=[check_permission("read_documents")])
async def list_documents():
return {"documents": []}
@app.delete("/api/documents/{doc_id}", dependencies=[check_permission("delete_documents")])
async def delete_document(doc_id: str):
return {"deleted": doc_id}
What's next?
- Configure agent identity in the LumoAuth tenant portal
- Set up ABAC policies for attribute-based authorization
- Enable audit logs to track agent actions
- SDKs & Libraries - Full SDK API reference