Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-27504.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"analysis_mode": "pr_first",
"commits": [
{
"author": "celia-oai",
"committed_at": "2026-06-11T00:56:21Z",
"message": "Add secret auth storage config",
"sha": "07d66eccd904cd15cd754c43d3f74a72d63a1980",
"url": "https://github.com/openai/codex/commit/07d66eccd904cd15cd754c43d3f74a72d63a1980"
},
{
"author": "celia-oai",
"committed_at": "2026-06-12T18:51:10Z",
"message": "refactor",
"sha": "3e3379b56006b9e877f5db4ba65009b4ad41c49c",
"url": "https://github.com/openai/codex/commit/3e3379b56006b9e877f5db4ba65009b4ad41c49c"
}
],
"default_branch": "main",
"docs_refs": [],
"examples_refs": [],
"extracted_flags": [
"MCP",
"CLI",
"TUI",
"CONFIG_TOML_FILE",
"LOCAL_FS",
"FEATURES"
],
"files": [
{
"additions": 20,
"deletions": 0,
"patch_excerpt": "@@ -113,6 +113,26 @@ pub enum OAuthCredentialsStoreMode {\n Keyring,\n }\n \n+/// Determine how auth credentials should use keyring-backed storage.\n+#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]\n+#[serde(rename_all = \"lowercase\")]\n+pub enum AuthKeyringBackendKind {\n+ /// Store the serialized auth payload directly in the OS keyring.\n+ Direct,\n+ /// Store auth payloads in the local encrypted secrets file, with the file key in the OS keyring.\n+ Secrets,\n+}\n+\n+impl Default for AuthKeyringBackendKind {\n+ fn default() -> Self {\n+ if cfg!(windows) {\n+ Self::Secrets\n+ } else {\n+ Self::Direct\n+ }\n+ }\n+}\n+\n #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema)]\n #[serde(rename_all = \"kebab-case\")]\n pub enum WindowsSandboxModeToml {",
"path": "codex-rs/config/src/types.rs",
"status": "modified"
},
{
"additions": 6,
"deletions": 0,
"patch_excerpt": "@@ -599,6 +599,9 @@\n \"search_tool\": {\n \"type\": \"boolean\"\n },\n+ \"secret_auth_storage\": {\n+ \"type\": \"boolean\"\n+ },\n \"shell_snapshot\": {\n \"type\": \"boolean\"\n },\n@@ -4751,6 +4754,9 @@\n \"search_tool\": {\n \"type\": \"boolean\"\n },\n+ \"secret_auth_storage\": {\n+ \"type\": \"boolean\"\n+ },\n \"shell_snapshot\": {\n \"type\": \"boolean\"\n },",
"path": "codex-rs/core/config.schema.json",
"status": "modified"
},
{
"additions": 59,
"deletions": 0,
"patch_excerpt": "@@ -0,0 +1,59 @@\n+use super::Config;\n+use super::ConfigTomlLoadResult;\n+use super::ManagedFeatures;\n+use codex_config::types::AuthKeyringBackendKind;\n+use codex_features::Feature;\n+use codex_features::FeatureConfigSource;\n+use codex_features::FeatureOverrides;\n+use codex_features::Features;\n+\n+impl Config {\n+ pub fn auth_keyring_backend_kind(&self) -> AuthKeyringBackendKind {\n+ auth_keyring_backend_kind_from_secret_auth_storage(\n+ self.features.enabled(Feature::SecretAuthStorage),\n+ )\n+ }\n+}\n+\n+/// Resolve the auth keyring backend from a partially loaded bootstrap config.\n+///\n+/// This is intended for startup paths that must read auth before managed cloud\n+/// requirements can be loaded and before a full [`Config`] exists.\n+pub fn resolve_bootstrap_auth_keyring_backend_kind(\n+ bootstrap_config: &ConfigTomlLoadResult,\n+) -> std::io::Result<AuthKeyringBac...",
"path": "codex-rs/core/src/config/auth_keyring.rs",
"status": "added"
},
{
"additions": 79,
"deletions": 0,
"patch_excerpt": "@@ -0,0 +1,79 @@\n+use super::*;\n+use codex_config::ConfigLayerStack;\n+use codex_config::ConfigRequirements;\n+use codex_config::ConfigRequirementsToml;\n+use codex_config::FeatureRequirementsToml;\n+use codex_config::RequirementSource;\n+use codex_config::Sourced;\n+use codex_config::config_toml::ConfigToml;\n+use codex_features::FeaturesToml;\n+use pretty_assertions::assert_eq;\n+use std::collections::BTreeMap;\n+\n+#[test]\n+fn resolve_bootstrap_auth_keyring_backend_kind_uses_secret_auth_storage_feature()\n+-> std::io::Result<()> {\n+ let config_toml = ConfigToml {\n+ features: Some(FeaturesToml::from(BTreeMap::from([(\n+ \"secret_auth_storage\".to_string(),\n+ true,\n+ )]))),\n+ ..Default::default()\n+ };\n+ assert_eq!(\n+ resolve_bootstrap_auth_keyring_backend_kind(&config_toml_load_result(\n+ config_toml,\n+ /*feature_requireme...",
"path": "codex-rs/core/src/config/auth_keyring_tests.rs",
"status": "added"
},
{
"additions": 2,
"deletions": 0,
"patch_excerpt": "@@ -4,8 +4,10 @@ use crate::config::edit::apply_blocking;\n use assert_matches::assert_matches;\n use codex_config::CONFIG_TOML_FILE;\n use codex_config::ConfigLayerEntry;\n+use codex_config::ConfigLayerStack;\n use codex_config::ProfileV2Name;\n use codex_config::RequirementSource;\n+use codex_config::Sourced;\n use codex_config::config_toml::AgentRoleToml;\n use codex_config::config_toml::AgentsToml;\n use codex_config::config_toml::AutoReviewToml;",
"path": "codex-rs/core/src/config/config_tests.rs",
"status": "modified"
},
{
"additions": 29,
"deletions": 1,
"patch_excerpt": "@@ -137,6 +137,7 @@ use toml::Value as TomlValue;\n use toml_edit::DocumentMut;\n \n pub(crate) mod agent_roles;\n+mod auth_keyring;\n pub mod edit;\n mod managed_features;\n mod network_proxy_spec;\n@@ -145,6 +146,7 @@ mod permissions;\n mod resolved_permission_profile;\n #[cfg(test)]\n mod schema;\n+pub use auth_keyring::resolve_bootstrap_auth_keyring_backend_kind;\n pub use codex_config::ConfigLoadOptions;\n pub use codex_config::Constrained;\n pub use codex_config::ConstraintError;\n@@ -1647,6 +1649,29 @@ pub async fn load_config_as_toml_with_cli_and_load_options(\n cli_overrides: Vec<(String, TomlValue)>,\n options: impl Into<ConfigLoadOptions>,\n ) -> std::io::Result<ConfigToml> {\n+ load_config_toml_with_layer_stack(codex_home, cwd, cli_overrides, options)\n+ .await\n+ .map(|result| result.config_toml)\n+}\n+\n+/// Partially loaded config plus the layer stack used to derive it.\n+/...",
"path": "codex-rs/core/src/config/mod.rs",
"status": "modified"
},
{
"additions": 8,
"deletions": 0,
"patch_excerpt": "@@ -81,6 +81,8 @@ pub enum Feature {\n ShellTool,\n /// Enable Claude-style lifecycle hooks loaded from hooks.json files.\n CodexHooks,\n+ /// Store CLI auth in the encrypted local secrets backend when keyring storage is selected.\n+ SecretAuthStorage,\n \n // Experimental\n /// Enable JavaScript code mode backed by the in-process V8 runtime.\n@@ -748,6 +750,12 @@ pub const FEATURES: &[FeatureSpec] = &[\n stage: Stage::Stable,\n default_enabled: true,\n },\n+ FeatureSpec {\n+ id: Feature::SecretAuthStorage,\n+ key: \"secret_auth_storage\",\n+ stage: Stage::Stable,\n+ default_enabled: cfg!(windows),\n+ },\n FeatureSpec {\n id: Feature::UnifiedExec,\n key: \"unified_exec\",",
"path": "codex-rs/features/src/lib.rs",
"status": "modified"
},
{
"additions": 10,
"deletions": 0,
"patch_excerpt": "@@ -189,6 +189,16 @@ fn tool_search_is_removed_and_disabled_by_default() {\n assert_eq!(feature_for_key(\"tool_search\"), Some(Feature::ToolSearch));\n }\n \n+#[test]\n+fn secret_auth_storage_defaults_to_windows_only() {\n+ assert_eq!(Feature::SecretAuthStorage.stage(), Stage::Stable);\n+ assert_eq!(Feature::SecretAuthStorage.default_enabled(), cfg!(windows));\n+ assert_eq!(\n+ feature_for_key(\"secret_auth_storage\"),\n+ Some(Feature::SecretAuthStorage)\n+ );\n+}\n+\n #[test]\n fn browser_controls_are_stable_and_enabled_by_default() {\n assert_eq!(Feature::InAppBrowser.stage(), Stage::Stable);",
"path": "codex-rs/features/src/tests.rs",
"status": "modified"
}
],
"linked_issues": [
"#17931"
],
"notes": [
"Built from GitHub pull-request, commits, files, and repo endpoints."
],
"primary_pr": {
"body": "## Why\n\nWindows Credential Manager limits generic credential blobs to 2,560 bytes. The encrypted local secrets backend avoids storing large serialized auth payloads directly in the OS keyring, but selecting that backend needs an independently reviewable feature/config layer before the auth and secrets implementation is wired in.\n\n## What Changed\n\n- Added the stable `secret_auth_storage` feature, enabled by default on Windows and disabled by default elsewhere.\n- Added `AuthKeyringBackendKind` and config resolution for full and bootstrap config loading.\n- Applied managed feature requirements when resolving the bootstrap auth backend.\n- Updated the generated config schema and added focused tests.\n\nThis is the base PR for #17931. The auth, secrets, MCP, CLI, TUI, and app-server implementation remains in that follow-up PR.\n\n## Validation\n\n- `just test -p codex-features`\n- `just test -p codex-config`\n- `just test -p codex-core resolve_bootstrap_auth_keyring_backend_kind_uses_secret_auth_storage_feature`\n- `just write-config-schema`\n- `just fix -p codex-core`\n\nThe full `just test -p codex-core` run compiled successfully and ran 2,690 tests; 2,589 passed, one was flaky, and 101 environment-sensitive tests failed because this shell injects a `pyenv` rehash warning into command output or because sandboxed subprocesses timed out.\n",
"labels": [],
"merged_at": "2026-06-12T19:15:22Z",
"number": 27504,
"state": "merged",
"title": "feat: add secret auth storage configuration",
"url": "https://github.com/openai/codex/pull/27504"
},
"repo": "openai/codex",
"schema": "github_change_bundle/v1"
}
47 changes: 47 additions & 0 deletions artifacts/github/impact/openai-codex-pr-27504.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"schema": "upstream_impact/v1",
"slug": "openai-codex-pr-27504",
"repo": "openai/codex",
"source_refs": {
"items": [
{
"kind": "pull_request",
"title": "feat: add secret auth storage configuration",
"url": "https://github.com/openai/codex/pull/27504",
"meta": "Merged 2026-06-12T19:15:22Z"
},
{
"kind": "pull_request",
"title": "Source-backed Decodex upstream review",
"url": "https://github.com/openai/codex/pull/27504",
"meta": "artifacts/github/reviews/openai-codex-pr-27504.review.json"
}
]
},
"observed_change": "Codex adds a stable `secret_auth_storage` feature and `AuthKeyringBackendKind` config resolution so auth credential storage can select direct keyring or encrypted-local secrets backends, with Windows defaulting to secrets.",
"public_signal_decision": "defer",
"control_plane_impact": "compat_risk",
"publisher_angle": "watch_note",
"confidence": "confirmed",
"evidence": [
"The upstream review records `secret_auth_storage`, `AuthKeyringBackendKind`, bootstrap resolution, managed feature requirements, schema updates, and tests.",
"The PR body says this is the independently reviewable configuration layer before auth and secrets implementation follow-ups.",
"The feature is stable, defaults on for Windows, and maps to the encrypted-local secrets backend when enabled.",
"Bootstrap auth backend resolution applies managed feature requirements before a full Config exists.",
"The source-backed review is recorded at `artifacts/github/reviews/openai-codex-pr-27504.review.json`."
],
"candidate_followups": [
"Audit Decodex managed config and auth-inspection paths for assumptions that Codex auth always uses direct OS keyring storage.",
"Preserve `secret_auth_storage` when reading or writing Codex feature configuration, especially for Windows and managed-requirement contexts.",
"Evaluate the auth-storage stack as a whole with PRs #27535, #27539, and #27541 before filing implementation work."
],
"social_notes": [
"Use deferred watch-note framing because PR #27504 is only the configuration layer.",
"Do not imply CLI auth, MCP OAuth, TUI, or app-server secret storage behavior shipped in this PR alone.",
"Combine with later source-backed auth-storage reviews for any stronger public explanation."
],
"caveats": [
"The PR explicitly says auth, secrets, MCP, CLI, TUI, and app-server implementation remains in follow-ups.",
"The compatibility risk becomes concrete when downstream code consumes the follow-up auth-storage implementation."
]
}
Loading