diff --git a/CHANGELOG.md b/CHANGELOG.md index 73582aabb..cff95faf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the ability to configure email code and credentials login from the security settings. [#1303](https://github.com/sourcebot-dev/sourcebot/pull/1303) - Added a list of configured SSO providers from the security settings. [#1303](https://github.com/sourcebot-dev/sourcebot/pull/1303) +### Fixed +- Validated that `SOURCEBOT_ENCRYPTION_KEY` is exactly 32 characters at startup, failing fast with an actionable message instead of a runtime encryption error. [#1305](https://github.com/sourcebot-dev/sourcebot/pull/1305) + ## [5.0.2] - 2026-06-11 ### Changed diff --git a/packages/shared/src/env.server.ts b/packages/shared/src/env.server.ts index b6d49327c..4b8d7d8ef 100644 --- a/packages/shared/src/env.server.ts +++ b/packages/shared/src/env.server.ts @@ -337,7 +337,13 @@ const options = { PERMISSION_SYNC_REPO_DRIVEN_ENABLED: booleanSchema.default('true'), EXPERIMENT_ASK_GH_ENABLED: booleanSchema.default('false'), - SOURCEBOT_ENCRYPTION_KEY: z.string(), + // Used as the key for AES-256-CBC encryption (@see shared/src/crypto.ts). + // The key is read as ASCII (1 char = 1 byte), so AES-256's 32-byte key + // requirement means this must be exactly 32 characters. Generate one with + // `openssl rand -base64 24` (24 random bytes => a 32-character base64 string). + SOURCEBOT_ENCRYPTION_KEY: z.string().length(32, { + message: "SOURCEBOT_ENCRYPTION_KEY must be exactly 32 characters (a 256-bit AES key). Generate one with `openssl rand -base64 24`.", + }), SOURCEBOT_INSTALL_ID: z.string().default("unknown"), SOURCEBOT_LIGHTHOUSE_URL: z.string().url().default("https://deployments.sourcebot.dev"), diff --git a/packages/shared/vitest.config.ts b/packages/shared/vitest.config.ts index 74728183f..35f8c7016 100644 --- a/packages/shared/vitest.config.ts +++ b/packages/shared/vitest.config.ts @@ -11,7 +11,7 @@ export default defineConfig({ SOURCEBOT_PUBLIC_KEY_PATH: '/tmp/test-key', NODE_ENV: 'test', CONFIG_PATH: '/tmp/test-config.json', - SOURCEBOT_ENCRYPTION_KEY: 'test-encryption-key-32-characters!', + SOURCEBOT_ENCRYPTION_KEY: 'test-encryption-key-32chars-pad!', SOURCEBOT_LIGHTHOUSE_URL: 'http://localhost:3003', } }