How to Publish a Public GitHub Repo Securely
Making a side project public on GitHub is great for a portfolio — but it's also the fastest way to leak a secret if you're not careful. Here's a practical checklist before (and after) you flip that repo to public.
1. Audit history before you make it public
Making a repo public doesn't just expose the current files — it exposes every commit in its history. If you ever committed a real .env, an API key, or a database password and later deleted it, it's still sitting in the git log. Run a scanner like gitleaks or git-secrets against the full history before flipping visibility.
gitleaks detect --source . -vIf it finds something, don't just delete the file in a new commit — that leaves it in history. Use git filter-repo (or the older BFG Repo-Cleaner) to actually strip it out, then rotate the leaked credential regardless, since you can't be sure no one already saw it.
2. Never commit real secrets — commit the shape of them instead
The pattern that works well: keep a .env.example with placeholder values checked in, and the real .env gitignored:
# .gitignore
.envAnyone cloning the repo sees exactly which variables they need to set, without ever seeing a real value.
3. Turn on secret scanning and push protection
GitHub has this built in for public repos, for free: Settings → Code security → enable Secret scanning and Push protection. Push protection blocks a commit at push-time if it matches a known secret pattern (AWS keys, private keys, common API token formats) — it catches mistakes before they ever hit history.
4. Scope tokens instead of reusing your personal one
If GitHub Actions needs to talk to AWS, don't drop long-lived AWS access keys into repo secrets. Use OpenID Connect (OIDC) so Actions assumes a scoped IAM role for the duration of the run, with no long-lived credential stored anywhere. If you must use a personal access token, use a fine-grained token scoped to that one repo, not a classic token with account-wide access.
5. Protect the default branch
Settings → Branches → add a protection rule on main: require a pull request before merging and require status checks to pass. This also stops a force-push from silently rewriting the history everyone builds from.
6. Turn on 2FA and use SSH keys, not passwords
Basic, but still the most common way accounts get taken over. Enable two-factor authentication, and use SSH keys instead of authenticating over HTTPS with a password.
7. Add a SECURITY.md
Even for a small project, a short SECURITY.md telling people how to privately report a vulnerability (instead of opening a public issue) is good practice once other people start depending on your code.
None of this is exotic — it's the same checklist any security review would run before a repo goes live. Doing it up front is a lot cheaper than rotating credentials after the fact.