GitHub Stops Taking Your Password for Git This Friday
If you still type your GitHub password when git push asks for one, you have until Friday. Starting August 13, 2021, GitHub.com stops accepting account passwords for Git operations. The push that worked this morning will fail with an authentication error, and depending on how your machine caches credentials, you might not notice until a cron job quietly stops mirroring a repo next week.
Here’s what’s actually changing, who it doesn’t touch, and how to get your laptop, scripts and CI sorted out in an evening.
What GitHub announced
The details are in GitHub’s post on token authentication requirements for Git operations from last December. The short version is that authenticated Git operations on GitHub.com will need a token instead of your account password. For a person, that means a personal access token over HTTPS, which GitHub calls the recommended option, or an SSH key if you’d rather use that. For apps and integrations, it means OAuth or GitHub App installation tokens.
The post calls out three kinds of workflows that are affected: command line Git, desktop apps that use Git under the hood, and any app or service that talks to your repositories directly with your password. GitHub also scheduled two brownouts to shake people loose, on June 30 and July 28, switching password authentication off for two three hour windows on each of those days. If a push randomly failed on one of those days and then worked an hour later, that was your warning. And if this feels familiar, the REST API went through the same change, and passwords stopped working there on November 13, 2020.
Who can ignore this
A fair number of people won’t notice anything. If you already have two factor authentication turned on, GitHub has required a token or SSH key for Git all along, so you’re already set. If you clone and push over SSH, nothing changes. GitHub Desktop is specifically listed as unaffected. And if you run GitHub Enterprise Server, the announcement says GitHub hasn’t announced any changes for the on premises product. The people who get bitten are the ones without 2FA who have been typing, or caching, a real password over HTTPS.
Why tokens instead of passwords
GitHub’s reasoning is pretty sound. A token is specific to GitHub, so it isn’t the same string you reused on some forum that got breached in 2016. You can create one per machine or per script and revoke any one of them without touching the rest. You can scope it down so it can only do what the job needs. And it’s random, so it isn’t going to fall to a dictionary attack.
There’s also a nice detail from earlier this year. GitHub changed its token format so personal access tokens now start with ghp_, and GitHub’s changelog entry for the new format says the reason to reset older tokens is so secret scanning can detect them. If you have tokens from before the new format went live at the end of March, regenerating them is worth the five minutes.
a personal access token over HTTPS
This is the smallest change if you’re happy with HTTPS remotes. You create a token in your account’s developer settings, and then you paste it wherever Git asks for your password.
Two choices on that page matter. The first is scopes. GitHub’s personal access token docs say to select repo if you want to use the token for repositories from the command line. If you push changes to files under .github/workflows, you’ll also want the workflow scope, since that’s the scope that allows adding and updating Actions workflow files. A token that only has repo can’t manage your SSH keys or change organization settings if it leaks.
The second is expiration, which is brand new. As of late July you can set expiration dates on personal access tokens, and GitHub will email you when one is about to run out. Expired tokens can be regenerated with the same settings, so an expiry date costs you a reminder email and a paste. A 90 day token on a laptop is a lot less scary than a token that works forever from a machine you might sell. GitHub also removes tokens that haven’t been used for a year, but that’s a backstop, not a plan.
Getting the old password out of your credential cache
If Git has been storing your password, it will keep offering it, and on some setups it won’t even prompt you. So clear it first.
On a Mac, the osxkeychain helper keeps it in your login keychain. GitHub’s page on updating credentials from the macOS Keychain shows two ways: search Keychain Access for the github.com internet password entry and delete or edit it, or erase it from the terminal.
git credential-osxkeychain erase
host=github.com
protocol=https
Press Return on a blank line after protocol=https and it’s gone. The next push prompts you, you paste the token as the password, and the keychain stores the token from then on. If you don’t have a helper set up at all, git config --global credential.helper osxkeychain turns it on.
On Linux, the built in cache helper only holds credentials in memory for a while (15 minutes by default), so it’s safe but you’ll be pasting often. Please don’t reach for the store helper or put the token in the remote URL as https://user:token@github.com/.... Both leave the token in plain text on disk, and a URL with a token in it also lands in .git/config, your shell history, and any log that prints the remote.
Let a credential manager or the GitHub CLI handle it
Microsoft’s Git Credential Manager Core is a credential helper that supports two factor sign in for GitHub and stores what it gets in the platform’s secure storage, which is Windows Credential Manager on Windows and the Keychain on macOS. It’s bundled with Git for Windows, and on a Mac the project recommends installing it with Homebrew from the microsoft/git tap. Linux support is still marked as a preview. Once it’s configured, Git asks it for credentials, and it can sign you in to GitHub with OAuth and store the result, so you don’t have to create and paste a token by hand.
The GitHub CLI is the other easy route. Run gh auth login and it walks you through a browser based sign in, then asks which protocol you prefer for Git. Pick HTTPS and say yes to authenticating Git with your GitHub credentials, and gh sets itself up as Git’s credential helper for github.com (or hands the token to the helper you already have). Pick SSH and it looks for an existing public key to upload, or offers to generate a new one. On a fresh laptop, that’s the fastest path I know of.
switch to SSH
If you’d rather never think about tokens for everyday Git, SSH keys are still fully supported. GitHub’s guide to generating a new SSH key recommends Ed25519, with 4096 bit RSA as the fallback for legacy systems that don’t support it.
ssh-keygen -t ed25519 -C "work-laptop"
Give it a passphrase. On macOS you can have the agent remember it in the keychain so you only type it once, with a few lines in ~/.ssh/config.
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Add the public key in your account’s SSH key settings, check it with ssh -T git@github.com, and then point existing clones at the SSH URL.
git remote set-url origin git@github.com:USERNAME/REPO.git
That last step is easy to forget, since a new key does nothing for a remote that still starts with https://.
Scripts, servers and CI
The machines are where this bites hardest, because nobody is watching when they fail. Search your deploy scripts, cron jobs, Dockerfiles and CI config for github.com URLs with credentials in them, and for any variable that holds a GitHub password.
If you use GitHub Actions, the checkout action defaults to the automatic GITHUB_TOKEN, an installation access token GitHub creates for each job that expires when the job finishes. That’s not a password, so those workflows are fine. Steps that reach other repositories with a stored password are the ones to fix.
If a job only needs one repository, a deploy key is an SSH key attached to that single repo, read only unless you allow write access. If it needs several repos across an organization, a GitHub App lets you generate tightly scoped tokens with just the permissions the job needs. A personal access token in the CI system’s secret store works too, but it acts as whoever created it, so give it minimal scopes, an expiration date, and a name that says which pipeline it belongs to. GitHub’s own docs say to treat tokens like passwords and pass them in as environment variables rather than hardcoding them.
Do it before Friday
The practical move is to try a push from every machine and pipeline you care about today, not Friday morning. Clear any cached password, pick tokens or SSH, and put expiration dates on whatever tokens you create. If you haven’t turned on two factor authentication yet, this is a good week for that too, since it closes off password auth for Git entirely and protects the web login that can create all these tokens in the first place.