Protect source and CI

Protect repository access

Require strong authentication, least privilege, attributable accounts, prompt offboarding, and recovery controls for source hosting.

Source hosting controls what becomes trusted code. Protect it as a production system.

Anyone who can push to your repository can change what every build after that moment contains. That includes people, but also machine identities: deploy keys, personal access tokens, and installed GitHub Apps. Each one is a door.

Start with authentication. Require MFA or passkeys for everyone in the organization, avoid shared accounts, and limit how many people are organization owners. An owner can change every other control, so each owner account is a single point of failure.

Inventory who and what has access

You cannot review access you have not listed. With the GitHub CLI:

gh api repos/acme/api/collaborators --jq '.[] | "\(.login) \(.permissions.admin)"'
gh api repos/acme/api/keys --jq '.[] | "\(.title) read_only=\(.read_only)"'

The first command prints every collaborator and whether they hold admin rights. The second prints deploy keys and whether each can write. A write-capable deploy key with a title nobody recognizes is a finding, not background noise.

Every entry in those lists needs an owner and a reason. If nobody can say why an integration has access, remove it and see what breaks in staging.

Offboard immediately, not eventually

A contractor leaves, but their personal account and old deploy key remain attached to the repository. Months later, either credential can still change release source without using a current team identity. Access removal belongs in the offboarding checklist with the same urgency as revoking a production database password.

Recovery is a privileged path too

Keep emergency recovery controlled and tested. Strong daily authentication helps little if one shared recovery account can bypass it. Store recovery codes for the organization owners somewhere access-controlled and audited, and rehearse the lost-owner scenario before you need it.

Export or capture the current owners, collaborators, applications, deploy keys, and recovery methods for one repository. Assign an owner and reason to every privileged entry, then remove one disposable test identity and prove its access fails. Record how the team would recover if the last owner lost access.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →