-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Describe the bug
Copilot CLI's Dynamic Client Registration (DCR) creates new OAuth clients on every session, triggering Entra ID "admin approval required" prompts in enterprise environments where the IDP broker federates to Azure AD/Entra ID.
This is related to but distinct from #1491 (redirect_uri mismatch). #1491 covers the port mismatch causing OAuth failures. This issue covers the consequence of DCR creating new clients constantly: enterprise IdPs that federate authentication to Entra ID require admin consent for each new dynamically registered client, blocking non-admin users entirely.
What happens
- Copilot CLI connects to a remote MCP server requiring OAuth
- CLI performs DCR with the authorization server (e.g., Keycloak)
- A new OAuth client is registered (new ephemeral port → new redirect_uri → new client)
- Keycloak federates the authorization to Entra ID (Azure AD)
- Entra ID sees an unrecognized OAuth client and shows "Approval required — This app requires your admin's approval"
- Non-admin users cannot proceed — they can only submit a justification and wait for admin approval
- CLI times out after 5 minutes:
MCPOAuthError: OAuth callback timeout
Why VS Code doesn't have this problem
VS Code's MCP OAuth implementation avoids this because (per #1491's analysis) it uses a preferred fixed port (33418) with ephemeral fallback. This means:
- DCR'd clients are reused across sessions (same port → same redirect_uri → same client)
- Entra ID admin consent is only needed once for the stable client
- After initial consent, sessions work without browser interaction
Copilot CLI uses port 0 (OS-assigned ephemeral) every time, creating a new client on every session, requiring fresh admin consent each time.
Impact
- Multiple users in our organization started hitting this simultaneously
- Users see "Approval required" for the Keycloak IDP broker app in Entra ID
- Non-admin users are completely blocked from using remote MCP servers
- Automated workflows that invoke
copilot --autopilotare also blocked since there's no human to interact with the consent page - Tokens expire every ~12 hours, so even if admin consent is granted for one client, the next session creates a new client requiring consent again
Affected version
GitHub Copilot CLI 1.0.6
Steps to reproduce the behavior
Prerequisites
- Enterprise environment with Entra ID (Azure AD) for identity
- Remote MCP server with OAuth, authorization server using Keycloak with IDP broker to Entra ID
- Entra ID tenant with admin consent policy requiring approval for unrecognized apps
Steps
- Configure
~/.copilot/mcp-config.json:
{
"mcpServers": {
"my-server": {
"url": "https://my-mcp-server.example.com",
"type": "http"
}
}
}- Clear any cached OAuth state:
rm -rf ~/.copilot/mcp-oauth-config/ - Run:
copilot - CLI opens browser for OAuth — browser shows Entra ID "Approval required" page
- Non-admin users cannot approve; CLI times out after 5 minutes
If admin consent IS granted:
6. Session works until tokens expire (~12 hours)
7. On next copilot invocation, CLI creates a new DCR client (new ephemeral port)
8. Entra ID requires admin consent again for the new client
9. Back to step 4
Expected behavior
Copilot CLI should reuse OAuth client registrations across sessions to avoid triggering repeated admin consent prompts. Specifically:
- Use a preferred fixed port (like VS Code uses 33418) so that DCR'd clients are stable across sessions
- Reuse existing client registration when a cached one exists with the same server, instead of always creating new ones
- Support CIMD (Support CIMD for Remote OAuth MCP Servers #1305) as an alternative to DCR, which avoids per-session client creation
Additional context
- Related: [BUG]: OAuth token refresh fails with invalid redirect_uri when using enterprise MCP servers #1491 (redirect_uri mismatch — same root cause, different symptom)
- Related: Support CIMD for Remote OAuth MCP Servers #1305 (CIMD support — would fix this by avoiding DCR entirely)
- Related: Do not initiate redundant MCP OAuth Flows per server #2036 (redundant OAuth flows per server)
- VS Code does NOT have this issue because it uses a fixed preferred port for OAuth callbacks
- Codex CLI also appears to handle this correctly (confirmed by another team member)
- The Entra ID consent page shows the Keycloak IDP broker app name and requests: "Sign in and read user profile" + "Maintain access to data you have given it access to"