HTTPS vs SSH
Intermediate Core Git Git CLI
Why this matters
Every clone URL commits you to one of two authentication methods, and the choice shows up every time you push. Neither is more secure in practice; they fail differently, and knowing which one a repository uses turns a confusing error into an obvious one.
The two methods
HTTPS uses the same protocol as your browser. When Git needs to prove who you are, it sends a username and a password, and the "password" is an access token generated on the website. Your credential helper stores it after the first use, so you type it once (lesson 8.4).
SSH uses a key pair: two matching files created on your computer. You upload the public half to GitLab or GitHub; the private half stays on your machine. When you connect, the server sends a challenge that only the holder of the private key can answer, so nothing secret crosses the network at all (lesson 8.2).
Which one is this repository using?
The URL says it:
$ git remote -vorigin https://gitlab.com/northwind-trails/trailguide.git (fetch)
origin https://gitlab.com/northwind-trails/trailguide.git (push)| URL starts with | Method | What Git will ask for |
|---|---|---|
https:// |
HTTPS | a username and a token (once, then the helper answers) |
git@ or ssh:// |
SSH | your key, and its passphrase if it has one |
Switching an existing clone is one command and touches no commits:
$ git remote set-url origin git@gitlab.com:northwind-trails/trailguide.gitChoosing
| HTTPS + token | SSH + key | |
|---|---|---|
| Setup effort | A form on the website, one paste | A command, then a paste on the website |
| Company firewalls and proxies | Almost always allowed | Sometimes blocked (port 22) |
| Expiry | Tokens expire, typically after a year; pushes then fail until you renew | Keys do not expire by default |
| Scope of damage if it leaks | Limited to the token's scopes; revoke on the website | Full access as you until you remove the key; a passphrase buys time |
| Several accounts on one machine | Awkward; the helper stores one credential per host | Straightforward with an SSH config file |
| Automation and servers | Deploy tokens | Deploy keys |
| Typing | Nothing after the first time | Passphrase once per session (or never, with an agent) |
Practical advice: on a company laptop, start with HTTPS, because it works through whatever the network team has configured, and the credential helper is already installed. Switch to SSH if you push many times a day, manage more than one account, or find yourself renewing tokens often. Many people use both: HTTPS at work, SSH at home.
Common mistakes
- Expecting an SSH key to be used by an
https://remote. The URL decides.git remote -vfirst. Permission denied (publickey)on an SSH remote. The key is missing, not loaded, or not uploaded; lesson 8.2 diagnoses it.Authentication failedon an HTTPS remote. A password was typed, or the token expired; lesson 8.3.- Cloning with SSH on a machine where you have no key. The clone fails at once; use the HTTPS URL instead, or set up a key.
- Assuming one is more secure. Both are strong. What differs is what happens when a credential leaks and how easy it is to revoke.
Try it yourself
Goal: identify your method, and see the other one refuse.
- In your playground, run
git remote -vand note the URL form. - Run
git remote show origin; it contacts the server, so it fails if authentication is not working. - If you use HTTPS, try
ssh -T git@gitlab.com(orgit@github.com) to see what happens without a key uploaded; if you use SSH, look at the same URL in HTTPS form on the project page. - Do not change your remote unless you want to; if you do,
git remote set-url origin <other-url>and back again.
Expected result: step 2 succeeds and prints the branch list; step 3 either greets you by name (a key is set up) or refuses with Permission denied (publickey), which is the expected answer when no key is uploaded.
Show solution
ssh -T is a test connection: GitLab answers Welcome to GitLab, @you! and GitHub answers Hi you! You've successfully authenticated…, in both cases without giving you a shell. A refusal is not a problem if you use HTTPS; it just means no key is configured, which is lesson 8.2's subject.