Support caller-provided MITM CAs in the network proxy (#47132)

## What changed

- Add optional `network.mitm_ca` configuration with `certificate_file` and
  `private_key_file` for trusted proxy configuration. Require MITM to be enabled
  and retain the generated CA when no external CA is configured.
- Validate absolute paths, regular files, file sizes, certificate/key matching,
  and Unix private-key permissions. Reject symlinks on Unix, private keys embedded
  in certificate files, and external private keys on non-Unix platforms.
- Store derived external-CA trust bundles in the proxy artifact directory,
  include only certificates, and skip inherited generated bundles to avoid
  retaining stale roots.
- Preserve MITM for external CAs when disabling credential brokerage. Reject
  external CA configuration for remote execution, even when the proxy is disabled,
  and reject unknown fields in `NetworkProxyConfig`.
- Default the upstream request version adapter to HTTP/1.1 and remove the request
  URI from upstream request failure context.

## Testing

Add regression coverage for external CA configuration, mismatched keys, embedded
private keys, non-Unix rejection, trust-bundle placement and contents, stale-root
exclusion, credential-broker toggling, and remote configuration rejection.

GitOrigin-RevId: cb209295c19fbe53a9fa0194f11ff06acccabef6
This commit is contained in:
viyatb-oai
2026-09-21 23:43:52 +00:00
committed by copyberry
parent cf6754e682
commit e4dba902ab
13 changed files with 470 additions and 68 deletions
+8 -2
View File
@@ -450,7 +450,13 @@ impl NetworkProxyRuntimeSettings {
fn from_config(config: &config::NetworkProxyConfig) -> Result<Self> {
let mitm_ca_trust_bundle = if config.mitm {
let env = crate::certs::ca_env_from_process();
Some(crate::certs::managed_ca_trust_bundle(&env)?)
Some(match config.mitm_ca.as_ref() {
Some(ca) => crate::certs::managed_ca_trust_bundle_for_external_cert_path(
std::path::Path::new(&ca.certificate_file),
&env,
)?,
None => crate::certs::managed_ca_trust_bundle(&env)?,
})
} else {
None
};
@@ -969,7 +975,7 @@ impl NetworkProxy {
config.enabled &= !broker_only;
config.credential_broker = false;
config.dangerously_allow_plaintext_credential_injection = false;
if config.mitm && config.mitm_hooks.is_empty() {
if config.mitm && config.mitm_hooks.is_empty() && config.mitm_ca.is_none() {
config.mitm = false;
}
}