diff --git a/codex-rs/secrets/src/lib.rs b/codex-rs/secrets/src/lib.rs index cdd6fe87c8..8f28ee1407 100644 --- a/codex-rs/secrets/src/lib.rs +++ b/codex-rs/secrets/src/lib.rs @@ -60,6 +60,7 @@ impl SecretScope { } pub fn canonical_key(&self, name: &SecretName) -> String { + // Stable, env-safe identifier used as the on-disk map key. match self { Self::Global => format!("global/{}", name.as_str()), Self::Environment(environment_id) => { diff --git a/codex-rs/secrets/src/local.rs b/codex-rs/secrets/src/local.rs index 83b7027121..f7b15cdcd0 100644 --- a/codex-rs/secrets/src/local.rs +++ b/codex-rs/secrets/src/local.rs @@ -155,6 +155,9 @@ impl LocalSecretsBackend { { Some(existing) => Ok(SecretString::from(existing)), None => { + // Generate a high-entropy key and persist it in the OS keyring. + // This keeps secrets out of plaintext config while remaining + // fully local/offline for the MVP. let generated = generate_passphrase()?; self.keyring_store .save(keyring_service(), &account, generated.expose_secret()) @@ -171,6 +174,7 @@ fn generate_passphrase() -> Result { let mut rng = OsRng; rng.try_fill_bytes(&mut bytes) .context("failed to generate random secrets key")?; + // Base64 keeps the keyring payload ASCII-safe without reducing entropy. let encoded = BASE64_STANDARD.encode(bytes); wipe_bytes(&mut bytes); Ok(SecretString::from(encoded))