fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters - #1311

Closed
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key
Closed

fix: normalize default SOURCEBOT_ENCRYPTION_KEY to 32 characters#1311
brendan-kellam wants to merge 3 commits into
mainfrom
brendan/fix-encryption-key

Conversation

@brendan-kellam

@brendan-kellambrendan-kellam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The default SOURCEBOT_ENCRYPTION_KEY shipped in docker-compose.yml is 33 zeros, but the env validation added in #1305 requires the key to be exactly 32 characters (a 256-bit AES key). This causes startup to fail with the default value.

This is a hacky workaround: the all-zeros default (33 chars) is coerced to 32 chars inside encrypt() and decrypt() in packages/shared/src/crypto.ts, where the key is actually used for AES-256. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env schema (the strict .length(32) check is removed so the default value loads). Any other key value is used unchanged.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed encryption key validation so the default environment value is normalized to the required length at startup.
    • Updated encryption/decryption to gracefully handle a legacy/incorrect 33-character key format by coercing it into a valid 32-character key before deriving cryptographic keys.

brendan-kellamand others added 2 commits June 16, 2026 19:13
The default SOURCEBOT_ENCRYPTION_KEY in docker-compose is 33 zeros, which
fails the 32-character (AES-256) length validation. Preprocess the value so
the all-zeros default is trimmed to 32 characters before validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

The PR handles legacy SOURCEBOT_ENCRYPTION_KEY configuration where the default value is 33 zeros instead of the required 32. A new coerceEncryptionKey helper in crypto.ts normalizes this value at runtime in encrypt and decrypt operations. The environment schema is relaxed to accept any string, delegating validation to the crypto layer. A changelog entry documents the fix.

Changes

Encryption Key Normalization

Layer / File(s)Summary
Encryption key coercion in encrypt and decrypt
packages/shared/src/crypto.ts
A coerceEncryptionKey helper converts the legacy 33-zero key to 32 zeros; encrypt and decrypt use the coerced value for AES key derivation.
Environment validation relaxation and documentation
packages/shared/src/env.server.ts, CHANGELOG.md
SOURCEBOT_ENCRYPTION_KEY schema changed from z.string().length(32) to z.string() with updated comment; changelog Fixed entry documents the 33-to-32 character normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 0.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately summarizes the main change: normalizing the default SOURCEBOT_ENCRYPTION_KEY from 33 to 32 characters to fix a validation issue.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-encryption-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/env.server.ts`:
- Around line 344-355: The SOURCEBOT_ENCRYPTION_KEY preprocessing silently
normalizes the malformed 33-zero key pattern into a valid but cryptographically
weak 32-zero key without alerting the operator. Instead of silently accepting
this weak key, modify the preprocessing function to detect when this pattern is
provided and emit a warning or error message to inform the operator that they
are using a predictable all-zero encryption key and should rotate it
immediately. This ensures security implications are not hidden from deployments
using this migration path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8f1a140d-f0f8-4867-9fbd-2eca574d762d

📥 Commits

Reviewing files that changed from the base of the PR and between e30e75e and 1ba8c53.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/shared/src/env.server.ts

Comment threadpackages/shared/src/env.server.ts Outdated
Comment on lines +344 to +355
SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// @hack in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// @see https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
(value) => value === "0".repeat(33) ? "0".repeat(32) : value,
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`.",
}),
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid silently accepting the known weak all-zero encryption key.

This normalization fixes startup, but it also preserves a predictable key ("0".repeat(32)) for deployments that never rotate it, weakening encryption-at-rest guarantees.

Suggested mitigation
 SOURCEBOT_ENCRYPTION_KEY: z.preprocess(
// `@hack` in our docker-compose.yml, we mistakenly used a
// encryption key with _33_ zeros. As a hacky mechanism to
// fix peoples deployments without requiring them to update
// their encryption key, we look for keys with this pattern
// and coerce them into _32_ zeros.
// `@see` https://github.com/sourcebot-dev/sourcebot/commit/e30e75e7af96308b3b063bb3aed8369f5b15aa2e
- (value) => value === "0".repeat(33) ? "0".repeat(32) : value,+ (value) => {+ if (value === "0".repeat(33)) {+ console.warn(+ "SOURCEBOT_ENCRYPTION_KEY default placeholder detected and normalized. Rotate to a unique 32-character key immediately.",+ );+ return "0".repeat(32);+ }+ return value;+ },
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`.",
}),
),

Based on learnings from provided context, packages/shared/src/crypto.ts:18-47 consumes this env var directly as AES/HMAC key material, so predictable defaults materially reduce secrecy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/env.server.ts` around lines 344 - 355, The
SOURCEBOT_ENCRYPTION_KEY preprocessing silently normalizes the malformed 33-zero
key pattern into a valid but cryptographically weak 32-zero key without alerting
the operator. Instead of silently accepting this weak key, modify the
preprocessing function to detect when this pattern is provided and emit a
warning or error message to inform the operator that they are using a
predictable all-zero encryption key and should rotate it immediately. This
ensures security implications are not hidden from deployments using this
migration path.

Move the 33-zeros -> 32-zeros default key normalization out of the env
schema and into encrypt()/decrypt() in crypto.ts, where the key is
actually used. SOURCEBOT_ENCRYPTION_KEY is now a plain string in the env
schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@brendan-kellam