linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Chapters
  • How it works
  • Lessons
  • Knowledge base
  • Interview prep
Cluster

← все кластеры

Security and secrets

GPG/SSH signing, secret scanning, ssh keys, gitignore and why it does not fix a secret that already leaked. This block comes up often on DevOps/SRE/Platform interviews, where Git is part of the supply chain.

5 вопросов · ~25 мин чтения

Questions

На этой странице

  1. 01Why sign commits with GPG or SSH? What does the verified badge give you?
  2. 02How does secret scanning differ from .gitignore? Why does .gitignore not protect you?
  3. 03I ran `git rm --cached secret.env` and committed. Is the secret gone from history?
  4. 04A leaked SSH key for Git: how do you revoke it and how do you avoid a replay?
  5. 05A file is already tracked in Git. I added it to `.gitignore` and it did not help. Why, and what is the right way?

#git-signed-commits-why

intermediateиногда

Why sign commits with GPG or SSH? What does the verified badge give you?

Что отвечать

Provenance: a signature proves the commit was created by the key owner, not by someone who put your name in `user.name`/`user.email` (Git never checks those fields). Without a signature it is trivial to commit under another person's name: `git -c user.name='Linus Torvalds' -c user.email='torvalds@...' commit`. A GPG/SSH signature plus publishing the key on GitHub gives you the Verified badge in the UI and verification through `git verify-commit`. This protects against impersonation and supply-chain attacks.

Что хотят услышать

A senior should: - name the concrete risk of going unsigned: committing "as someone else" is trivial, all it takes is two lines in `git -c` - distinguish GPG (the older standard, needs gpg-agent) from SSH signing (Git 2.34+, simpler: the same ssh key you use for push) - show the setup: `git config user.signingkey <key>` + `git config commit.gpgsign true` + `git config gpg.format ssh` for the SSH variant - state that GitHub marks a commit Verified only when it is signed **and** the key is published on the author's profile - mention `git verify-commit <sha>` and `git log --show-signature` for local verification - say that highly sensitive repos should require signed commits through branch protection

Подводные камни

  • ✗ Treating `user.name`/`user.email` as authentication. It is just text in the commit, nobody verifies it
  • ✗ Storing a private GPG key without a passphrase for convenience. A leaked key means every commit can be forged
  • ✗ Enabling signed commits in branch protection and forgetting about the CI bot that commits without a key. It will block your automation

Follow-up

  • ? How do you set up SSH signing instead of GPG?
  • ? What happens when a commit is signed but the key is not on your GitHub profile?
  • ? How do you require signed commits in branch protection without breaking CI?

Глубина в базе знаний

  • GPG Commit Signing
  • [[ssh-keys-git]]
  • Branch protection rules
tags: security, signing, provenance

#git-secret-scanning-vs-gitignore

intermediateчасто

How does secret scanning differ from .gitignore? Why does .gitignore not protect you?

Что отвечать

`.gitignore` is **only a discipline tool**: it stops Git from tracking new files that match a pattern. It does not help if the file is already tracked (you need `git rm --cached`), it does not scan **contents**, and it does not catch a secret in a log line or a comment. Secret scanning (GitHub Advanced Security, gitleaks, trufflehog) scans the **diff** for regex/entropy patterns: AWS keys, Slack tokens, private keys, JWT. It runs in a pre-commit hook or in CI and catches the secret before push.

Что хотят услышать

A senior should: - name three layers of defense: pre-commit hook (fast feedback), CI scanner (protection against bypassing the hook), post-commit notification from the provider (GitHub auto-revokes leaked tokens) - say that gitleaks/trufflehog can plug into a pre-commit framework and into a GitHub Action with a single config - mention that GitHub Secret Scanning has a partner program for popular providers (AWS, Stripe, Slack). They revoke the token automatically on detection - state that `.gitignore` is still worth having as the first barrier. Not tracked means it will not land in a blob, but it is not your main defense - say that a secret **in commit history** that the scanner found requires rotation plus filter-repo, not just a delete

Подводные камни

  • ✗ Relying on .gitignore alone. It does not protect against an accidental `git add -f` or a typo in the pattern
  • ✗ Scanning only the last commit in CI. An old leak will not be found, you need `gitleaks detect` over the full history
  • ✗ Thinking secret scanning replaces a KMS/vault. It reacts to a leak, a vault prevents it

Follow-up

  • ? How do you set up gitleaks in a pre-commit hook?
  • ? What does GitHub Advanced Security do when it detects an AWS key?
  • ? In practice, how does `trufflehog` differ from `gitleaks`?

Глубина в базе знаний

  • Secret Scanning in a Repository
  • .gitignore
tags: security, secrets, scanning

#git-rm-cached-history-myth

intermediateчасто

I ran `git rm --cached secret.env` and committed. Is the secret gone from history?

Что отвечать

No. `git rm --cached` removes the file from the index and from the next commit, but **it leaves past commits untouched**. The blob with the secret stays reachable through `git log -- secret.env` and `git show <old-sha>:secret.env`. The only fix is rewriting history: `git filter-repo --invert-paths --path secret.env` plus a force-push of every branch. And, above all, **rotate the secret**. Removing it from history does not fix the leak. Only rotation does.

Что хотят услышать

The candidate should: - say "no" clearly and explain why: the blob is still in objects, visible through `git show <old-sha>:secret.env` - name filter-repo as the tool for cleaning history, not filter-branch (deprecated) - stress that rotation is **the main thing** and cleaning history is secondary. The secret already leaked, it was seen/downloaded/cached by GitHub - say that GitHub caches force-pushed commits and they stay reachable through the direct link `/<repo>/commit/<old-sha>` for a long time - mention that forks keep their own copy of the history. Even after you clean yours, the secret stays in the forks

Подводные камни

  • ✗ Saying "git rm --cached removed it from history". It did not, only from the next commit
  • ✗ Running filter-repo and not rotating the secret. The leak is still open
  • ✗ Thinking a force-push to main wiped the old SHA on GitHub. It did not, they are reachable through a direct link

Follow-up

  • ? Which `git show` finds a file in history after it was removed from the last commit?
  • ? What happens to forks after filter-repo plus a force-push?
  • ? What is the order of steps when a secret leaks into a public repo?

Глубина в базе знаний

  • .gitignore
  • git filter-repo: Rewriting History
  • Secret Scanning in a Repository
tags: security, secrets, myths

#git-ssh-key-rotation-revoke

seniorиногда

A leaked SSH key for Git: how do you revoke it and how do you avoid a replay?

Что отвечать

The steps: remove the key from GitHub/GitLab/Bitbucket settings (revoke on the server, so push breaks for whoever stole it), generate a new key pair (`ssh-keygen -t ed25519 -C "..."`, since ed25519 is shorter and faster than RSA), add the public key to the platform, update `~/.ssh/config` if you use one. If the key was used for signed commits, also revoke the signing entry (on GitHub: `Settings → SSH and GPG keys → Revoke`), otherwise old commits keep showing Verified.

Что хотят услышать

A senior should: - name "revoke on the platform" as the first action. It cuts off access immediately - recommend ed25519 (`ssh-keygen -t ed25519`) as the modern default: shorter, faster, safer than RSA-2048 - mention hardware keys (YubiKey, Secure Enclave) for highly sensitive accounts. The private part never leaves the hardware - mention `ssh-add --apple-use-keychain` (macOS) or ssh-agent + a systemd user service for convenient passphrase caching - say that for CI you are better off with deploy keys (per-repo, read-only) or OIDC federation (GitHub Actions to AWS) instead of long-lived SSH keys

Подводные камни

  • ✗ Generating a new key and forgetting to remove the old one from the platform. The leaked key still works
  • ✗ Using RSA-1024 or DSA in 2026. Those algorithms are obsolete and many platforms already reject them
  • ✗ Storing a private key without a passphrase "for convenience". A leaked laptop means instant compromise

Follow-up

  • ? How does a deploy key differ from a user key?
  • ? How do you use a YubiKey for git over SSH without a passphrase?
  • ? Why is OIDC federation preferable to long-lived keys for CI?

Глубина в базе знаний

  • [[ssh-keys-git]]
tags: security, ssh, rotation

#git-gitignore-vs-cached

juniorчасто

A file is already tracked in Git. I added it to `.gitignore` and it did not help. Why, and what is the right way?

Что отвечать

`.gitignore` affects only **untracked** files. Git keeps tracking tracked files because they are already in the index. To stop tracking without deleting it locally: `git rm --cached <file>` (removes it from the index, keeps it on disk), then commit, and after that `.gitignore` will work. For a whole directory: `git rm --cached -r <dir>`. Keep in mind that **past commits with the file stay**. The content is in history.

Что хотят услышать

The candidate should: - explain why `.gitignore` is ignored for tracked files: otherwise an accidental pattern would drop the file from the commit - give the correct workflow: `git rm --cached <file>` + commit + `.gitignore` - name `git check-ignore -v <file>` as the way to check which rule in `.gitignore` fires (or does not fire) - mention `.git/info/exclude` as the local (non-shared) counterpart of `.gitignore`. It does not land in a commit, handy for personal .DS_Store or IDE configs - stress that this does not clean the file's history. The blob stays reachable

Подводные камни

  • ✗ Thinking that adding to `.gitignore` stops tracking right away. It does not for an already tracked file
  • ✗ Running `git rm <file>` instead of `git rm --cached <file>`. It deletes the file from disk
  • ✗ Using `.gitignore` for secrets. It does not help after the first commit

Follow-up

  • ? What does `git check-ignore -v src/secret.env` show?
  • ? How does `.git/info/exclude` differ from `.gitignore`?
  • ? How do you untrack the whole `node_modules/` directory in one command without deleting it from disk?

Глубина в базе знаний

  • .gitignore
tags: security, gitignore, trackingbook: github.for.next.generation.coders.epub:ch3
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies