Add runtime assertion authentication modes and an auth provider (#55636)

## What changed

Add `RuntimeAuthProvider` to resolve request authentication through the runtime auth manager. Support `dual_header` mode, which sends a bearer credential alongside `x-openai-agent-assertion`, and `assertion_only` mode, which uses `Authorization: AgentAssertion …`.

Replace stale authentication headers and sign a fresh assertion for each request attempt. Propagate registration failures without falling back to credential-only authentication, preserving policy errors and classifying transport failures, rate limits, and server errors as transient.

Add the disabled-by-default `features.runtime_agent_instances` configuration with independent `enabled` and `mode` settings, schema support, and structured override merging. Selecting a mode alone does not enable the feature.

## Testing

Add coverage for both modes with API key and ChatGPT credentials, stale header replacement, fresh assertions, credential refresh without runtime replacement, registration failures, and configuration parsing and merging.

GitOrigin-RevId: 9e93d25762600f0ff592c5248fe4c8c2c8182c8d
This commit is contained in:
cooper-oai
2026-10-20 17:29:40 +00:00
committed by copyberry
parent a13ab7e4ed
commit cb00a67569
12 changed files with 444 additions and 39 deletions
+5 -1
View File
@@ -70,7 +70,11 @@ pub fn is_structured_feature_path<S: AsRef<str>>(path: &[S]) -> bool {
features.as_ref() == "features"
&& matches!(
feature.as_ref(),
"code_mode" | "multi_agent_v2" | "network_proxy" | "sleep_tool"
"code_mode"
| "multi_agent_v2"
| "network_proxy"
| "sleep_tool"
| "runtime_agent_instances"
)
}
+31 -26
View File
@@ -295,33 +295,38 @@ fn code_mode_overrides_preserve_enabled_state_and_cell_overhead() {
}
#[test]
fn sleep_tool_overrides_preserve_disabled_state_and_mode() {
for feature_path in ["features", "profiles.work.features"] {
let disabled = (
format!("{feature_path}.sleep_tool"),
TomlValue::Boolean(false),
);
let mode = (
format!("{feature_path}.sleep_tool.mode"),
TomlValue::String("always_on".to_string()),
);
let expected = parse_toml(&format!(
"[{feature_path}.sleep_tool]\nenabled = false\nmode = \"always_on\"\n",
));
for overrides in [vec![disabled.clone(), mode.clone()], vec![mode, disabled]] {
assert_eq!(crate::build_cli_overrides_layer(&overrides), expected);
}
fn structured_mode_overrides_preserve_disabled_state_and_mode() {
for (feature, selected_mode) in [
("sleep_tool", "always_on"),
("runtime_agent_instances", "assertion_only"),
] {
for feature_path in ["features", "profiles.work.features"] {
let disabled = (
format!("{feature_path}.{feature}"),
TomlValue::Boolean(false),
);
let mode = (
format!("{feature_path}.{feature}.mode"),
TomlValue::String(selected_mode.to_string()),
);
let expected = parse_toml(&format!(
"[{feature_path}.{feature}]\nenabled = false\nmode = \"{selected_mode}\"\n",
));
for overrides in [vec![disabled.clone(), mode.clone()], vec![mode, disabled]] {
assert_eq!(crate::build_cli_overrides_layer(&overrides), expected);
}
let boolean_layer = parse_toml(&format!("[{feature_path}]\nsleep_tool = false\n"));
let table_layer = parse_toml(&format!(
"[{feature_path}.sleep_tool]\nmode = \"always_on\"\n",
));
for (mut base, overlay) in [
(boolean_layer.clone(), table_layer.clone()),
(table_layer, boolean_layer),
] {
merge_toml_values(&mut base, &overlay);
assert_eq!(base, expected);
let boolean_layer = parse_toml(&format!("[{feature_path}]\n{feature} = false\n"));
let table_layer = parse_toml(&format!(
"[{feature_path}.{feature}]\nmode = \"{selected_mode}\"\n",
));
for (mut base, overlay) in [
(boolean_layer.clone(), table_layer.clone()),
(table_layer, boolean_layer),
] {
merge_toml_values(&mut base, &overlay);
assert_eq!(base, expected);
}
}
}
}
+9
View File
@@ -153,6 +153,15 @@ pub fn features_schema(schema_gen: &mut SchemaGenerator) -> Schema {
);
continue;
}
if feature.id == codex_features::Feature::RuntimeAgentInstances {
validation.properties.insert(
feature.key.to_string(),
schema_gen.subschema_for::<codex_features::FeatureToml<
codex_features::RuntimeAgentInstancesConfigToml,
>>(),
);
continue;
}
if feature.id == codex_features::Feature::AppsMcpPathOverride {
validation.properties.insert(
feature.key.to_string(),