mirror of
https://github.com/openai/codex.git
synced 2026-10-23 18:08:45 +00:00
Support confidential OAuth clients for enterprise-managed MCP auth (#56001)
## Why Enterprise-managed MCP authentication previously required public OAuth clients at both the identity provider and the MCP authorization server, preventing use of registrations that require client secrets. ## What changed - Accept separate `client_secret` and `token_endpoint_auth_method` settings for the enterprise IdP and MCP server OAuth registration. Support `client_secret_basic` and `client_secret_post`, defaulting to Basic when a secret is configured. - Validate the registered method against server metadata and use it for enterprise login and both ID-JAG exchanges. - Require a configured `oauth.authorization_server_issuer` for confidential MCP registrations and reject empty secrets or authentication methods without secrets. - Require the account OAuth client to match the configured IdP client before reusing an account grant with a provisioned secret; otherwise use dedicated enterprise login. ## Testing Extend configuration, login, exchange, and app-server lifecycle tests to cover confidential registrations, separate IdP and resource credentials, authentication method validation, and exclusion of client secrets from authorization URLs, stored login grants, and logs. GitOrigin-RevId: b3be378c2b1bb67e6a3652c648e72fd2e21e956d
This commit is contained in:
@@ -169,6 +169,9 @@ fn serialize_mcp_server_table(config: &McpServerConfig) -> anyhow::Result<TomlTa
|
||||
if let Some(client_secret) = &oauth.client_secret {
|
||||
oauth_table["client_secret"] = value(client_secret.as_str());
|
||||
}
|
||||
if let Some(method) = oauth.token_endpoint_auth_method {
|
||||
oauth_table["token_endpoint_auth_method"] = value(method.as_str());
|
||||
}
|
||||
if let Some(callback_url) = &oauth.callback_url {
|
||||
oauth_table["callback_url"] = value(callback_url.clone());
|
||||
}
|
||||
|
||||
@@ -1054,11 +1054,20 @@ fn blocking_replace_mcp_servers_round_trips() {
|
||||
let codex_home = tmp.path();
|
||||
|
||||
let mut servers = BTreeMap::new();
|
||||
servers.insert("ema".to_string(), serde_json::from_value(serde_json::json!({
|
||||
"url": "https://ema.example/mcp", "auth": "ema_auth", "scopes": ["tools"],
|
||||
"oauth_resource": "https://ema.example",
|
||||
"oauth": {"client_id": "resource-client", "authorization_server_issuer": "https://as.example"}
|
||||
})).expect("EMA server"));
|
||||
servers.insert(
|
||||
"ema".to_string(),
|
||||
serde_json::from_value(serde_json::json!({
|
||||
"url": "https://ema.example/mcp", "auth": "ema_auth", "scopes": ["tools"],
|
||||
"oauth_resource": "https://ema.example",
|
||||
"oauth": {
|
||||
"client_id": "resource-client",
|
||||
"client_secret": "test-ema-secret",
|
||||
"token_endpoint_auth_method": "client_secret_post",
|
||||
"authorization_server_issuer": "https://as.example"
|
||||
}
|
||||
}))
|
||||
.expect("EMA server"),
|
||||
);
|
||||
servers.insert(
|
||||
"stdio".to_string(),
|
||||
McpServerConfig {
|
||||
@@ -1154,6 +1163,8 @@ oauth_resource = \"https://ema.example\"
|
||||
|
||||
[mcp_servers.ema.oauth]
|
||||
client_id = \"resource-client\"
|
||||
client_secret = \"test-ema-secret\"
|
||||
token_endpoint_auth_method = \"client_secret_post\"
|
||||
authorization_server_issuer = \"https://as.example\"
|
||||
|
||||
[mcp_servers.http]
|
||||
|
||||
Reference in New Issue
Block a user