Chapter 21Lesson 01~125 minutes

Signing, Trust, Secret Removal, fsck, Safe Directories, and Repository Integrity: Concepts, Architecture, and Mental Model

Separate Git object integrity, signer authenticity, authorization, credential secrecy, repository ownership trust, fsck evidence, and sensitive-history remediation into a precise production security model.

IntegritySigning trustSecret responsefsck

Learning objectives

  • Distinguish object integrity, signer authenticity, authorization, credential secrecy, and repository trust.
  • Explain OpenPGP, X.509, and SSH signing formats and the identity-policy layer above cryptographic verification.
  • Treat exposed credentials as revocation/rotation incidents before Git history cleanup.
  • Explain safe.directory as a narrow protected-configuration ownership exception.
  • Use fsck as object/connectivity evidence without treating it as malware, secret, or authorization proof.

1. Source-control security has several different questions

A repository can be internally consistent and still be unsafe. A commit hash can prove that an object has not changed since its object ID was calculated, yet it does not prove who created it, whether that person was authorized to publish it, whether the content contains a credential, or whether the repository itself is trusted to execute local configuration and hooks.

Chapter 20 treated merge correctness as more than marker removal. Chapter 21 applies the same discipline to security: integrity, authenticity, authorization, credential secrecy, and repository trust are related controls, but they are not synonyms.

2. Start with read-only evidence

git --version
git status --short --branch
git log --graph --decorate --oneline --all --max-count=30
git log -1 --show-signature
git config --list --show-origin --show-scope
git config --show-origin --get-all safe.directory
git fsck --no-progress

A missing safe.directory output is not an error; it can mean no explicit exceptions are configured. Likewise, an unsigned commit is not automatically malicious. The point is to establish what Git can actually prove before drawing a security conclusion.

3. Integrity, authenticity, authorization, and secrecy answer different questions

Question Git/security concept What it does not prove
Did this object change? Content-addressed object integrity Who approved it
Did this signing key sign this payload? Cryptographic signature verification That the key belongs to an authorized person
May this actor update protected source? Server/filesystem/hosting authorization policy That committed content is secret-free
Is a token/password still usable by an attacker? Credential lifecycle: revoke/rotate That old repository copies no longer contain it
Should Git trust this repository ownership/config context? Ownership and safe.directory protections That the repository is malware-free

4. Git object IDs are integrity identifiers, not author identities

Blobs, trees, commits, and annotated tags are content-addressed. A commit object includes its tree, parents, author/committer metadata, and message, so changing any of those fields creates a different commit ID. That property makes accidental or malicious object mutation detectable, but an attacker who can create new objects can also create perfectly valid hashes.

5. Signed commits and tags add a cryptographic statement

Git can embed cryptographic signatures in commit and tag objects. The signing backend is selected by gpg.format. Current Git supports OpenPGP, X.509, and SSH formats. The historical configuration prefix and command wording still use “gpg” in many places even when the selected format is SSH or X.509.

From object integrity to policy trust
flowchart TD
O[Commit or tag payload] --> H[Git object ID]
O --> S[Cryptographic signature]
S --> K[Public-key verification]
K --> I[Identity / key trust mapping]
I --> P[Organization authorization policy]
H --> V[Object integrity check]

The object ID checks the stored object; the signature checks possession of a signing key; the identity/trust mapping connects the key to a principal; and organization policy decides whether that principal was authorized for this action.

6. OpenPGP verification needs both cryptographic validity and trust interpretation

git verify-commit and git verify-tag invoke the configured signing backend. A “good signature” means the signature mathematically matches the payload and key. It does not by itself establish that the signer is the release manager your organization intended to authorize.

7. SSH signing uses an allowed-signers trust mapping

With gpg.format=ssh, Git uses SSH signature tooling. Current configuration supports gpg.ssh.allowedSignersFile, which maps principals to trusted public keys. Without an appropriate trust mapping, a mathematically valid SSH signature is not automatically equivalent to an organization-approved identity.

8. X.509 signing relies on certificate trust infrastructure

With gpg.format=x509, Git uses the X.509 signing backend and a configured program such as gpgsm. Certificate-chain validity and organizational authorization still need a policy. Git does not turn a certificate into deployment approval merely because the cryptographic check succeeds.

9. Git signatures are not branch protection

Core Git can sign and verify objects, but server-side rules such as protected branches, required review, merge queues, and organization permissions are hosting or server controls. A signed commit can still be rejected by policy, and an unsigned commit can still exist locally. Keep the Git cryptographic mechanism separate from the authorization layer that decides what may be published.

10. A leaked credential is an incident even if Git history is later rewritten

A token, password, private key, or other credential committed into Git may already have been copied to clones, caches, logs, forks, build artifacts, or mirrors. The primary containment action is to revoke or rotate the real credential. History rewriting is a secondary containment/cleanup step that reduces future exposure; it cannot retroactively make a previously usable credential safe.

11. Training uses fake markers, never real credentials

FAKE_TOKEN_DO_NOT_USE_2026

This course uses an intentionally non-sensitive marker. Never substitute a real token, private key, authorization header, credential-helper output, or password in a training repository, screenshot, terminal transcript, or support ticket.

12. Removing a secret from the working tree does not remove it from history

git log -S'FAKE_TOKEN_DO_NOT_USE_2026' --all -p
git grep 'FAKE_TOKEN_DO_NOT_USE_2026' $(git rev-list --all)

A later commit that deletes the string only makes the current snapshot clean. Older reachable commits still retain the blob unless history is rewritten or the containing refs are removed and old data eventually ages out of every relevant copy.

13. Secret removal changes commit identities

When a historical blob is changed, its blob ID changes, its containing tree changes, the commit containing that tree changes, and every descendant commit whose parent chain includes that commit also changes. Rewriting therefore coordinates a new history, not an in-place edit of old immutable objects.

Production consequence: collaborators, automation, tags, caches, forks, mirrors, and hosted refs can still retain old history. Rewrite planning must include every relevant copy and a freeze/coordination window.

14. Rewriting signed history invalidates the old signature relationship

A signature covers a specific commit or tag payload. If the payload or parent chain changes, the original signature cannot remain a valid signature of the rewritten object. Current git filter-repo documentation notes that rewritten commit signatures are stripped and signed tags become unsigned annotated tags. After cleanup, establish new attestations according to policy rather than pretending old signatures survived unchanged.

15. safe.directory is an ownership trust exception

Git normally refuses to operate on a repository owned by a different user in security-sensitive circumstances. safe.directory lets protected configuration declare specific repositories trusted despite ownership differences. Because an untrusted repository must not be able to whitelist itself, this setting is respected only in protected configuration scopes.

16. Do not disable repository-ownership protection globally

Current Git supports safe.directory=* as a complete opt-out. This course does not use it as a fix. If ownership is legitimate, prefer correcting filesystem ownership/permissions or adding one exact, reviewed path in protected configuration. Broad wildcards turn a diagnostic warning into a weakened trust boundary.

17. git fsck checks repository object validity and connectivity

git fsck verifies object database consistency, references, and reachability according to its mode. It can report missing, malformed, dangling, and unreachable objects. That makes it useful for integrity diagnostics, but it is not a malware scanner, secret scanner, signer-authorization system, or proof that every repository action was legitimate.

18. Dangling and unreachable objects are evidence, not automatic trash

Rebases, aborted work, temporary objects, and ref movement can leave objects outside current reachable history. Current Git documentation explicitly describes dangling objects as common and not inherently problematic. During an incident, preserve them until you understand whether they contain recoverable work or forensic evidence.

19. DevOps connection — source control is part of the software supply chain

A production operating model needs separate controls for object integrity, signer identity, repository authorization, credential rotation, ownership trust, server-side object validation, and incident evidence retention. Collapsing them into one “Git is secure” claim creates blind spots at exactly the moments when CI/CD and release provenance matter most.

20. Knowledge check

Question 1. Does a valid Git object hash prove who authored or approved the object?

Question 2. Does a mathematically valid signature automatically prove organizational authorization?

Question 3. What is the first security action after a real credential is exposed in Git?

Question 4. Why is safe.directory=* not the default remediation?

Question 5. What can a clean fsck result not prove?

21. Summary

Git integrity, cryptographic authenticity, authorization, secret lifecycle, repository ownership trust, and fsck diagnostics are separate layers. Secure operations preserve that separation so each control answers the question it was designed to answer.

Next

Build a disposable signing and incident-response laboratory

Lesson 2 creates signed and unsigned objects with a local free backend when available, detects a fake leaked marker in history, preserves evidence, examines fsck output, and prepares a filter-repo remediation path.

Authoritative references

 Git signature formats
 git-config signing and safe.directory
 git-fsck
 filter-branch warning and filter-repo recommendation

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.