Skip to main content
Two transports, one rule: pick by visibility, not by owner. Every repo across the org has exactly one canonical transport. The visibility of the repo decides which.

The rule

The owner (personal account, org, fork) does not matter. A public dryvist repo gets SSH; a private personal repo gets HTTPS. The transport is a property of the repo, not the account.

Why split this way

The two scenarios that drive the rule:

Public repos use SSH because there’s nothing to gate

A public repo’s read path needs no auth (anyone can git clone https://…). The write path is gated by GitHub-side branch protection and ruleset rules rather than client-side credentials. Routing public pushes through SSH:
  • Skips per-command credential lookups entirely.
  • Keeps GitHub token scope completely orthogonal to public writes. Even a read-only token can push to a public repo over SSH, because the SSH key, not the token, is what GitHub authenticates.
  • Works fine on hosts where no token is configured at all (CI runners with deploy keys, for example).

Private repos use HTTPS because the credential lookup gates writes

A private repo’s write path is only gated by client-side credentials. If a private repo used SSH:
  • An unlocked SSH key is always on. It would auto-authenticate to every private repo the user can reach, with no per-repo scope and no record of which tool initiated the push.
  • Any process with read access to ~/.ssh/id_* could push, because SSH is binary “key works” or “key doesn’t.” There is no fine-grained scope on the SSH side.
Private pushes require a credential scoped to the target repository.

Setting the right remote URL

After cloning, check the remote and correct it if wrong:
When in doubt about visibility:

What this does not cover

  • CI authentication. GitHub Actions, deploy keys, and OIDC federation use their own per-job credentials wired into the workflow. The SSH-vs-HTTPS rule is for local developer transports, not CI.
  • Submodules. Treat the submodule URL the same way: public submodule → SSH, private submodule → HTTPS, regardless of how the parent repo is cloned.

What this connects to

Branch conventions

Branch names are transport-agnostic. The conventions are the same on either remote.

PR conventions

PR creation uses the gh CLI. It needs an equivalent scoped token, but reaches it by its own route — see GitHub access.

GitHub authentication docs

Upstream reference on connecting to GitHub over SSH and HTTPS.