Join our Newsletter — 33% off our NHI Course

How do security teams know whether force-pushed commits still contain secrets?

They should scan the dangling commit set, not just the current branch history. The practical test is whether the force-push event created unreachable commits that still exist on the server and whether those commits contain secrets. A useful workflow is to identify the force-push boundary, walk the dangling commit chain, and run secret scanning across that retained history.

Why This Matters for Security Teams

A force-push does not guarantee a clean slate. Git may remove commits from the visible branch history, but unreachable objects can still persist on the server until garbage collection, backup retention, or repository mirroring clears them. That means a secret can remain recoverable even after the developer has rewritten history and the branch looks fixed.

This is why teams need to validate the dangling commit set, not just the current tip. The issue is not theoretical: in secrets-heavy environments, leaked credentials can remain valid long after discovery, and GitGuardian & CyberArk report that the average time to remediate a leaked secret is 27 days in The State of Secrets in AppSec. For broader context on how repo exposure spreads through real incidents, see Guide to the Secret Sprawl Challenge and the OWASP Non-Human Identity Top 10.

In practice, many security teams discover the exposure only after a credential has already been abused from an old commit, rather than through intentional post-force-push verification.

How It Works in Practice

The practical workflow starts with the force-push boundary. Teams identify the old commit range, then inspect the unreachable objects that were left behind when the branch pointer moved. A commit can be unreachable from any current branch and still be present in the object database, which is exactly where secret scanning needs to look.

Current guidance suggests combining Git history analysis with repository-level secret detection. The goal is to traverse the dangling commit chain, scan blobs and trees that are no longer referenced, and compare findings against the current branch so analysts can separate genuinely removed content from still-live exposures. This is especially important where the same secret may have been copied across several commits before the rewrite.

  • Identify the force-push event and the pre-rewrite tip.
  • Enumerate dangling commits, not only reachable refs.
  • Scan retained blobs for API keys, tokens, certificates, and other secrets.
  • Confirm whether the secret appears in current history, stale history, or both.
  • Trigger revocation if the secret was ever exposed, even if it is no longer visible.

For incident patterns that show why retained history matters, NHIMG has documented repeated code-and-pipeline exposure in the Reviewdog GitHub Action supply chain attack and the Shai Hulud npm malware campaign. These are useful reminders that secrets often survive in places defenders do not routinely inspect.

These controls tend to break down in large monorepos with heavy rewrite activity because the volume of unreachable objects can outpace scanning and retention windows.

Common Variations and Edge Cases

Tighter history rewrite hygiene often increases operational overhead, requiring organisations to balance developer speed against forensic confidence. There is no universal standard for how long unreachable commits should be retained, so teams need to align scan depth, garbage collection timing, and evidence preservation to their own risk model.

One common edge case is a force-push that removes the branch reference but leaves the secret duplicated in tags, forks, mirrors, or CI clones. Another is when the commit contains a secret that was already rotated, which reduces immediate risk but does not eliminate the need to verify exposure. Best practice is evolving, but current guidance still treats any exposed secret as compromised until validated otherwise.

In higher-risk repositories, teams often pair commit scanning with secret revocation and downstream access review. That matters because a visible fix in Git does not mean the secret stopped being usable elsewhere in the environment. When the repo is mirrored into multiple systems, or when garbage collection is delayed, the dangling set can stay meaningful for much longer than the branch history suggests.

For organisations trying to mature their program, the practical lesson is simple: after a force-push, prove that the old commits are both unreachable and clean, not merely hidden. In mixed human and automated development flows, a rewritten branch can still leave a usable secret behind in replicas, caches, or retained object stores.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10 and CSA MAESTRO address the attack and risk surface, while NIST CSF 2.0, NIST AI RMF and NIST SP 800-63 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP Non-Human Identity Top 10 NHI-03 Covers secret lifecycle and exposure in non-human identities.
NIST CSF 2.0 RS.AN-1 Incident analysis requires confirming whether exposed secrets remain recoverable.
NIST AI RMF GOVERN Governance must define ownership for secret exposure after history rewrites.
CSA MAESTRO G1 Agentic and automated pipelines need controls around credential leakage paths.
NIST SP 800-63 Credential assurance is relevant when secrets in commits remain valid.

Treat Git history scanning as part of the pipeline trust boundary and automate checks.