Unit 1: Secrets in code · Lesson 4 of 4 · 18 min

Stop the next secret at commit time

Install a pre-commit hook that blocks secrets, test it with a fake key and fix the ignore rule that let the password in.

mission

You are
You are the application security engineer at Quayside.
Situation
Cleaning up after leaks is slow and expensive. The team agrees to catch secrets before they ever reach a commit.
Goal
Add a local hook that refuses commits containing secrets, and fix the ignore rule for env files.
Hand in
A working hook and a corrected .gitignore.
01

Write the hook

Git runs .git/hooks/pre-commit before every commit and aborts if it exits with a non-zero status.

learner@dev-lab
printf '#!/bin/sh\nscan-secrets --staged . || { echo "Commit blocked: remove the secret, then commit again."; exit 1; }\n' > .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit && cat .git/hooks/pre-commit
#!/bin/sh
scan-secrets --staged . || { echo "Commit blocked: remove the secret, then commit again."; exit 1; }

you should see A two-line script that scans only the staged changes.

02

Test it with a fake key

learner@dev-lab
echo 'token = "qsk_live_AAAAbbbbCCCCddddEEEEffff"' > config/test-token.js && git add config/test-token.js && git commit -q -m 'Add test token'; echo "exit $?"
config/test-token.js  quay-live-key  qsk_live_AAA****
1 finding
Commit blocked: remove the secret, then commit again.
exit 1

you should see The hook finds the key, prints why and the commit is refused.

defender tip Local hooks are a seatbelt, not a guarantee: they are not cloned with the repository and anyone can skip them with --no-verify. Pair them with server-side push protection that the developer cannot turn off.

03

Clean up the test

learner@dev-lab
git restore --staged config/test-token.js && rm config/test-token.js && git status --short

you should see Nothing staged and no test file left behind.

04

Fix the ignore rule

git rm --cached stops tracking a file without deleting your local copy.

learner@dev-lab
echo 'docker/.env*' >> .gitignore && git rm --cached -q docker/.env.staging && git status --short
 M .gitignore
D  docker/.env.staging
git check-ignore -v docker/.env.staging
.gitignore:3:docker/.env*	docker/.env.staging

you should see docker/.env* now matches the staging file, and git will drop it in the next commit. The password still needs rotating.

Where to catch secrets

Only after the fact
nightly scan of main
  finds the key a day later
  key already pushed, cloned and cached

Every finding becomes an incident.

Layered
pre-commit hook on the laptop
push protection on the server
scan of history on a schedule
secrets manager so code never needs keys

Most secrets never leave the developer's machine.

What a defender takes away

  1. 1Block secrets before commit, and again at push on the server.
  2. 2Hooks can be skipped, so server-side checks are the real control.
  3. 3Untracking a file is not the same as rotating what was in it.

Questions

0 of 3 solved

Answer each one from what you find on your lab machine.

  1. Show hint

    Read the hook output.

  2. Show hint

    The command prints it with `echo "exit $?"`.

  3. Show hint

    `git check-ignore -v docker/.env.staging`