# Git & GitHub Security Checklist

From Modern Git Academy — https://moderngitacademy.com/

---

## Credentials in history

- [ ] Secret scanning enabled on every repository.
- [ ] **Push protection** on — it blocks the commit rather than reporting it afterwards.
- [ ] A `.gitignore` covering `.env`, key files and credential stores.
- [ ] Team knows: a committed secret is **exposed the moment it is pushed**.

### If a secret is committed

**Order matters:**

1. **Revoke the credential first.** Rotation is the fix; history cleanup is tidying.
2. Assess exposure — repository visibility, who had access, whether it was cloned.
3. *Then* consider history rewriting.

⚠️ Removing a secret from history does not remove it from existing clones or forks. Anyone
who cloned still has it. Rotation is the only thing that actually helps.

## Repository configuration

- [ ] Default branch protected by a ruleset.
- [ ] Force pushes blocked on the default branch.
- [ ] Branch deletion restricted.
- [ ] Pull request required before merge.
- [ ] Required reviewer is **someone other than the author**.
- [ ] Required status checks that actually exist and run.
- [ ] Automatic branch deletion on merge.
- [ ] File size limit via push ruleset — well below the 100 MB hard limit.

## Access

- [ ] Base permission is `read` or `none`, not `write`.
- [ ] Access granted to **teams**, not individuals.
- [ ] Outside collaborators reviewed quarterly — they sit outside SSO and SCIM.
- [ ] Admin permission is rare and justified.
- [ ] Deploy keys inventoried; read-only unless write is genuinely needed.
- [ ] Two-factor authentication enforced.

## Machine identities

- [ ] Automation authenticates as a **GitHub App**, not a personal access token.
- [ ] No production pipeline depends on an individual's token — it dies when they leave.
- [ ] App private keys in a secret manager, rotated on a schedule.
- [ ] Apps installed on the repositories they need, not "all repositories".
- [ ] Classic personal access tokens inventoried and migrated to fine-grained.

## Actions

- [ ] Default workflow permissions set to **read-only**.
- [ ] Workflows cannot approve pull requests.
- [ ] Third-party actions pinned to a commit SHA.
- [ ] No fork PR code executed with secrets. Check every `pull_request_target`.
- [ ] Untrusted input passed via `env:`, never interpolated into `run:`.
- [ ] Production credentials in **environments with required reviewers**.
- [ ] OIDC used instead of long-lived cloud keys.
- [ ] Self-hosted runners not reachable from public repositories.

## Commit integrity

- [ ] Commit signing configured (GPG, SSH or S/MIME).
- [ ] Signing solved for bots before it is *required* of humans.
- [ ] Team knows commit author fields are self-asserted and trivially forged — signing is
      what makes authorship verifiable.

## Dependencies

- [ ] Dependabot alerts on.
- [ ] Dependency review on pull requests.
- [ ] Lockfiles committed.
- [ ] A route to act on a critical advisory within days, not quarters.

## Audit

- [ ] Audit log **streamed** to storage you control.
- [ ] Git events included — GitHub retains those only **seven days**.
- [ ] Alerts on: repository made public, transferred, deleted; SSO configuration changed.

---

Full lessons: https://moderngitacademy.com/security/
