Skip to content

Stop shipping credentials as shell defaults - #36

Merged
radsilent merged 1 commit into
mainfrom
security/remove-committed-secrets
Aug 27, 2026
Merged

Stop shipping credentials as shell defaults#36
radsilent merged 1 commit into
mainfrom
security/remove-committed-secrets

Conversation

@radsilent

Copy link
Copy Markdown
Owner

What was found

Four credentials are committed to this repository, which is public:

Secret At HEAD In history
License key 2 files 6 commits
Admin API key 4 files 8 commits
Editor API key 4 commits
Viewer API key 3 commits

Every occurrence had the same shape — a real credential used as the fallback in a ${VAR:-default} expansion. The scripts therefore worked with no environment set, so nothing ever failed and the hardcoded value went unnoticed.

What this changes

Six files, all at HEAD:

File Was Now
.env.example working license key your-license-key-here
scripts/dev-up.sh ${VECTORMBE_LICENSE_KEY:-<key>} ${VECTORMBE_LICENSE_KEY:?…}
deploy/recovery/health-check.sh ${VECTORMBE_ADMIN_KEY:-<key>} ${VECTORMBE_ADMIN_KEY:?…}
deploy/recovery/simulate-failure.sh same same
deploy/recovery/validate-deployment.sh same same
deploy/recovery/watchdog.sh same same

${VAR:?message} fails loudly with the message instead of silently falling back to a shared credential. That is the point of the change: a missing key should stop the script, not quietly authenticate as admin.

Verified: no secret value remains anywhere at HEAD, and every modified script passes bash -n.

What this does not fix

Rotate all four keys. They have been readable in a public repository; this PR does not un-publish them. Rotation is the only step that restores control.

They remain in history — 21 commits across the four values. Removing them needs a git filter-repo pass and a force-push, which rewrites all 1661 commits and invalidates every existing clone. Held deliberately, pending rotation.

Check what the frontend ships. ui/dist-prod/env.js assigns the admin key to window.__VSS_ENV.VECTOROWL_API_KEY. That file is not at current HEAD, but it is in history, and any deployed build of that shape hands the admin key to every visitor — independent of GitHub, and unaffected by any history rewrite.

🤖 Generated with Claude Code

Four credentials were committed to this repository: a license key, and
admin, editor and viewer API keys. The repository is public, so all four
must be treated as compromised and rotated regardless of this change.

Every occurrence had the same shape - a real secret used as the fallback
in a ${VAR:-default} expansion, so the scripts kept working with no
environment set and nobody noticed the value was hardcoded.

Each is now a required variable using ${VAR:?message}, which fails
loudly instead of silently falling back to a shared credential, and
.env.example carries a placeholder rather than a working key.

This clears the working tree only. The values remain in history and are
removed separately.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@radsilent
radsilent merged commit 400fafb into main Aug 27, 2026
3 checks passed
@radsilent
radsilent deleted the security/remove-committed-secrets branch August 27, 2026 00:54
Sign up for free to 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