Arezgitfield notes / engineering
SecurityUPDATED JUL 15, 2026

Secret Scanning Before a Git Commit: A Practical Defense

How to prevent credentials from entering Git with staged-content scanning, entropy and format checks, allowlists, secure storage, and an incident response plan.

AREZGIT / FIELD NOTESECURITY
The best time to catch a secret is before Git creates the commit. Repository hosting scans are valuable, but by the time they alert, the credential may already exist in local history, a push
READ / VERIFY / APPLYTECHNICALLY REVIEWED

The best time to catch a secret is before Git creates the commit. Repository hosting scans are valuable, but by the time they alert, the credential may already exist in local history, a pushed object, a fork, a CI log, or a developer's clone.

Pre-commit scanning creates an earlier boundary. It is not sufficient by itself, and it must be designed so developers understand what was found and what to do next.

Define what counts as a secret

Secrets include more than obvious API keys:

  • Private keys and signing keys
  • OAuth client secrets and refresh tokens
  • Personal access tokens
  • Database connection strings
  • Cloud access credentials
  • Webhook signing secrets
  • Session and cookie signing keys
  • Encryption keys
  • License material with privileged use
  • Passwords embedded in URLs or scripts

Public identifiers can look sensitive without granting authority. Stripe price IDs, OAuth client IDs, and Turnstile site keys are often designed to be public. A scanner should classify rather than declare every identifier compromised.

The safe default is to stop the commit when a high-confidence credential appears and show a narrow remediation path.

Scan the staged snapshot

A commit contains the index, not the current working file. Scanning only the filesystem can inspect lines that are not staged and miss a secret staged before it was removed from the working tree.

Use the staged patch or staged blobs as the primary source:

git diff --cached --binary
git diff --cached --name-only --diff-filter=ACMR
git show :path/to/file

Do not pass the entire patch through shell interpolation or temporary files with broad permissions. Stream content directly to the scanner where possible and bound the maximum size.

Handle partial staging explicitly. The developer should be able to see whether the finding exists in the staged version, working version, or both.

Combine high-confidence detectors

No single detector is enough. Use a layered strategy.

Provider and format signatures

Known prefixes, key structures, checksums, and surrounding field names provide high-confidence findings. Examples include PEM private-key blocks and token families with documented formats.

Keep rules versioned and test each with positive and negative fixtures. Do not log the matching value during tests or production scanning.

Context-aware assignment patterns

An assignment to a name containing password, secret, token, or private_key is suspicious. The value, file type, and nearby text determine severity.

Placeholders such as an empty value in env.example should not fail. A long non-placeholder value in a production configuration file should.

Entropy and length

High entropy helps identify random credentials without known formats. It also flags hashes, lockfile integrity values, compressed data, and test fixtures. Use entropy only with context, minimum length, file exclusions, and confidence scoring.

URL credential detection

Detect authority embedded in URLs:

https://user:password@example.com
postgresql://user:password@host/database

Redact the credential before showing the finding. Treat full connection strings as secrets even when the database is local; copied examples have a habit of becoming production configuration.

Exclude noise without creating blind spots

Large generated files, dependency locks, binaries, snapshots, and fixtures can create noise. Exclusions should be narrow and reviewable.

Prefer:

  • Skip binary blobs after content detection.
  • Apply size limits with a visible "not scanned" result.
  • Use file-type-specific detectors.
  • Allow exact fingerprinted findings rather than broad path exclusions.
  • Expire allowlist entries or attach an owner and reason.

Avoid excluding an entire config, tests, or docs directory. Real credentials frequently enter repositories through examples and test data.

An allowlist should store a one-way fingerprint of the finding, not the secret itself. Changes to the value should trigger scanning again.

Protect the scanner itself

A scanner processes the most sensitive content in the repository. Its telemetry, errors, and debugging output need stricter handling than ordinary features.

  • Never send matched content to analytics.
  • Never include full values in logs or crash reports.
  • Redact all but a few non-sensitive identifying characters in UI.
  • Keep scanning local unless the user explicitly selects a remote provider.
  • Do not store scanned source content after the operation.
  • Bound memory use for large blobs.
  • Treat file paths as potentially sensitive metadata.

If an optional AI service explains a finding, send a structured classification without the credential. Most remediation guidance does not require the raw value.

Make remediation part of the result

A useful finding includes:

  • File and staged line
  • Secret category
  • Confidence
  • Redacted fingerprint
  • Why the detector matched
  • Immediate safe action
  • Link to provider revocation guidance when relevant

The primary action should be removing the secret from the staged snapshot and moving it to an appropriate secret store. Unstaging the file alone is not remediation if the secret remains in the working tree.

For application configuration, add the variable name with an empty or safe placeholder to env.example, then store the real value in Fly secrets, a CI secret manager, or the operating-system credential vault depending on its consumer.

Respond correctly when a secret was committed

Assume exposure and rotate first. Removing the line or rewriting Git history does not invalidate copies.

  1. Revoke or rotate the credential with the provider.
  2. Identify its permissions and accessible systems.
  3. Review provider and application logs for misuse.
  4. Replace the credential in legitimate deployments.
  5. Remove the value from current files.
  6. Decide whether history rewriting is necessary.
  7. Coordinate rewritten history with every clone and protected branch.
  8. Document the incident and prevention change.

Do not paste the credential into chat, an issue, or an incident document. Refer to a fingerprint and provider record.

If the leaked value is a signing or encryption key, the response may require re-signing artifacts, rotating verification keys, or re-encrypting protected data. Plan rotation before an incident.

Use multiple enforcement layers

A mature defense includes:

  • Editor or workspace feedback before staging
  • Staged-content scanning before commit
  • CI scanning of the full branch range
  • Hosted repository scanning after push
  • Provider-side leak detection and revocation
  • Least-privilege, short-lived credentials
  • Periodic history and artifact scanning

Local enforcement gives fast feedback. Server enforcement prevents bypass from becoming the only protection. Provider controls reduce the value and lifetime of anything that still leaks.

Secret scanning succeeds when it is accurate enough to remain enabled, private enough to trust, and actionable enough to change behavior. Catch the staged value, protect the finding, rotate on exposure, and design credentials so one mistake has a bounded impact.