From fbbe7676ae2f0461476d26ba9dc9cadd929f8edb Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sun, 7 Jun 2026 20:43:17 +0200 Subject: [PATCH] fix(shared): F-S-009 require PICLOUD_DEV_INSECURE_KEY acknowledgement for dev master key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PICLOUD_DEV_MODE=true alone fell through to a fully public deterministic master key — SHA-256("picloud-dev-master-key-v1.1.7"). The warning was correct but the gate was a single env var. An operator copying a dev docker-compose file into prod silently encrypted everything with a world-known key. Require both: - PICLOUD_DEV_MODE=true - PICLOUD_DEV_INSECURE_KEY=i-understand-this-is-insecure Without the literal-string acknowledgement, MasterKey::from_env returns the new DevModeUnacknowledged error and the process refuses to start. Production deployments aren't affected (they set PICLOUD_SECRET_KEY). AUDIT.md anchor: F-S-009. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/shared/src/crypto.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/shared/src/crypto.rs b/crates/shared/src/crypto.rs index 8ede3dd..cb03cce 100644 --- a/crates/shared/src/crypto.rs +++ b/crates/shared/src/crypto.rs @@ -144,6 +144,15 @@ pub enum MasterKeyError { /// Decoded to the wrong number of bytes. #[error("PICLOUD_SECRET_KEY must decode to exactly {KEY_LEN} bytes, got {0}")] WrongLength(usize), + + /// F-S-009: PICLOUD_DEV_MODE=true was set without PICLOUD_SECRET_KEY, + /// AND without the explicit PICLOUD_DEV_INSECURE_KEY acknowledgement. + #[error( + "PICLOUD_DEV_MODE=true without PICLOUD_SECRET_KEY requires an explicit acknowledgement. \ + Set PICLOUD_DEV_INSECURE_KEY=i-understand-this-is-insecure to confirm — but never in \ + production: the dev master key is a fully public deterministic value." + )] + DevModeUnacknowledged, } impl MasterKey { @@ -189,6 +198,18 @@ impl MasterKey { let dev_mode = std::env::var("PICLOUD_DEV_MODE") .map(|v| is_truthy(&v)) .unwrap_or(false); + // F-S-009: PICLOUD_DEV_MODE alone falls through to a fully + // public deterministic key (the warning is correct but the gate + // is a single env var — copying a dev docker-compose file into + // prod silently encrypts everything with a world-known key). + // Require an explicit second knob acknowledging the risk before + // we accept dev mode without a real secret. + let dev_ack = std::env::var("PICLOUD_DEV_INSECURE_KEY") + .map(|v| v == "i-understand-this-is-insecure") + .unwrap_or(false); + if dev_mode && secret.as_deref().map(str::trim).unwrap_or("").is_empty() && !dev_ack { + return Err(MasterKeyError::DevModeUnacknowledged); + } Self::resolve(secret.as_deref(), dev_mode) }