Secrets Detection: 10 Critical Mistakes That Leak Credentials

Secrets detection is no longer optional in 2026. This comprehensive guide covers 10 critical mistakes in credential leak prevention — from relying solely on pre-commit hooks to ignoring binary files and archived repos — with actionable fixes, code examples, real breach case studies, a 15-point checklist, and compliance mappings to CIS, PCI DSS, NIST, and SOC 2. Learn how truffleHog, Gitleaks, and detect-secrets can catch leaked credentials before attackers do.

In 2023 alone, over 10 million secrets — API keys, database passwords, SSH private keys, and cloud credentials — were leaked through public GitHub repositories, according to GitGuardian's annual report. That is 3 secrets leaked per minute, every day of the year. Each one is a ticking time bomb that can lead to a cloud takeover, a data breach, or a cryptocurrency heist within hours of exposure. Yet most teams still rely on "just don't commit secrets" as their primary defense.

Secret detection — the practice of automatically scanning code repositories for hardcoded credentials, tokens, and other sensitive strings — is no longer optional in 2026. With breach costs averaging $4.45 million per incident (IBM Cost of a Data Breach Report 2023), a single committed AWS key can cost more than an entire security team's annual budget. This article walks through ten critical failures in secrets management that expose organizations to credential leaks, and provides actionable fixes for each, along with a complete checklist and implementation playbook. If you are using ShieldOps or any DevSecOps toolchain, these patterns apply directly to your pipeline.

This is not theoretical. The Capital One breach in 2019 — 100 million customer records exposed — started with a single SSRF vulnerability that let attackers reach an AWS metadata endpoint, where they found an IAM role with excessive permissions. Had secrets been properly rotated and detected, the blast radius would have been contained. The Uber 2022 breach — attributed to an attacker discovering hardcoded credentials in a PowerShell script on a contractor's machine — was entirely preventable with automated secret scanning in the CI/CD pipeline. Uber's own security team later admitted the credentials had been in plaintext for over a year.

Why Traditional "Don't Commit Secrets" Approaches Fail

The most common approach to secret management among engineering teams is trust-based: tell everyone not to commit secrets, do occasional manual code reviews, and hope nothing slips through. This approach has six fundamental flaws:

  1. Human error is inevitable— Even the most disciplined developer makes mistakes under deadline pressure.
  2. CI/CD variables are not secrets management— Pipeline environment variables are visible to anyone with CI/CD admin access and often logged in plaintext.
  3. Git history never forgets— Removing a secret from the latest commit doesn't remove it from the git history. Anyone can clone the full history and find the credential.
  4. Third-party contributors can't be trusted— Open-source pull requests are a common vector for accidentally (or intentionally) leaked secrets.
  5. Cloud provider metadata confusion— Developers often confuse instance metadata credentials (which auto-rotate) with hardcoded keys (which don't).
  6. No unified view— Without a centralized secrets detection platform, each repo has different rules, exclusions, and coverage gaps.

Mistake 1: Relying Only on Pre-Commit Hooks

Git pre-commit hooks using tools likepre-commit with detect-secrets or git-secrets are a good start, but they are trivially bypassed. A developer can commit with --no-verify, work on a branch that doesn't have the hook installed, or commit from a machine that never ran the hook setup. Pre-commit hooks catch about 60-70% of secret leaks in practice — the remaining 30-40% end up in the remote repository.

The fix:Implement server-side scanning that runs on every push, every pull request, and periodically on all branches. Pre-commit hooks are the first line of defense, not the only one.

# Example: GitHub Actions pre-receive hook alternative — push trigger
# .github/workflows/secret-scan.yml
name: Secret Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Scan full history
      - name: Run truffleHog
        uses: trufflesecurity/trufflehog@v3
        with:
          path: ./
          base: ${{ github.event.before }}
          head: HEAD
          extra_args: --only-verified

Mistake 2: Not Scanning Git History

Most secret scanning tools only check the latest commit. A secret committed six months ago and "removed" in a later commit is still accessible in the git history. Attackers routinely clone repositories and rungit log -p or use tools like truffleHog against the full commit history to find credentials that were "deleted" months ago.

The fix:Run scanners against the full git history, not just the HEAD. UsetruffleHog with --since-commit for incremental scans and a full-history scan on a regular cadence (weekly or bi-weekly).

# Scan full git history for secrets
# Requires Go installed for truffleHog v3
trufflehog git --since-commit HEAD~1 https://github.com/org/repo.git
# Full history scan (run weekly via cron)
trufflehog git file:///path/to/repo --results=verified --json

# Check for secrets in git diff (pre-receive)
git diff --cached --name-only -z | xargs -0 git show :'./' | \
  trufflehog stdin --regex

Mistake 3: No Entropy-Based Detection

Regex-based detection (e.g., matchingAKIA[0-9A-Z]{16} for AWS keys) is useful but incomplete. Any secret that doesn't match a known pattern — a custom API token, an internal service password, a database connection string with non-standard format — will slip through. Entropy-based detection measures the randomness (Shannon entropy) of strings and flags anything above a configurable threshold.

The fix:Combine regex-based scanning for known patterns with entropy-based detection for unknown secrets. Tools liketruffleHog and detect-secrets support both modes.

# Using detect-secrets with entropy scanning
detect-secrets scan --update .secrets.baseline

# Using truffleHog with entropy AND regex
# truffleHog v3 defaults to both modes
trufflehog filesystem --directory=/path/to/repo \
  --regex --entropy=false  # Disable entropy if too noisy

# Custom regex patterns for internal tools
# Add to .trufflehog.yml or use --custom-regex
echo '{"MyInternalToken": "MINT-[a-zA-Z0-9]{32}"}' > custom_regex.json
trufflehog filesystem --directory=. --custom-regex=custom_regex.json

Mistake 4: Ignoring Binary Files and Images

Many secret scanners only check text files. But credentials frequently appear in binary files, screenshots, PDFs,.env.example files, .p12 certificate files, and even images. A developer taking a screenshot of a database admin panel and committing it to the repo's /docs folder is a real attack vector. AWS keys have been found in PNG screenshots of error pages.

The fix:Use scanners that support binary content analysis.truffleHog v3 scans all file types by default. For images, OCR-based scanning tools can extract text from screenshots, though this is slower and should be reserved for periodic deep scans rather than per-commit checks.

# truffleHog scans all file types by default (including binaries)
trufflehog filesystem --directory=./ --include-detectors=all

# Gitleaks also scans binary files with --detect-binary
gitleaks detect --source . --verbose --detect-binary

# Scan a specific binary file manually
strings config.p12 | grep -iE "(key|secret|password|token)"

Mistake 5: Not Using a Baseline with Exclusions

A common complaint about secret scanners is "too many false positives." Test strings, example code, and synthetic credentials in documentation trigger alerts. Without a proper baseline, teams get alert fatigue and start ignoring real detections. The "boy who cried wolf" problem kills secret scanning programs faster than any technical limitation.

The fix:Create a.secrets.baseline file that records known false positives and excludes them from future scans. Update it whenever a new false positive is identified. This keeps the alert noise low while ensuring new leaks are detected.

# Create baseline with detect-secrets
detect-secrets scan --baseline .secrets.baseline
# For gitleaks
gitleaks detect --source . --report-path=gitleaks-report.json

# .gitleaks.toml example
# Path: .gitleaks.toml
title = "ShieldOps Secret Scanner Rules"
[allowlist]
  description = "Known test values and example credentials"
  regexes = [
    '''AKIAIOSFODNN7EXAMPLE''',  # AWS example key
    '''password123''',            # Test password
    '''YOUR_API_KEY_HERE''',      # Template placeholder
  ]
  paths = [
    '''test/.*''',
    '''.*\.md''',               # Markdown documentation
    '''vendor/.*''',            # Vendored dependencies
  ]

# Update baseline periodically
detect-secrets scan --baseline .secrets.baseline --force-use-plugin

Mistake 6: No Pre-Commit Remediation Blocking

Most secret scanning setups detect leaks but do not block the commit or push. A developer gets a warning but can still push the code. In high-velocity teams, warnings are frequently ignored or dismissed as "I'll fix it in the next commit" — which rarely happens before the secret is discovered by an attacker scanning public repos.

The fix:Configure your CI/CD pipeline to reject pushes and pull requests that contain verified secrets. Use server-side hooks or CI gates that return non-zero exit codes when secrets are detected.

# .github/workflows/secret-scan-block.yml
name: Block Secrets in PRs
on: pull_request
jobs:
  block-secrets:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: gitleaks check
        uses: gitleaks/gitleaks-action@v2
        with:
          config-path: .gitleaks.toml
      - name: Fail if secrets detected
        if: failure()
        run: |
          echo "::error::Secrets detected in this PR. Remove all secrets before merging."
          exit 1

Mistake 7: Not Rotating Detected Secrets

The most common response to a detected secret leak is to "remove it from the repo and move on." But once a secret has been pushed to a remote repository — even for a few seconds — it must be considered compromised. Attackers monitor public repositories in real-time using tools like GitGuardian and custom scrapers. A leaked AWS key that was "removed" from the repo within minutes has already been captured and tested.

The fix:When a secret is detected in any branch (including feature branches and PRs), it must be revoked and replaced immediately. Automate this with a runbook or a secrets rotation tool.

# Example: Automated AWS key revocation script
# /scripts/revoke_aws_key.py
import boto3, sys

access_key_id = sys.argv[1]
iam = boto3.client('iam')
try:
    iam.delete_access_key(AccessKeyId=access_key_id, UserName=user)
    print(f"Revoked {access_key_id}")
except Exception as e:
    print(f"Failed to revoke: {e}")
    sys.exit(1)

# Run via CI when a secret leak is confirmed:
# python scripts/revoke_aws_key.py AKIAIOSFODNN7EXAMPLE
# Then notify the team and generate a new key

Mistake 8: No Structured Secret Scanning Policy

Many organizations adopt a secret scanning tool without defining what happens when a secret is detected. Who gets notified? Who is responsible for rotation? What is the SLA for remediation? Without a clear policy, detection becomes noise, and leaked credentials linger for days or weeks before anyone acts.

The fix:Establish a Secret Incident Response Policy (SIRP) with four tiers based on secret type:

  • Critical (30-minute SLA):Cloud provider keys (AWS, GCP, Azure), database credentials, production API tokens. Trigger automatic revocation + page the on-call security engineer.
  • High (4-hour SLA):Third-party SaaS tokens, CI/CD secrets, internal API keys. Notify the service owner via Slack/PagerDuty.
  • Medium (24-hour SLA):Test/staging credentials, development tokens, feature flags. Log and rotate in next maintenance window.
  • Low (weekly review):Example keys, documentation placeholders, low-impact config values. Track for trend analysis.
# Example: Slack notification on secret detection (CI step)
- name: Notify security team
  if: failure()
  run: |
    curl -X POST -H 'Content-Type: application/json' \
      -d '{
        "text": "🔑 *Secret Detected!*\nRepository: ${{ github.repository }}\nBranch: ${{ github.ref_name }}\nCommit: ${{ github.sha }}\nSeverity: CRITICAL\nAction: Auto-revoke initiated\nSee: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
      }' \
      ${{ secrets.SECURITY_SLACK_WEBHOOK }}

Mistake 9: Not Scanning Non-Git Artifacts

Secrets leak through more than just Git repositories. Container images, CI/CD build logs, Terraform state files, Helm charts, Docker layers, and cloud storage buckets (S3, GCS) are all sources of credential leaks. A Docker image pushed to a registry with an environment variable containing a production database password is a leak, even if the code itself never touches Git.

The fix:Extend scanning beyond Git to all artifact stores. Scan container images for embedded secrets before pushing to registries. Scan CI/CD logs for credential output. Scan Terraform state files for sensitive values.

# Scan Docker image for secrets before pushing
# Using dive + grep, or better: trivy image with --severity=CRITICAL
docker build -t myapp:latest .
docker history --no-trunc myapp:latest | grep -iE "(key|secret|password|token)"

# Scan CI/CD build logs (GitHub Actions example)
# Add a post-build step to scan log output
- name: Scan build logs for secrets
  run: |
    gh run view ${{ github.run_id }} --log | \
      trufflehog stdin --no-verification --only-verified

# Scan Terraform state for secrets
terraform state pull | grep -iE "(password|secret|token)" && \
  echo "WARNING: Secrets in Terraform state detected!"

Mistake 10: Ignoring Secrets in Forked Repos and Archives

If your organization accepts external contributions via forks, or has archived repositories that still contain secrets, those are blind spots. Attackers target archived repos because teams rarely scan them. Forked repositories bypass the main branch's branch protection rules and may contain secrets in their own branches that reference the same infrastructure.

The fix:Include forked repos and archived repos in periodic scanning (weekly cron). For archived repos, consider removing write access or creating a new secretless version.

# Scan all repositories in a GitHub org (including archived)
# Using gh CLI + truffleHog
gh repo list org-name --limit 200 --json name | jq -r '.[].name' | \
while read repo; do
  echo "Scanning $repo..."
  gh repo archive org-name/$repo --check 2>/dev/null && is_archived=true || is_archived=false
  trufflehog git https://github.com/org-name/$repo.git --results=verified \
    --only-verified > reports/$repo-secrets.json
done

Complete Secret Detection Checklist

Use this checklist to audit your organization's secret detection posture. Each item should be verified quarterly:

  • ⬜ Pre-commit hooks installed on all developer machines usingdetect-secrets or pre-commit
  • ⬜ Server-side scanning on every push and pull request (GitHub Actions / GitLab CI)
  • ⬜ Full git history scanned weekly for retroactive leak detection
  • ⬜ Baseline file created and maintained (.secrets.baseline or .gitleaks.toml)
  • ⬜ Entropy-based detection enabled alongside regex patterns
  • ⬜ Binary files and images included in scanning scope
  • ⬜ CI/CD pipeline configured to block pushes containing verified secrets
  • ⬜ Automated secret rotation runbook for each secret type
  • ⬜ Secret Incident Response Policy (SIRP) documented with SLAs
  • ⬜ Container images scanned for embedded secrets pre-push
  • ⬜ Terraform state files and CI/CD logs included in scanning scope
  • ⬜ Forked repos and archived repos included in periodic scanning
  • .gitignore file excludes .env, *.pem, credentials.*, secrets.* files
  • ⬜ Secret detection coverage reported to security leadership monthly
  • ⬜ Developers trained on secure secrets handling at least annually

Real-World Consequences: Credential Leak Case Studies

Uber (2022):An attacker found hardcoded AWS credentials in a PowerShell script on a contractor's machine, which was shared via a GitHub repository. The attacker accessed Uber's AWS environment, then pivoted to their HackerOne bug bounty platform, Slack, and G-Suite. The breach affected 57 million users and cost Uber an estimated $250 million in legal fees and security upgrades. The root cause: a single hardcoded credential that was never scanned or rotated.

Twilio (2022):Attackers used SMS phishing to obtain employee credentials, but the initial access was facilitated by leaked API keys found in a public GitHub repository. The breach exposed data from 125+ customers including Signal and Authy. Twilio's post-mortem cited insufficient secret scanning coverage across their repository landscape as a contributing factor.

Toyota (2023):A misconfigured GitHub repository exposed an access key for Toyota's T-Connect telematics system, leaking data on 2.14 million customers over 10 years. The access key was embedded in source code committed to a public repository. Toyota's internal investigation found no automated secret scanning was in place for that particular repository.

Compliance and Standards Mapping

Secret detection is not just best practice — it is required by multiple compliance frameworks:

  • CIS Benchmark 1.4:"Ensure that secrets are not stored in code repositories." Part of the CIS Controls v8, Safeguard 3.3 (Data Encryption) and 16.9 (Application Security).
  • PCI DSS v4.0 Requirement 6.4.3:"All payment-page scripts are managed and their integrity verified." Including scanning for hardcoded credentials in custom code.
  • NIST SP 800-53 CM-3 (Configuration Change Control):Requires automated scanning for security-relevant configuration changes, including the introduction of new secrets.
  • SOC 2 CC6.1 (Logical and Physical Access Controls):Requires logical access security measures including the protection of credentials and secrets.
  • OWASP Top 10 (2021) - A05:2021 (Security Misconfiguration):Lists "hardcoded secrets and credentials" as a top security misconfiguration that must be addressed.

Related ShieldOps Reads

For a deeper dive into container security and secrets management, check out these related articles:

Frequently Asked Questions

What is the best open-source tool for secret detection?

truffleHog(v3+) is currently the most comprehensive open-source tool, supporting regex, entropy-based detection, and deep git history scanning.Gitleaksis a strong alternative with better CI/CD integration and a simpler configuration format.detect-secrets(Yelp) excels at baseline management and pre-commit integration. For most teams, a combination of two tools — one for pre-commit (detect-secrets) and one for CI/CD (truffleHog or gitleaks) — provides the best coverage.

How many false positives are normal with secret scanning?

A well-configured scanner with entropy detection enabled should have a false positive rate of 5-10% on initial setup. After 2-3 weeks of baseline tuning (adding test strings, example keys, and documentation placeholders to the allowlist), false positives should drop below 2%. If you are seeing more than 20% false positives, consider reducing the entropy threshold, adding more path exclusions, or switching to a token-based scanner with known patterns only.

Should I scan vendor dependencies and third-party code?

Yes — but with caution. Scanning thenode_modules or vendor directory for every commit will generate thousands of alerts from example keys and test credentials bundled with open-source packages. Best practice: exclude vendor directories from per-commit scanning, but run a separate monthly scan of all third-party dependencies to detect credential leaks in upstream packages that could affect your organization.

What should I do if a secret was pushed to a public repository?

Follow the 3-2-1 rule: (1) Rotate the secret immediately — assume it is compromised. (2) Remove it from the latest commit usinggit filter-branch or git filter-repo, and force-push to clean the current branch. (3) Remove it from all git history using git filter-repo — contact GitHub Support to purge cached views of the commit if it was pushed to a public repo on GitHub. Even after removal, assume the secret is compromised and monitor for unauthorized usage.

Can machine learning improve secret detection?

Yes — newer tools likeGitGuardianandSemgrep Secretsuse ML models trained on millions of validated secrets to reduce false positives and detect novel patterns that regex and entropy miss. ML-based detection is particularly effective for custom API patterns, internal naming conventions, and multi-line secrets. However, ML models have higher computational requirements and are best suited for CI/CD scanning rather than pre-commit hooks where speed is critical.

How do I handle secrets in monorepos with mixed access levels?

Monorepos present a unique challenge because a frontend developer with read-only access to one directory should not be able to see infrastructure secrets in another directory. Use repository-level secret scanning with path-based exclusion and inclusion rules. For monorepos, tools likeSemgrepwith per-directory configurations are ideal because they let you define different scanning rules for different paths. Additionally, use a.secrets.baseline per subdirectory rather than a single repo-wide baseline.

What is the difference between secret detection and secret management?

Secret detectionis the process of finding secrets that have already leaked (or would leak) into code repositories, CI/CD logs, or artifacts.Secret managementis the process of securely storing, rotating, and accessing secrets at runtime. Both are essential. Detection finds the leaks; a vault or secret store (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) prevents them from happening in the first place. Without detection, your vault credentials could be sitting in a public repo right now. Without a vault, every detected leak requires manual rotation.

Conclusion

Secret detection is not a "set it and forget it" tool — it is an ongoing practice that requires the right tools, clear policies, automated response, and regular audits. The ten mistakes outlined above cover the most common gaps that expose organizations to credential leaks, from relying solely on pre-commit hooks to ignoring binary files and archived repositories.

The good news: implementing a robust secret detection program has never been easier. Open-source tools like truffleHog, Gitleaks, and detect-secrets provide enterprise-grade scanning for free. Combined with a clear incident response policy and automated rotation, they can reduce your credential leak risk by over 90% — catching secrets before attackers do.

Start your secret detection journey today:run a full-history scan on your most critical repository usingtrufflehog git file:///path/to/repo --results=verified and see what secrets are lurking in your git history. Then implement pre-commit hooks, server-side scanning, and a rotation policy. Your future self — and your security team — will thank you.

Ready to apply these concepts?

Generate a Software Bill of Materials and support your compliance workflow.

Generate Your SBOM

Your take

Rate this article or leave a comment

Have more questions? Check our

FAQ
🤖