Authentication quick-start
Intermediate Git CLI GitLab UI GitHub UI
Why this matters
The first push to a private repository is where most people get stuck, and the error message is unhelpful because it looks like a password problem. It is not. GitLab and GitHub stopped accepting account passwords over Git years ago. This lesson gets you working in ten minutes; Section 8 explains tokens, keys, scopes and expiry properly.
Two routes
| HTTPS with an access token | SSH with a key pair | |
|---|---|---|
| URL looks like | https://gitlab.com/group/project.git |
git@gitlab.com:group/project.git |
| You set up | A token on the website, pasted once | A key pair on your computer, public half uploaded |
| Works behind strict company firewalls | Usually yes | Sometimes blocked |
| Expiry | Tokens expire; you renew them | Keys do not expire by default |
| Best for | Getting started today, and most corporate laptops | People who push many times a day, on machines they control |
Both are equally legitimate. Pick HTTPS if you want to be working in five minutes.
Route 1: HTTPS and an access token
An access token is a long generated string that acts as a password for one purpose, with limited permissions and an expiry date. You create it on the website and paste it once.
- Create the token. On GitLab: your avatar → Edit profile → Access → Personal access tokens → Generate token (older versions say Add new token). Fill in Token name, an Expiration date (365 days is the default and usually the maximum), and tick the scopes
read_repositoryandwrite_repository. On GitHub: avatar → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token, select the repository, and give it the Contents: Read and write permission. - Copy it immediately. Both platforms show the token exactly once. If you lose it, delete it and make another; there is no way to see it again.
-
Push. Git asks for a username and password:
Terminal $ git push -u origin mainUsername for 'https://gitlab.com': ana Password for 'https://ana@gitlab.com':Type your platform username, and paste the token as the password. Nothing appears as you paste; that is normal. 4. Confirm it was stored. Push again after another commit. If you are not asked a second time, your credential helper saved it (lesson 3.3 set that up: Keychain on macOS, Credential Manager on Windows).
Route 2: SSH and a key pair
An SSH key is a pair of files: a private half that never leaves your computer and a public half you upload to GitLab or GitHub. The server recognizes you by the pair without any password being sent.
$ ssh-keygen -t ed25519 -C "ana@northwind-trails.example"Generating public/private ed25519 key pair.
Your identification has been saved in /Users/you/.ssh/id_ed25519
Your public key has been saved in /Users/you/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:YMp4KTlbeWOy2ELLvIbfcMl2e0oRPmBhrggl5ND78rg ana@northwind-trails.examplePress Enter at each prompt to accept the default path, and set a passphrase if you want one. Then copy the public half and paste it into the website:
$ cat ~/.ssh/id_ed25519.pubOn GitLab: avatar → Edit profile → SSH keys → Add new key. On GitHub: avatar → Settings → SSH and GPG keys → New SSH key. Paste the whole line, starting with ssh-ed25519.
Test it, then use the SSH form of the URL when cloning:
$ ssh -T git@gitlab.com
$ git clone git@gitlab.com:northwind-trails/trailguide.gitWhich one is this repository using?
$ git remote -vA URL beginning https:// uses a token; one beginning git@ uses a key. Switching an existing clone from one to the other is one command, and no commits are affected:
$ git remote set-url origin git@gitlab.com:northwind-trails/trailguide.gitHow to do it
The steps above. The one command worth memorizing when something goes wrong:
$ git remote -vIt tells you which method the repository expects, which decides whether the problem is a token or a key.
VS Code uses the same credential helper as the terminal, so a token stored by one is found by the other. For GitHub specifically, VS Code can sign you in: the Accounts icon at the bottom of the Activity Bar → Sign in with GitHub, which handles authentication for cloning and for the pull request extension without a token.
For GitLab, install the GitLab Workflow extension and give it a token in its settings.
Settings → Version Control → GitHub (or GitLab) → + → Log In with Token… or, for GitHub, Log In with GitHub… which opens a browser. Once an account is added, IntelliJ handles authentication for clone, push and pull requests.
Tokens live under your avatar → Edit profile → Access tokens; SSH keys under SSH keys. Both pages list what exists, when it expires, and when it was last used, and both let you revoke with one click.
Projects and groups can also have their own tokens for automation (lesson 8.3); for your own work, a personal token is the right one.
Tokens live under avatar → Settings → Developer settings → Personal access tokens, in two flavours: Fine-grained tokens (per repository, per permission, recommended) and Tokens (classic) (broad scopes, older). SSH keys are under Settings → SSH and GPG keys.
If your organization uses single sign-on, a new token must additionally be authorized for the organization from that same token page.
Common mistakes
- Typing your account password.
remote: HTTP Basic: Access deniedorAuthentication failed. Passwords are not accepted; use a token. - A token without the write scope. Cloning works, pushing fails. Check the scopes on the token page;
write_repositoryon GitLab, Contents: Read and write on GitHub. - Pasting the private key instead of the
.pubfile. Delete the key pair, generate a new one, upload only.pub. - A stored wrong token. The helper keeps answering with it and the error repeats. Remove the stored entry (lesson 8.4).
- Mixing the URL forms. An
https://remote will never use your SSH key.git remote -vfirst.
Try it yourself
Goal: find out how your playground authenticates, and prove the credential is stored.
- Run
git remote -vand note whether the URL starts withhttps://orgit@. - Make a small commit and push. Note whether you were asked for anything.
- If you were asked, push a second time after another commit; you should not be asked again.
Expected result: an https:// remote asks once and then remembers; a git@ remote asks for the key passphrase at most once per session.
Show solution
Being asked every single time means no credential helper is configured. On macOS git config --global credential.helper osxkeychain, on Windows manager, on Linux libsecret or store. Lesson 8.4 covers each and shows how to remove a wrong entry.