I know that pushing a commit with an API key is something for which a developer should have his balls cut off, but…
…I’m wondering what I should do if, somehow, I accidentally commit an API key or other sensitive information, an environment variable to the repo.
Should I just revoke the access and leave it as is, or maybe locally remove this commit and force-push a new one without the key? How do you guys handle this situation in a professional environment?
Other answers have only called out rotating the secret which is how you fix this specific failure. After you’ve rotated, delete the key from the repo because secrets don’t belong in repos. Next look at something like git-secrets or gitleaks to use as a local pre-commit hook to help prevent future failures. You’re human and you’re going to make mistakes; plan for them.
Another good habit to be in is to only access secrets from environment variables. I personally use direnv whose configuration file is globally ignored via the core.excludesfile.
You can add other strategies for good defense-in-depth such as a pre-receive hook checking for secrets to ensure no one can push them (eg they didn’t install hooks).
The smoking man clearly has engineered with humans before. Kudos for excellent advice.
only access secrets from environment variables
I kind of think this is a bad idea because environment variables can be read from anywhere and aren’t designed to be secret.
But I’m not sure what a better solution is tbh.
Storing them in files with correct permissions.
also storing them outside of the webserver directory
you’re not entirely wrong, but this is the current standard/accepted advice for local development - probably what we’re talking about given this thread is about git commits - because the chance of exploit via this mechanism requires local access… with such access, you’re pretty screwed in far more ways
Sops, or OpenBao
Rotate the keys, the old one is on the Internet forever
This is the only answer. Git history is forever.
you can overwrite it
If you upload anything to the internet unencrypted, it’s always best to assume it’ll be publicly accessible forever.
Another user shared this link. https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github
s/git/github please
As others have already pointed out, you must rotate the key. I don’t even put any restrictions on that. Once you have shared a secret in any way, it is no longer a secret. Don’t try to avoid work, just because it is an inconvenience. Convenience is the enemy of security.
Rotating your key is not enough though. Verify that it wasn’t used. API providers also often provide audit logs to show when credentials were used and from which location. If someone had your key only for a second, they could have used it to generate a new key you don’t even know about. Audit!
If you pushed to github, that key is there forever! (very few exceptions). Regardless, if you pushed it to any machine you don’t own, assume it’s compromised and rotate.
If it’s a publicly-accessible repo, then immediately revoke the key and leave it. Force-pushing isn’t good enough because the old commit will still be tracked by Git until the garbage collector kicks in, and you don’t have control over the GC on GitHub (not sure about other providers).
If it’s an internal repo that’s only accessible by employees, then you probably should still revoke it, but you’ve got more leeway. Usually I’d create a ticket to revoke it when there’s time, unless this is particularly sensitive.
You don’t say if you noticed before pushing. If it’s your last commit and not pushed yet, you can still amend your last commit.
https://rtyley.github.io/bfg-repo-cleaner/
Also revoke the key of course
If you didn’t push your changes yet, you can use
git filter-branch
to remove it from all your commits. If you already pushed (or figured out that someone committed and pushed a key), you can do the same with force-push, but also revoke the key.Revoke, invalidate, rotate, blacklist, do whatever to make the key/information not usable for that system anymore. It’s an “exploit” (but more a defining feature of git) to record everything because each link is dependent on the last thing and even old branches can be brought back and searched through.
If it’s a public repo, revoke the key (on your own/company repo it might not matter so much)
Then
git reset head~1
- remove api key
git push - f