Skip to content

Comments

🤖 feat: add Azure Entra ID keyless auth for OpenAI provider#2428

Open
ibetitsmike wants to merge 9 commits intomainfrom
mike/entra-auth
Open

🤖 feat: add Azure Entra ID keyless auth for OpenAI provider#2428
ibetitsmike wants to merge 9 commits intomainfrom
mike/entra-auth

Conversation

@ibetitsmike
Copy link
Contributor

@ibetitsmike ibetitsmike commented Feb 14, 2026

Summary

Adds Azure Entra ID (Microsoft identity) keyless authentication as a new auth path for the OpenAI provider. Enterprise Azure deployments can now use DefaultAzureCredential (via az login, managed identity, or workload identity) instead of distributing API keys.

Background

Enterprise customers deploying Azure OpenAI often rely on Azure Entra ID for authentication rather than API keys. This enables tighter security controls (no long-lived secrets), compliance with corporate identity policies, and seamless integration with Azure managed identity on cloud workloads.

The implementation reuses the existing openai provider namespace — no new provider or model migration needed. Auth priority is preserved: API key → Codex OAuth → Entra keyless → error.

Implementation

Core auth flow (providerModelFactory.ts):

  • Added lazy-loaded Entra token provider using @azure/identity (DefaultAzureCredential + getBearerTokenProvider)
  • Wraps fetch to inject Authorization: Bearer <token> and remove x-api-key header
  • Propagates request AbortSignal into token acquisition
  • Token caching/refresh handled by the Azure SDK internally
  • Inserted after Codex OAuth check in the auth decision chain

Credential resolver (providerRequirements.ts):

  • OpenAI marked as configured when authMode=entra + baseUrl present, no API key required
  • Supports both config (providers.jsonc) and env vars (OPENAI_AUTH_MODE=entra + OPENAI_BASE_URL)
  • API key always takes precedence when present
  • Codex-required models can still fall back to configured non-OAuth credentials (including Entra)

Schema + service (api.ts, providerService.ts):

  • Added openaiAuthMode: "apiKey" | "entra" field to ProviderConfigInfoSchema
  • Provider service surfaces auth mode to frontend

UI (ProvidersSection.tsx):

  • Auth mode selector in OpenAI provider settings (API Key / Azure Entra ID)
  • Uses existing updateOptimistically persistence pattern

Docs (providers.mdx, gen_docs.ts):

  • Setup guide for keyless mode with config and env examples
  • Doc generator updated to include OPENAI_AUTH_MODE in env var table

PR-linked CI follow-ups after rebase:

  • Updated flake.nix offline cache hash to match lockfile changes introduced by this PR
  • Fixed E2E selector ambiguity in tests/e2e/scenarios/settings.spec.ts by targeting the API key label (avoids matching the new auth-mode option text)
  • Updated PR CI workflow (.github/workflows/pr.yml) so Storybook tests install chromium-headless-shell alongside chromium (matches Playwright runtime expectation)

Validation

  • make static-check — passes locally
  • bun test src/node/utils/providerRequirements.test.ts src/node/services/providerService.test.ts src/node/services/providerModelFactory.test.ts
  • xvfb-run -a env MUX_E2E_LOAD_DIST=1 MUX_E2E_SKIP_BUILD=1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 bun x playwright test --project=electron tests/e2e/scenarios/settings.spec.ts -g "provider settings updates propagate without reload"
  • make storybook-build && make test-storybook (with local static server, matching CI flow)

Risks

  • Low severity: @azure/identity is lazily loaded only when authMode=entra — no impact on non-Azure users (no startup cost, no bundle bloat for users who don't use it)
  • Low severity: Entra token acquisition requires valid Azure credentials in the environment. Clear errors from DefaultAzureCredential surface when credentials are missing.
  • Low severity: Storybook CI now installs one additional Playwright browser artifact (chromium-headless-shell), increasing setup time slightly while improving determinism.

Generated with mux • Model: openai:gpt-5.3-codex • Thinking: xhigh • Cost: $4.76

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2e0c3b7e2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ibetitsmike
Copy link
Contributor Author

@codex review

Addressed the two open review threads with PR-linked fixes only:

  1. Restored Codex-required model fallback to non-OAuth configured creds (!creds.isConfigured), so Entra keyless configs are not blocked when OAuth isn't connected.
  2. Propagated request AbortSignal into Entra token acquisition (tokenProvider({ abortSignal })).

Also added targeted tests in providerModelFactory.test.ts for both behaviors.

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant