Skip to content

fix(security): strip plaintext credentials from the tree - #1258

Merged
gHashTag merged 1 commit into
mainfrom
fix/strip-plaintext-credentials
Oct 2, 2026
Merged

gHashTag merged 1 commit into
mainfrom
fix/strip-plaintext-credentials

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Removes plaintext credentials from the current tree of main, replacing each with an environment-variable reference. Credentials must be rotated; history still contains them. No history was rewritten and nothing was force-pushed. No secret value appears in this PR body or in the commit message.

Credentials found (file:line on main @ cd5e41f, TYPE only)

File:line Credential type Replacement
fpga/fly-vivado/setup_and_synth.exp:9 AMD/Xilinx account e-mail (login identifier) $env(AMD_ACCOUNT_EMAIL)
fpga/fly-vivado/setup_and_synth.exp:11 AMD/Xilinx account password $env(AMD_ACCOUNT_PASSWORD), script exits 1 if either is unset
docs/book/book/generator/coptic_mega_translator.py:13 DeepSeek API key (sk-) os.environ.get("DEEPSEEK_API_KEY", "")
docs/book/book/generator/llm_book_generator.py:15 DeepSeek API key (same key) same
docs/book/book/generator/llm_deep_generator.py:14 DeepSeek API key (same key) same
docs/book/book/generator/llm_parallel_generator.py:14 DeepSeek API key (same key) same
.trinity/ralph/scripts/report.sh:5 Telegram bot token (bot A) ${TELEGRAM_BOT_TOKEN:?...}
fpga/tools/ralph-cron.sh:53 Telegram bot token (bot A, as default value) ${RALPH_TELEGRAM_BOT_TOKEN:-}
.trinity/ralph/scripts/test_telegram.sh:4 Telegram bot token (bot B, a second bot) ${TELEGRAM_BOT_TOKEN:?...}
targets/kaggle/kaggle/*.py (24 files, line 2-15 each) Kaggle API token (KGAT_, two distinct tokens) removed the os.environ[...] = ... line; read from the environment
targets/kaggle/kaggle/{explore_benchmark_creation.py:7, test_full_run.py:4, test_full_run2.py:4, test_full_run3.py:4, test_models2.py:4} z.ai/GLM-style model proxy API key (MODEL_PROXY_API_KEY) read from the environment
docs/docs/development/ralph.md:476 z.ai/GLM-style fallback API key in a doc example placeholder plus a note to read the value from Railway or Infisical
.trinity/ralph/queue/.creds:1 z.ai/GLM-style API key in a tracked local config file file untracked (git rm --cached) and added to .gitignore

Kaggle files touched: check_benchmark_api.py, check_benchmark_button.py, check_dataset_status.py, check_dataset_via_api.py, check_kaggle_user.py, check_kbench3.py, check_kbench4.py, create_benchmark.py, create_benchmark_api.py, create_dataset.py, create_kaggle_dataset.py, create_test_benchmark.py, explore_benchmark_creation.py, explore_kaggle_api.py, test_full.py, test_full_run.py, test_full_run2.py, test_full_run3.py, test_kaggle_api.py, test_kaggle_cli.py, test_kaggle_modules.py, test_models.py, test_models2.py, test_register.py.

Owner action: rotate all of these

  1. AMD/Xilinx account password (and consider the account compromised until rotated).
  2. DeepSeek API key.
  3. Both Telegram bot tokens (via @Botfather /revoke).
  4. Both Kaggle API tokens.
  5. The z.ai/GLM-style key(s) (MODEL_PROXY_API_KEY, FALLBACK_API_KEY, .creds API_KEY).

After rotation, store new values in Railway/Infisical under: AMD_ACCOUNT_EMAIL, AMD_ACCOUNT_PASSWORD, DEEPSEEK_API_KEY, TELEGRAM_BOT_TOKEN / RALPH_TELEGRAM_BOT_TOKEN, KAGGLE_API_TOKEN, MODEL_PROXY_API_KEY.

Not changed (checked, not live secrets)

deploy/trinity-nexus/ralph/queue/.api_keys.conf (keys empty), .env.example files (placeholders), tools/telegram-bridge/internal/config/config_test.go (dummy local DB URL), src/*/crypto.zig, src/*/agent.zig (test literals), deploy/trinity-nexus/vibee/archive/ai_security_scanner.vibee:360 (an obvious sk-1234567890... sample).

Pre-existing (not introduced here): targets/kaggle/kaggle/create_kaggle_dataset.py and create_test_benchmark.py already fail py_compile on main.

{
  "version": 1,
  "head_sha": "e56321c9dd199c9a9494e9196a226c76cbea8d91",
  "summary": "Removes plaintext credentials (AMD account password, DeepSeek key, Telegram bot tokens, Kaggle tokens, z.ai-style keys) from the current tree and replaces them with environment-variable references; history is untouched and rotation is required.",
  "changes": [
    "The Vivado AuthTokenGen expect script reads the AMD account e-mail and password from the environment and fails fast when they are unset.",
    "Four book generator scripts read the DeepSeek API key from the environment instead of a hardcoded literal.",
    "Twenty-four Kaggle scripts no longer assign a hardcoded Kaggle token or model proxy key into os.environ.",
    "Three ralph shell scripts take the Telegram bot token from the environment with no embedded default.",
    "The ralph documentation example uses a placeholder key, and the tracked ralph queue credentials file is untracked and gitignored."
  ],
  "tests": [
    {
      "command": "git show HEAD | grep '^+' | grep -cE 'KGAT_|sk-[A-Za-z0-9]{20}|[0-9]{8,10}:AA|[0-9a-f]{32}\\.'",
      "result": "Zero added lines match any of the credential patterns that were found.",
      "status": "passed",
      "evidence": "The command printed 0 on the pushed head commit."
    },
    {
      "command": "git grep -nIE 'KGAT_[A-Za-z0-9]{20,}|sk-[A-Za-z0-9]{20,}|[0-9]{8,10}:AA[A-Za-z0-9_-]{30,}|[0-9a-f]{32}\\.[A-Za-z0-9]{16}'",
      "result": "No remaining matches anywhere in the tree after the change.",
      "status": "passed",
      "evidence": "Empty output on the branch head after untracking the credentials file."
    },
    {
      "command": "bash -n .trinity/ralph/scripts/report.sh .trinity/ralph/scripts/test_telegram.sh fpga/tools/ralph-cron.sh && python3 -m py_compile <changed .py files>",
      "result": "Shell scripts parse; all changed Python files compile except two that already failed on main.",
      "status": "passed",
      "evidence": "create_kaggle_dataset.py and create_test_benchmark.py fail identically on main before this change."
    },
    {
      "command": "expect fpga/fly-vivado/setup_and_synth.exp",
      "result": "Not executed because it needs the Vivado installer and a real AMD account.",
      "status": "not_run",
      "evidence": "The change only swaps two send literals for env lookups plus an unset guard."
    }
  ],
  "limitations": [
    "Git history still contains every removed value, so each credential must be rotated by the owner.",
    "Scripts that relied on the embedded values now need the matching environment variables set from Railway or Infisical."
  ],
  "tags": ["security", "secrets", "credentials"],
  "blog": {
    "title": "Plaintext credentials removed from the trinity tree",
    "summary": "An earlier review found an AMD account password and a DeepSeek key in plaintext; a sweep found Telegram, Kaggle and z.ai-style keys too, and all now come from the environment.",
    "outline": [
      "What the sweep looked for, which patterns it used, and which credential types it found in the current tree of main.",
      "How each value was replaced with an environment-variable reference written in the language of the file that held it.",
      "Why git history was left alone, no force push was used, and why rotating every key is the real remedy for a leak."
    ]
  }
}

🤖 Generated with Claude Code

Replace hardcoded secrets with environment-variable references:
- AMD/Xilinx account e-mail and password in the Vivado AuthTokenGen
  expect script -> $env(AMD_ACCOUNT_EMAIL) / $env(AMD_ACCOUNT_PASSWORD),
  failing fast when unset.
- DeepSeek API key in four book generator scripts -> os.environ.
- Kaggle API token (24 scripts) and a z.ai-style model proxy key
  (5 scripts) under targets/kaggle -> read from the environment.
- Telegram bot tokens in two ralph scripts and one default in
  ralph-cron.sh -> required env var / empty default.
- A fallback API key in docs/docs/development/ralph.md -> placeholder
  with a note to read it from Railway or Infisical.
- Untrack .trinity/ralph/queue/.creds and gitignore it.

Credentials must be rotated; history still contains them. This change
only removes them from the current tree; no history was rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the status:in-progress 🔵 Agent working label Oct 2, 2026
@gHashTag

gHashTag commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

Bee review: head e56321c9dd199c9a9494e9196a226c76cbea8d91

The author is another bee. I checked this in a fresh /tmp clone of the PR head, whose parent is current main cd5e41f. No secret values appear in this comment.

1. Tree-wide scan at the PR head. I checked these patterns:

  • sk- (DeepSeek/OpenAI/Anthropic/OpenRouter)
  • KGAT_
  • Telegram bot tokens
  • ghp_, github_pat_, gho_
  • AKIA
  • gsk_, hf_, xai-, AIza, r8_, xox?-
  • BEGIN … PRIVATE KEY
  • quoted password / api_key / secret / token literals of 12+ characters
  • unquoted *KEY|TOKEN|SECRET|PASSWORD= literals
  • Bearer literals
  • z.ai-shaped hex32.x16 keys
  • Kaggle "key" JSON
  • tracked .creds, .netrc, .env, *.pem and id_rsa files

Result: no live secrets remain. What's left is placeholders or test fixtures only: sk-ant-your-key, sk-ant-test, hf_test, your-key-here, ${VAR} references, the empty KEY_1= / KEY_2= in deploy/trinity-nexus/ralph/queue/.api_keys.conf, and the redaction-test input in src/tri-api/tool_executor.zig. The only tracked .env* files are .env.example files.

2. The diff's added lines. I extracted every literal the diff removes (two Telegram bot tokens, the DeepSeek key, the Kaggle KGAT_ tokens, the z.ai key, and the AMD account password). None of them appears anywhere in the PR-head tree, and the added lines contain only env references, <your-api-key> and comments. The account email removed from the expect script still appears in 13 docs/metadata files. It is a public contact address, not a credential.

3. The scripts still parse.

  • bash -n passes on .trinity/ralph/scripts/report.sh, .trinity/ralph/scripts/test_telegram.sh and fpga/tools/ralph-cron.sh.
  • py_compile: 26 of the 28 changed .py files pass. The two failures were already broken on main, so I confirmed that claim:
    • targets/kaggle/kaggle/create_kaggle_dataset.py has the same SyntaxError on main. It sits at line 29 there and line 28 here, because one line was removed.
    • targets/kaggle/kaggle/create_test_benchmark.py has the same SyntaxError at line 59 on both.
  • Every changed Python file that reads os.environ / os.getenv imports os.
  • fpga/fly-vivado/setup_and_synth.exp checks that AMD_ACCOUNT_EMAIL and AMD_ACCOUNT_PASSWORD exist and are non-empty before spawn, and exits 1 with a clear message otherwise. send "$env(...)\r" substitutes correctly under Tcl double quotes, and the password never goes to puts.
  • .trinity/ralph/queue/.creds is untracked and added to .gitignore.

4. Checks. T27 work report passes, as do Build & Test, GitGuardian, Build Check, VIBEE Codegen and Code Format. Three checks fail, and none is caused by this PR:

  • Documentation Consistency fails on src/hslm/tjepa.zig not found. This PR doesn't touch that file.
  • Brain Health fails with "brain health was NOT MEASURED". The same check fails on main e88f863.
  • pr-opened fails at the project-item lookup, which is board infrastructure.

Non-blocking:

  • ralph-cron.sh now defaults the bot token to empty and doesn't guard send_telegram_photo, so without the variable the curl fails silently. That is harmless.
  • The removed credentials are still in git history. Removing them from the tree doesn't revoke them. The Telegram tokens, the DeepSeek key, the Kaggle tokens, the z.ai key and the AMD account password should all be rotated by the owner.

Verdict: sound. Labelling bee-reviewed and merging with squash, matched to this head.

@gHashTag gHashTag added the bee-reviewed A reviewer bee reviewed and verified this PR after its head commit; required to merge label Oct 2, 2026
@gHashTag
gHashTag merged commit 7511cc7 into main Oct 2, 2026
38 of 47 checks passed
@gHashTag
gHashTag deleted the fix/strip-plaintext-credentials branch October 2, 2026 19:03
@github-actions github-actions Bot added status:completed Done and removed status:in-progress 🔵 Agent working labels Oct 2, 2026
github-actions Bot added a commit that referenced this pull request Oct 2, 2026
fix(security): strip plaintext credentials from the tree (#1258)

Replace hardcoded secrets with environment-variable references:
- AMD/Xilinx account e-mail and password in the Vivado AuthTokenGen
  expect script -> $env(AMD_ACCOUNT_EMAIL) / $env(AMD_ACCOUNT_PASSWORD),
  failing fast when unset.
- DeepSeek API key in four book generator scripts -> os.environ.
- Kaggle API token (24 scripts) and a z.ai-style model proxy key
  (5 scripts) under targets/kaggle -> read from the environment.
- Telegram bot tokens in two ralph scripts and one default in
  ralph-cron.sh -> required env var / empty default.
- A fallback API key in docs/docs/development/ralph.md -> placeholder
  with a note to read it from Railway or Infisical.
- Untrack .trinity/ralph/queue/.creds and gitignore it.

Credentials must be rotated; history still contains them. This change
only removes them from the current tree; no history was rewritten.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bee-reviewed A reviewer bee reviewed and verified this PR after its head commit; required to merge status:completed Done

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant