Skip to content
October 23, 2026 Practical guides on software, AI and security

Search Shartech Blogs

Software Development

Private Repository Security: A Practical Checklist with Commands (GitHub)

Table of Contents

It’s easy to treat “private” as the security setting for a repository. It isn’t. A private repo is only as safe as every account that can access it, every token that can clone it, every CI job that runs in it, and every secret someone once committed to it and forgot about. Most real-world code leaks don’t come from someone breaking into GitHub. They come from a stolen laptop, a leaked token, an over-permissioned integration or a repo accidentally made public.

This is a practical checklist for securing private repositories, mostly on GitHub, with the actual commands and settings rather than general advice.

1. Lock down accounts first

Every person with access is a way in. Start with the accounts:

  • Require two-factor authentication for your organisation (Organization settings → Authentication security). Prefer passkeys or an authenticator app over SMS.
  • Use least privilege. Most developers need Write, not Admin. Give Admin to as few people as possible, and use teams rather than adding individuals repo by repo so access is easy to review.
  • Review access regularly. Remove people who’ve left or changed roles. Put a recurring reminder in the calendar, because nobody remembers otherwise.
  • Restrict who can change visibility. In organisation settings you can prevent members from making private repositories public, which is a common source of accidental exposure.

2. Use SSH keys or fine-grained tokens, not passwords

GitHub no longer accepts account passwords for Git operations. You’ll use either an SSH key or a token. For SSH, generate a modern key and protect it with a passphrase:

ssh-keygen -t ed25519 -C "you@example.com"
# add the key to your agent so you don't retype the passphrase
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# then paste ~/.ssh/id_ed25519.pub into GitHub → Settings → SSH and GPG keys
ssh -T git@github.com

If you use HTTPS, create a fine-grained personal access token rather than a classic one. Fine-grained tokens can be limited to specific repositories and specific permissions, and must have an expiry date. A leaked token that can only read one repo for 30 days is a much smaller problem than a classic token with full access to everything.

For automation, don’t use a person’s token at all. Use a GitHub App or, for deployment to a single repo, a deploy key. Both can be scoped narrowly and aren’t tied to someone’s personal account.

3. Keep secrets out of the repository

This is the single most important habit. API keys, database passwords and private keys in a Git repository end up in every clone, every fork and every backup, forever, even if you delete them in a later commit.

Keep configuration in environment variables or a secrets manager, commit a template instead of the real file, and ignore the real one:

# .gitignore
.env
.env.*
!.env.example
*.pem
*.key

Then add a safety net that catches secrets before they’re committed. Gitleaks is an open-source scanner that works well as a pre-commit hook:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.2   # use the latest release tag
    hooks:
      - id: gitleaks
pip install pre-commit
pre-commit install
# scan the existing history once
gitleaks git -v

Pre-commit hooks run on each developer’s machine and can be skipped, so also run the scan in CI.

If a secret was already committed

  1. Revoke and rotate it immediately. This is the step that actually matters. Assume it’s compromised.
  2. Then, if you need to, remove it from history with a tool like git filter-repo, and force-push. Everyone will need to re-clone.

Cleaning history without rotating the secret doesn’t help, because copies may already exist elsewhere.

4. Protect your main branch

Branch protection rules, or the newer repository rulesets, stop anyone pushing straight to main. Useful rules include:

  • Require a pull request with at least one approving review.
  • Require status checks (tests, lint, secret scan) to pass before merging.
  • Dismiss stale approvals when new commits are pushed.
  • Block force pushes and branch deletion.
  • Apply the rules to administrators too.

Add a CODEOWNERS file so changes to sensitive areas need a review from the right people:

# .github/CODEOWNERS
/infra/          @your-org/platform-team
/.github/        @your-org/platform-team
/src/payments/   @your-org/payments-team

Note that on GitHub, branch protection and rulesets for private repositories require a paid plan (Pro, Team or Enterprise). On the Free plan they’re available for public repositories only.

5. Sign your commits

Git lets anyone set any name and email on a commit. Signed commits prove that a commit really came from a key you control, and GitHub shows them as “Verified”. The simplest setup reuses your SSH key:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

Add the same public key to GitHub a second time, as a signing key. You can then require signed commits on protected branches.

6. Secure your CI/CD

CI pipelines often have more power than any developer: deploy keys, cloud credentials and write access. Treat workflow files as sensitive code.

  • Set minimal token permissions at the top of each GitHub Actions workflow and grant more only where needed:
permissions:
  contents: read
  • Pin third-party actions to a full commit SHA, not a tag like @v4, because tags can be moved. Several supply-chain incidents have involved compromised actions.
  • Use OIDC for cloud deployments where possible, so the workflow gets short-lived cloud credentials instead of long-lived keys stored as secrets.
  • Protect deployment environments with required reviewers for production.

7. Watch your dependencies

Your code is only part of what you ship. Enable Dependabot alerts and security updates, which are available for private repositories on all plans, and add a dependabot.yml so version updates arrive as regular pull requests:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

8. Know what’s free and what isn’t

GitHub’s secret scanning with push protection, which blocks pushes that contain recognised secrets, is free for public repositories. For private repositories in organisations, it’s part of GitHub Secret Protection, which GitHub introduced in 2025 at $19 per active committer per month, alongside GitHub Code Security at $30 per active committer per month, according to GitHub’s announcement. Both became available to Team plan customers, not only Enterprise.

If that’s outside your budget, the open-source combination of Gitleaks in pre-commit and CI, Dependabot, and careful branch rules covers much of the same ground.

9. Plan for mistakes

  • Add a SECURITY.md explaining how to report a problem, even for internal repos.
  • Turn on the organisation audit log and know where to find it.
  • Keep a short written plan for a leaked credential: who rotates what, and in what order.
  • Back up critical repositories somewhere outside your Git host.

A quick checklist

  1. 2FA required, admins kept to a minimum, access reviewed quarterly.
  2. SSH keys or fine-grained tokens with expiry. Apps or deploy keys for automation.
  3. .env ignored, Gitleaks in pre-commit and CI.
  4. Protected main with reviews, status checks and CODEOWNERS.
  5. Signed commits.
  6. Minimal workflow permissions, pinned actions, OIDC for cloud.
  7. Dependabot on.
  8. A plan for when something leaks.

None of this is complicated, and most of it takes an afternoon to set up. The payoff is that a single stolen laptop or leaked token becomes an inconvenience rather than a breach.

Related reading

Sources: GitHub Docs: SSH keys, GitHub Docs: protected branches, GitHub Docs: commit signature verification, GitHub Changelog, Gitleaks.

Did you find this article helpful?

Written by

Malik Shamir

Malik Shamir is the founder and lead tech writer at SharTech, a modern technology platform focused on artificial intelligence, software development, cloud computing, cybersecurity, and emerging digital trends. With hands-on experience in full-stack development and AI systems, Shamir creates clear, practical, and research-based content that helps readers understand complex technologies in simple terms. His mission is to make advanced tech knowledge accessible, reliable, and useful for developers, entrepreneurs, and digital learners worldwide.

54 Articles Website
Previous Article Open-Source CLI Coding Agents: Gemini CLI, Codex CLI, Aider and Goose Compared Next Article Building on Decentralized Social Networks: ActivityPub, AT Protocol, Farcaster and Lens in 2026

Leave a Comment

Your email address will not be published. Required fields are marked *

Stay Updated with Shartech

Get smart tech insights, tutorials, and the latest in AI & programming directly in your inbox. No spam, ever.

We respect your privacy. Unsubscribe at any time.