mirror of
https://github.com/openai/codex.git
synced 2026-11-09 20:50:33 +00:00
## Why Cached executor MCP declarations must not gain access to host environment credentials when reconnecting to an executor that lacks environment credential resolution. ## What changed - Retain credential policy through MCP registration, catalog materialization, and runtime setup. Derive selected HTTP plugin policy from the plugin's source environment. - Reject host bearer-token fallback and transports requiring host environment headers or helpers for executor-owned declarations. Preserve host-configured credential resolution. - Include credential policy in connection and tool catalog cache identities, and avoid reading host environment values for executor-only identities. ## Testing Add regression coverage for legacy executors, cached declarations after a capability downgrade, policy preservation through catalog rebuilds, and connection and tool cache isolation. GitOrigin-RevId: 2d5b85e4e98668c637c538cbe528914c936bd831
60 lines
2.1 KiB
Rust
60 lines
2.1 KiB
Rust
//! Credential resolution must retain executor provenance when host fallback is considered.
|
|
|
|
use super::resolve_bearer_token;
|
|
use crate::server::McpCredentialPolicy;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn executor_credentials_reject_host_fallback_for_arbitrary_environment_names() {
|
|
for env_var in ["PATH", "MCP_UNPROTECTED_TEST_TOKEN"] {
|
|
let error = resolve_bearer_token("docs", Some(env_var), McpCredentialPolicy::ExecutorOnly)
|
|
.expect_err("executor credential names must never resolve on the host");
|
|
|
|
assert_eq!(
|
|
error.to_string(),
|
|
"MCP server 'docs' requires executor-side environment credential resolution; update the executor to a version that supports it (host fallback is disabled)",
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn servers_without_environment_credentials_do_not_require_host_fallback() {
|
|
for policy in [
|
|
McpCredentialPolicy::ExecutorOnly,
|
|
McpCredentialPolicy::HostFallbackAllowed,
|
|
] {
|
|
assert_eq!(
|
|
resolve_bearer_token("docs", /*bearer_token_env_var*/ None, policy)
|
|
.expect("a server without an environment credential needs no resolution"),
|
|
None,
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn configured_credentials_retain_host_environment_resolution() {
|
|
// PATH is nonsecret and read without changing the process environment.
|
|
let expected = match std::env::var("PATH") {
|
|
Ok(value) if value.is_empty() => {
|
|
Err("Environment variable PATH for MCP server 'docs' is empty".to_string())
|
|
}
|
|
Ok(value) => Ok(Some(value)),
|
|
Err(std::env::VarError::NotPresent) => {
|
|
Err("Environment variable PATH for MCP server 'docs' is not set".to_string())
|
|
}
|
|
Err(std::env::VarError::NotUnicode(_)) => Err(
|
|
"Environment variable PATH for MCP server 'docs' contains invalid Unicode".to_string(),
|
|
),
|
|
};
|
|
|
|
assert_eq!(
|
|
resolve_bearer_token(
|
|
"docs",
|
|
Some("PATH"),
|
|
McpCredentialPolicy::HostFallbackAllowed
|
|
)
|
|
.map_err(|error| error.to_string()),
|
|
expected,
|
|
);
|
|
}
|