Feature request: Support Microsoft Entra ID (Azure AD) OAuth2 Client Credentials for model providers (tenant_id/client_id/client_secret)

Resolved 💬 5 comments Opened Jan 12, 2026 by c0okB Closed Mar 20, 2026

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_

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗