Lesson  in  DevSecOps in Practice: Container & Kubernetes Security

Secret Scanning with Gitleaks

Commit API keys to a git repo, then "remove" them. Gitleaks finds them anyway — they're still in history. Install a pre-commit hook that blocks secrets before they ever enter the repository, and verify it catches the next attempt.

Git History is Forever

If a secret was committed — even once, even if later "removed" — it is in git history permanently. Anyone who clones the repo can find it.

Create a Repository with Committed Secrets

mkdir -p ~/demo-repo && cd ~/demo-repo
git init
git config user.email "demo@dangote.com"
git config user.name "Demo User"
# Commit 1: config with credentials
cat > config.py << 'EOF'
DATABASE_PASSWORD = "p@ssw0rd!SuperSecret2024"
DATABASE_USER = "admin"
DATABASE_HOST = "postgres.internal.example.com"
EOF

git add config.py
git commit -m "Add database configuration"

# Commit 2: API keys
cat > .env << 'EOF'
STRIPE_SECRET_KEY=sk_test_zQPyAkXOPdh2IEbhCDN0gZhMbJ83XYZABC12345
AWS_SECRET_ACCESS_KEY=P9Tq/ABcDefGHiJkL+MnOpQrStUvWxYzABcDeF12
GITHUB_TOKEN=ghp_ABcDefGHiJkLmNoPqRsTuVwXyZABcDeFgHiJ12
EOF

git add .env
git commit -m "Add API credentials config"

# Commit 3: "Remove" them — but they're still in history!
cat > .env << 'EOF'
STRIPE_SECRET_KEY=
AWS_SECRET_ACCESS_KEY=
GITHUB_TOKEN=
EOF

git add .env
git commit -m "Move secrets to environment variables"

Scan the Full Git History

gitleaks detect --source ~/demo-repo --verbose 2>&1

Expected: 4+ secrets found, including ones in the "cleaned up" commit.

Gitleaks finds secrets across all commits — including the one where we "removed" them.

Install a Pre-commit Hook

Prevention is better than detection. Stop secrets before they enter history.

cd ~/demo-repo

mkdir -p .git/hooks

cat > .git/hooks/pre-commit << 'HOOK'
#!/bin/sh
echo "Running Gitleaks secret scan..."
gitleaks protect --staged --verbose
if [ $? -ne 0 ]; then
    echo ""
    echo "COMMIT BLOCKED: Gitleaks detected secrets in staged changes."
    exit 1
fi
echo "No secrets detected. Commit allowed."
HOOK

chmod +x .git/hooks/pre-commit
echo "Pre-commit hook installed."

Test the Hook

cd ~/demo-repo

cat > new-secret.py << 'EOF'
STRIPE_SECRET_KEY = "sk_test_zQPyAkXOPdh2IEbhCDN0gZhMbJ83XYZABC12345"
EOF

git add new-secret.py
git commit -m "Add payment integration"

Expected:

Running Gitleaks secret scan...
COMMIT BLOCKED: Gitleaks detected secrets in staged changes.

The commit is blocked. Clean up:

git restore --staged new-secret.py
rm new-secret.py

Key Rule

When a secret is found in history:

  1. Revoke it immediately — assume it's already compromised
  2. Rotate it — generate a new credential
  3. Then clean history (git filter-repo) — optional, cosmetic only

The order matters: clean history first and you've just hidden the evidence while the attacker still holds the key.