skip to content

questions

6

In Git, how do https:// and ssh:// remote URLs differ in how they authenticate?

level: juniorimportance: must knowfreq 74%

answer

  1. The scheme decides who proves what
  2. One shells out to another program
  3. One asks a helper for a secret per request
  4. Keys versus tokens
  5. Port 443 versus port 22

basics

~20 s

An https:// remote authenticates per request with a username and a token, supplied by a credential helper over a TLS connection. An ssh:// remote shells out to ssh, which authenticates with a key pair; the server then runs git-upload-pack or git-receive-pack over that channel.

solid answer

~40 s

With an `https://` remote, Git speaks smart HTTP over TLS and needs a username and secret for each authenticated request. It asks the configured `credential.helper` first, and prompts only if no helper answers; most hosts now expect a personal access token rather than an account password in that field. With an `ssh://git@host/org/repo.git` remote — or the equivalent scp-like form `git@host:org/repo.git` — Git shells out to the system `ssh` client, which authenticates with a key pair from `~/.ssh` or an agent, and the server then runs `git-upload-pack` or `git-receive-pack` on the other end of that channel. There is also the legacy `git://` transport, which is anonymous, read-only, unencrypted and unauthenticated; it should not be used for anything private. Switching between them is just `git remote set-url`.

code

bash · 6 lines
bash
git remote -v
# origin  [email protected]:acme/app.git (fetch)
# origin  [email protected]:acme/app.git (push)

git remote set-url origin https://example.com/acme/app.git
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519_ci" git ls-remote [email protected]:acme/app.git

go deeper

for a junior

Be able to read a remote URL and say how it will authenticate: a key pair for the SSH forms, a username and token for HTTPS. Know git remote -v and git remote set-url.

for a middle

Explain that Git shells out to ssh for SSH remotes while HTTPS goes through the credential-helper mechanism, and name the server-side programs the transports invoke.

for a senior

Argue the operational tradeoffs — proxy traversal, container ergonomics, host-key verification, credential rotation — rather than repeating a preference for one scheme.

for a principal

Own which transport the organization standardizes on for humans and for automation, and what that implies for firewall rules, secret rotation and onboarding.

## The transports Git speaks A remote URL's scheme selects a transport, and each transport has its own authentication story. **HTTPS** — `https://host/org/repo.git`. Git makes HTTP requests to the server's Git endpoints over TLS. TLS authenticates the *server* and encrypts the channel; the *client* proves who it is with an HTTP credential, conventionally a username plus a secret. Most hosts have stopped accepting an account password here and expect a personal access token instead — a separately issued secret with its own permissions and expiry, revocable without changing your login. **SSH** — `ssh://git@host/org/repo.git`, or the older scp-like shorthand `git@host:org/repo.git` (note the colon, and that it takes no port; use the full `ssh://` form when you need `-p`-style port selection). Git does not implement SSH itself; it executes the system `ssh` binary, which performs public-key authentication using a key from `~/.ssh` or from a running `ssh-agent`. Once authenticated, the client asks the server to run `git-upload-pack` (for fetch) or `git-receive-pack` (for push), and the Git protocol flows over that channel. **git://** — the daemon protocol on port 9418. It has no authentication and no encryption. It exists for fast anonymous public mirrors and is unsuitable for anything private. **file://** and a plain local path also work, useful for local mirrors and tests. ## Where the secret lives in each case For SSH, the secret is a private key file on disk, usually protected by a passphrase and unlocked once into `ssh-agent`. Git itself never sees it. You can point Git at a specific key or ssh invocation with `core.sshCommand` or the `GIT_SSH_COMMAND` environment variable — useful when one machine must use different identities for different hosts. For HTTPS, the secret reaches Git through the credential-helper mechanism (`credential.helper`), which may store it in an OS keychain, in memory for a while, or in a plaintext file. Without a helper Git prompts on the terminal every time. ## Practical differences that decide the choice - **Firewalls and proxies.** HTTPS uses port 443 and passes through corporate proxies that block port 22. This is often the deciding factor. - **Container and CI ergonomics.** HTTPS needs one secret in an environment variable and a helper or askpass hook. SSH needs a key file with correct permissions, a known-hosts entry, and usually an agent — more moving parts inside a minimal image. - **Host verification.** SSH verifies the server by its host key against `known_hosts`; a first connection to an unknown host either prompts or, in a non-interactive job, fails. HTTPS verifies the server via the TLS certificate chain, which needs no per-user setup. - **Rotation.** Tokens usually carry an expiry and can be scoped narrowly; SSH keys typically live until someone removes them. ## Mixing them A repository can have several remotes with different transports, and `url.<base>.insteadOf` can rewrite one form into the other globally — handy when a `.gitmodules` file hardcodes SSH URLs but a CI job only has an HTTPS token. `git remote -v` shows what each remote currently uses, and `git remote set-url origin <new>` switches it.

  • What is the difference between git@host:org/repo.git and ssh://git@host/org/repo.git?
    They select the same transport. The first is the scp-like shorthand, where the colon separates host from path and no port can be given. The second is the full URL form, which accepts an explicit port and a leading slash on an absolute path. When a non-default port is involved, the `ssh://` form is required.
  • Why do hosts require a token instead of an account password over HTTPS?
    A token is a separate credential with its own scope and expiry, so it can be limited to specific operations and revoked without touching the account itself. It also survives the interactive login flows an account password is now wrapped in. From Git's point of view nothing changes: the token is simply what goes in the password field.
  • When would you deliberately use the git:// transport?
    Only for anonymous read access to public content where speed matters more than integrity guarantees, such as a public mirror. It is unauthenticated and unencrypted, so anyone on the path can observe or tamper with what you fetch. For anything private, or anything you will build and run, use HTTPS or SSH.

saying these in an interview costs you the question

  • Thinks SSH keys authenticate HTTPS remotes too
  • Says TLS proves who the client is
  • Believes git:// is just HTTPS without a certificate
  • Assumes changing the URL scheme changes the repository
  • Treats a personal access token as the account password

context

open as a page

What does Git's credential.helper do, and how do the store, cache, and keychain helpers differ?

level: middleimportance: must knowfreq 56%

basics

~20 s

credential.helper names a program Git asks for a username and secret before prompting. store writes them in plaintext to ~/.git-credentials, cache keeps them in a short-lived in-memory daemon, and osxkeychain or manager delegate to an OS-backed secure store.

open as a page

A CI job cannot clone a private repository over SSH. How do you diagnose it at the Git level?

level: seniorimportance: must knowfreq 50%

basics

~20 s

Reproduce the exact command with verbose SSH via GIT_SSH_COMMAND="ssh -v", then check in order: which key was offered, whether the agent is reachable, key file permissions and passphrase, the host key in known_hosts, and whether the key has write as well as read access.

open as a page

What does Git's url.<base>.insteadOf config do, and when would you use it?

level: middleimportance: should knowfreq 30%

basics

~20 s

url.<base>.insteadOf rewrites a URL prefix before Git contacts a remote, so any URL starting with the given prefix is transparently replaced. It lets you redirect hardcoded remote or submodule URLs to a transport you actually have credentials for.

open as a page

How do you decide between SSH keys and HTTPS tokens for Git access across many CI jobs and machines?

level: principalimportance: should knowfreq 33%

basics

~20 s

Judge each option on lifetime, scope, how the secret reaches the git process, and what happens when a machine is compromised. Tokens favour short-lived, narrowly scoped, easily rotated automation; keys favour stable identities where port 443 is unavailable or an agent already exists.

open as a page

What is Git's wire protocol v2, and what does it change about fetching?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

Protocol v2 is Git's second-generation transfer protocol. Instead of the server advertising every ref up front, the client requests only the refs it cares about via ls-refs with ref prefixes, which makes fetches on ref-heavy repositories dramatically cheaper.

open as a page