Feature request: Support Microsoft Entra ID (Azure AD) OAuth2 Client Credentials for model providers (tenant_id/client_id/client_secret)
What feature would you like to see?
Summary
Please add first-class support in Codex CLI for authenticating to LLM endpoints using Microsoft Entra ID (Azure AD) OAuth 2.0 client credentials (tenant_id + client_id + client_secret), and automatically attaching the resulting Bearer access token to requests.
This is needed for enterprise environments where API keys are disallowed and access must be governed via Entra ID app registrations / service principals.
Background / Why
Codex currently supports:
- Sign in with ChatGPT (subscription)
- Sign in with API key
- For custom model providers: OpenAI auth (
requires_openai_auth = true) or provider-specific API key via env var (env_key), or no auth.
However, many enterprises expose OpenAI-compatible endpoints behind Azure API Management / gateways that require Entra ID Bearer tokens, not API keys. We need Codex to obtain and refresh those tokens automatically.
(See Microsoft identity platform: OAuth2 client credentials grant flow.)
Current behavior
There is no built-in way for a custom provider to:
1) Fetch an Entra ID access token from https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
2) Cache/refresh it
3) Attach Authorization: Bearer <token> to provider requests
Desired behavior
Add a new provider auth mode, e.g. auth.type = "entra_client_credentials" that:
- Exchanges (tenant_id, client_id, client_secret) for an access token
- Supports
scope = "<resource>/.default"(v2 token endpoint) as the common enterprise pattern - Automatically refreshes token before expiry
- Stores secrets securely (prefer OS keyring; allow env var references)
- Sends requests with
Authorization: Bearer <access_token>
Proposed config (example)
# ~/.codex/config.toml
[[model_providers]]
name = "my-enterprise-gateway"
base_url = "https://my-gateway.example.com/openai"
# OpenAI-compatible routes, e.g. /v1/chat/completions
requires_openai_auth = false
[model_providers.auth]
type = "entra_client_credentials"
tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Prefer env var to avoid secrets in files
client_secret_env = "AZURE_CLIENT_SECRET"
# Token endpoint (optional; can be derived from tenant_id)
token_url = "https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/token"
# Typical v2 scope format for client credentials
scope = "https://cognitiveservices.azure.com/.default"
# Optional: audience/resource override if needed by gateway
# audience = "https://cognitiveservices.azure.com/"
### Additional information
_No response_This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗