Authorisation¶
CEM-013-000
🤖 OIDC Provider¶
CEM-013-000
Specification¶
for a small number of users use Auth0
for a larger number of users use Okta
Motivation¶
Feature |
Clerk |
Auth0 (Okta) |
Logto |
WorkOS |
Zitadel |
|---|---|---|---|---|---|
AI Focus |
Frontend AI DX |
Agentic Auth & FGA |
Modern SaaS & AI |
Enterprise Agents |
Multi-tenancy |
Setup Speed |
Instant (React/Next) |
Medium (Enterprise) |
Fast (OSS/Cloud) |
Fast (API-first) |
Medium |
Key AI Feature |
Shared User Pools |
Token Vault for RAG |
M2M & API Keys |
Enterprise SSO |
Fine-grained RBAC |
Best For |
Fast-moving startups |
Regulated Enterprise |
Open-source lovers |
B2B SaaS Growth |
Complex Permissioning |
Complexity |
Very Low |
High |
Low to Medium |
Low |
Medium |
Auth0 Setup (MCP + Codex CLI)¶
Use this when connecting Codex CLI to the MCP server with Auth0. Codex CLI performs OAuth via Dynamic Client Registration (DCR), so the MCP server must explicitly support OAuth and expose the protected resource metadata endpoint. The flow used is Authorization Code + PKCE.
Auth0 Dashboard: create an API and set its Identifier to your audience (e.g.
https://penroselamarck/). - Auth0 Dashboard: set Default Audience under **Tenant Settings → API AuthorizationSettings** to exactly
https://penroselamarck/to ensure DCR clients receive JWT access tokens for this API.Auth0 Dashboard: enable Dynamic Client Registration (DCR) and Enable Application Connections. - Navigation:
Settings → Advanced.Auth0 Dashboard: for the API Application Access Policy, set User Access to Allow and Client Access to Deny.
Ensure at least one connection exists (Database or Social).
Promote that connection to domain level. DCR creates third‑party clients that cannot be enabled per‑app, so domain‑level promotion is required for DCR logins to work. - You must obtain a Management API token using
Applications → APIs → Auth0 Management API → API Explorer. Without this token, the commands below will fail.
export AUTH0_DOMAIN="YOUR_TENANT.us.auth0.com"
export MGMT_TOKEN="YOUR_MGMT_API_TOKEN"
export CONNECTION_NAME="google-oauth2" # or Username-Password-Authentication
# Fetch the connection id
CONNECTION_ID=$(curl -s "https://${AUTH0_DOMAIN}/api/v2/connections?name=${CONNECTION_NAME}" \
-H "Authorization: Bearer ${MGMT_TOKEN}" | jq -r '.[0].id')
# Promote to domain-level so third-party apps can use it
curl -s -X PATCH "https://${AUTH0_DOMAIN}/api/v2/connections/${CONNECTION_ID}" \
-H "Authorization: Bearer ${MGMT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"is_domain_connection": true}'
Configure MCP (
.env) and restart the container:
AUTH0_DOMAIN=YOUR_TENANT.us.auth0.com
AUTH0_AUDIENCE=https://penroselamarck/
Configure Codex CLI and login: - Set
mcp_oauth_callback_port = 1455in~/.codex/config.toml. - Setmcp_oauth_credentials_store = "file"if you want MCP OAuth tokens stored in afile instead of the OS keyring.
The callback URL is not the MCP server. It is the local loopback URL Codex listens on. Ensure the Auth0 application callback URL includes
http://localhost:1455/auth/callback.Run:
codex mcp login penroselamarck
Validate OAuth metadata (optional):
curl -s http://penroselamarck-api:8080/.well-known/oauth-protected-resource | jq