Fix enterprise MCP credential selection and reauthentication (#55859)

## What changed

- Prefer an eligible account grant over saved enterprise credentials, with a fallback to saved enterprise sign-in during initial connection if the account grant is rejected.
- Remember rejected account grants per enterprise MCP registration across threads and report authentication failures as requiring reauthentication. Keep administrator configuration errors distinct from sign-in failures.
- Compare account grants independently of access and ID token rotation, recheck the latest identity eligibility after exchange, and retry once when the refresh grant changes.
- Make MCP authentication status reflect usable account grants, saved enterprise credentials, and completed connection failures.

## Testing

Extend regression coverage for enterprise sign-in failures and recovery, MCP authentication status, account grant identity across token refreshes, and retries after transient credential failures.

GitOrigin-RevId: eeac65f668d5d2d55e9d8bf4547fbcbdd6a6c42d
This commit is contained in:
jif
2026-10-21 10:40:59 +00:00
committed by copyberry
parent 6bae551093
commit c419fd01a7
23 changed files with 520 additions and 72 deletions
+6
View File
@@ -128,6 +128,7 @@ struct PublishedMcpRuntime {
config: Option<Arc<McpConfig>>,
auth: Option<CodexAuth>,
auth_token: Option<String>,
auth_manager: Option<Arc<AuthManager>>,
auth_generation: Arc<()>,
plugins_available: bool,
ready_selected_capability_roots: Vec<SelectedCapabilityRoot>,
@@ -238,6 +239,7 @@ impl McpRuntime {
config: None,
auth: None,
auth_token: None,
auth_manager: None,
auth_generation: Arc::new(()),
plugins_available: false,
ready_selected_capability_roots: Vec::new(),
@@ -376,6 +378,7 @@ impl McpRuntime {
let (publish, publication_gate) = McpPublicationGate::pending();
let config = Arc::clone(&input.config);
let auth = input.auth.clone();
let auth_manager = input.auth_manager.clone();
let auth_token = auth.as_ref().and_then(|auth| auth.get_token().ok());
let auth_generation = if current.auth_matches(auth.as_ref()) {
Arc::clone(&current.auth_generation)
@@ -415,6 +418,7 @@ impl McpRuntime {
config: Some(config),
auth,
auth_token,
auth_manager,
auth_generation,
plugins_available,
ready_selected_capability_roots,
@@ -1119,6 +1123,7 @@ mod tests {
config: Some(Arc::new(config)),
auth: None,
auth_token: None,
auth_manager: None,
auth_generation: Arc::new(()),
plugins_available: false,
ready_selected_capability_roots: Vec::new(),
@@ -1193,6 +1198,7 @@ mod tests {
))),
auth: None,
auth_token: None,
auth_manager: None,
auth_generation: Arc::new(()),
plugins_available: false,
ready_selected_capability_roots: Vec::new(),