Skip to content

new(security): check-staged-secrets.sh, an opt-in staged-blob secret check (TK-025) - #411

Merged
MendixMau merged 10 commits into
masterfrom
night/fix-tk-025
Oct 16, 2026
Merged

MendixMau merged 10 commits into
masterfrom
night/fix-tk-025

Conversation

@MendixMau

@MendixMau MendixMau commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Direct lane

What changed and why: a field run (five apps, mxcli v0.26.0) had six secret leak events into agent transcripts and one demo password reach git: .mxcli/run-local.json holds database and API passwords in clear under bootConfig, and a rendered login page with the password filled in was tracked. .gitignore does not help once a file is tracked, and git commit -- <path> re-adds an ignored tracked file at commit time. New project-bin/check-staged-secrets.sh compares the project's real secret values (.env, .env.*, run-local.json bootConfig, optional $MXTK_SECRET_VALUES_FILE) against the staged blobs, or with --tree every tracked file at HEAD, and prints only the file and the key name, never a value. Not treated as secrets: values under 8 characters, well-known dev defaults (mendix, password, admin, ...; mendix is the mxcli database password and sits in thousands of tracked files, so counting it would fail every commit), and a value equal to the same key in .env.example. .docker/.env (the mxcli docker layout) is read too. CRLF, KEY = value and inline comments are normalised. Scanning is one git grep -F -f per value, with the value passed through a mode 600 file, not argv. A new section in skills/learned-constants-and-secrets.md lists the files and commands an agent never prints. It is opt-in and not wired into the generated pre-commit hook; a separate warn-only wiring PR comes later. Finding TK-025, no GitHub issue.

Impact

Row Answer
Process none: opt-in, not on any gate, not in the pre-commit hook; nothing new blocks
Dependencies new project-bin/check-staged-secrets.sh (named in MXTK_PROJECT_BIN in bin/lib/install-manifest.sh), skills/learned-constants-and-secrets.md, its test, CHANGELOG.md. Reads .env* and .mxcli/run-local.json if present; plain bash and git, any OS. No overlap with _common.sh or exec.sh.
Context cost none: learned-constants-and-secrets is ondemand in bin/lib/skill-routing.tsv, no always-loaded file touched. bin/render-routing.sh --check: baseline 75225 words (budget 80000), same on origin/master and on this head.
Behaviour NOT RUN: situational skill text (A/B recommended, not required); the script itself is covered by the test below
Runtime n/a: not on any gate. Measured on a synthetic 6,000-file repo, 5 values: 230 staged files 1.0 s, whole tree (--tree) 2.6 s (was 41 s to 3 min 16 s for 231 files)

Field evidence: the leak events come from the lab report; the script was not run against that lab's real values. The test uses made-up values only and proves the mechanism, not a real leak.

  • No client data anywhere in the diff (test values are invented strings)
  • Size cap respected (5 files, 198 insertions, 1 deletion)
  • Test tier: T1. bash tests/wave2/test-check-staged-secrets.sh gives 30 passed, 0 failed on this head, including the default mendix password (exit 0), .docker/.env, a CRLF file, spaced and commented values, an .env.example-equal value, and MicroflowConstants values: a placeholder default already in the committed model is skipped (exit 0, staged and --tree), a constant value not in the model is still found. On master the subject script does not exist, so the test cannot run there (the whole check is absent).
  • bin/check-pr-discipline.sh origin/master clean
  • CHANGELOG line added under ## Unreleased

🤖 Generated with Claude Code

MendixMau and others added 6 commits October 15, 2026 22:41
…tion (TK-025)

Situational skills only; sources and field evidence in CHANGELOG. Verified claims are
marked as field observations where mxcli/Mendix docs did not confirm them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	CHANGELOG.md
….docker/.env, CRLF (TK-025 review)

Skip values under 8 chars, well-known defaults (mendix etc.) and values equal
to .env.example. One git grep -F -f per value (value via 600 file, not argv).
Read .docker/.env and similar. Normalise CRLF, spaces and inline comments.
Tests for each. Skill text states what the check does not protect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… model

run --local writes every constant's model default into bootConfig, so a
placeholder default of a key-like constant counted as a secret and could
not be unstaged. Values present at HEAD in *.mpr or mprcontents/ are skipped;
a constant passed with a value not in the model is still found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MendixMau
MendixMau marked this pull request as ready for review October 16, 2026 03:52
MendixMau and others added 4 commits October 16, 2026 16:00
Keep both manifest entries and both changelog entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…are name

Same non-fatal probe exec.sh uses; a local fallback when _common.sh is absent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MendixMau
MendixMau merged commit ea2dd17 into master Oct 16, 2026
2 checks passed
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