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

Find the secrets in a repository

Scan quay-api for credentials, then work out why a staging password slipped past .gitignore.

mission

You are
You are the application security engineer at Quayside.
Situation
quay-api is about to be shared with an outside contractor. Before anyone outside the company gets a copy, you check what secrets sit in the code.
Goal
List every credential in the working tree and explain how each one got there.
Hand in
A short list of findings with file, type and who added it.

A secret scanner as a baggage X-ray

01

Look around the repository

learner@dev-lab
ls -a
.
..
.git
.github
.gitignore
.npmrc
README.md
config
docker
package-lock.json
package.json
src
test
tests
git log --oneline | wc -l
10

you should see A Node.js service with config, docker and tests folders and ten commits of history.

02

Run the scanner

Scanners match known key formats and common patterns such as password assignments. They are fast, so run them on every repository you inherit.

learner@dev-lab
scan-secrets .
docker/.env.staging:3  password  PASSWORD=Har****
tests/fixtures/deploy_key:1  private-key  -----BEGIN O****
2 findings

you should see A staging database password and a private key, both committed as ordinary files.

defender tip Real tools such as gitleaks, trufflehog and GitHub secret scanning ship hundreds of rules for cloud, payment and chat tokens. The lab scanner shows the idea with six rules.

03

See who added the password

learner@dev-lab
cat docker/.env.staging
DB_HOST=db.staging.quay.internal
DB_USER=quay_app
DB_PASSWORD=Harbour-Staging-2026!
git log --format='%h %an %ad %s' --date=short -- docker/.env.staging
e70bc03 Ines Rocha 2026-09-18 Add staging config and test fixtures

you should see Ines added a staging config file with a real database password on 18 September.

04

Find out why .gitignore missed it

git check-ignore -v prints the rule that ignores a path, or nothing when no rule matches.

learner@dev-lab
cat .gitignore
node_modules/
.env
git check-ignore -v docker/.env.staging; echo "exit $?"
exit 1

you should see The rule .env matches only a file named exactly .env, so .env.staging was committed.

defender tip Ignore patterns are an easy place for gaps. Use .env* and keep a committed .env.example with placeholder values instead.

What a defender takes away

  1. 1Scan every repository you inherit before you share or publish it.
  2. 2Secrets hide in configs, test fixtures and docker files, not just in code.
  3. 3Check ignore rules with git check-ignore, do not assume them.

Questions

0 of 3 solved

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

  1. Show hint

    Run `scan-secrets .` in ~/repos/quay-api.

  2. Show hint

    Look at the private-key finding.

  3. Show hint

    `git log --format='%an' -- docker/.env.staging`