Git over HTTPS
githosted is real Git. Anything git clone, git fetch, git push,
git tag, or any other client-side Git invocation can do, you can
do against githosted.dev. Auth is HTTP Basic with a gw_ /
gr_ token as the password — the SDK and git are two windows
into the same repo.
The recommended local setup: gho auth login
Section titled “The recommended local setup: gho auth login”curl -fsSL https://githosted.sh | shgho auth loginThat’s the whole flow. gho auth login opens your browser,
runs the OAuth dance, stores the token in your OS keychain, and
writes git’s credential-helper config. After that, every
git clone / fetch / push against githosted Just Works:
git clone https://githosted.dev/<ws>/<repo>.gitNo token in the URL. No extraHeader. No prompt. Same UX as
gh auth login + Git Credential Manager.
gho auth logout revokes the token server-side, clears the
keychain entry, and unsets the helper config — fully clean.
Don’t have the CLI? Use the dashboard
Section titled “Don’t have the CLI? Use the dashboard”Open the repo page and click Clone. The dropdown’s HTTPS
tab has a copy-paste setup block that wires git’s
http.extraHeader against githosted.dev. Paste once into
your shell; afterward git clone works the same as the CLI
path above.
The rest of this page is the manual reference for environments without a browser handy — CI runners, scripts, headless terminals, Docker build contexts.
The clone URL
Section titled “The clone URL”https://githosted.dev/<workspace-slug>/<repo-slug>.gitThe workspace slug is the human-readable one you see in the
dashboard URL, not the ws_… ID. Same for the repo slug.
Both
https://githosted.dev/<ws>/<repo>.gitand the longerhttps://api.githosted.dev/git/<ws>/<repo>.gitwork and resolve to the same repo. The shorter apex form is what we recommend and what the dashboard shows; theapi.form is the underlying origin if you ever need to bypass the apex proxy (e.g. debugging).
Authenticate
Section titled “Authenticate”Git uses HTTP Basic for password-based auth. The server doesn’t care about the username — put anything there, or just put the token:
git clone https://gw_xxxx@githosted.dev/<ws>/<repo>.gitThat works. It’s also the wrong way to do it for anything beyond a one-shot clone, because:
- The token ends up in
~/.githosted/<repo>/.git/config(Git stores the URL as-is when you usegit clone <url>). - The token shows up in your shell history.
- Other tools that read
git remote -vsee the token in plain text.
So clone without the token in the URL, and let Git’s credential helper handle the prompt:
git clone https://githosted.dev/<ws>/<repo>.git# Username for 'https://githosted.dev': anything# Password for 'https://anything@githosted.dev': gw_…Once Git asks for credentials and you give the token, the configured credential helper stores it for next time.
Configure a credential helper
Section titled “Configure a credential helper”git config --global credential.helper osxkeychainThe token is stored in the macOS Keychain. Subsequent clones, fetches, and pushes don’t prompt.
Linux (GNOME / KDE)
Section titled “Linux (GNOME / KDE)”git config --global credential.helper libsecretStores the token in the GNOME Keyring or KDE Wallet via the freedesktop Secret Service.
If libsecret isn’t built in, install Git’s libsecret helper:
sudo apt install libsecret-1-0 libsecret-1-devsudo make --directory=/usr/share/doc/git/contrib/credential/libsecretWindows
Section titled “Windows”Git for Windows ships with the manager-core helper out of the box — nothing to configure.
Use a per-host header (alternative)
Section titled “Use a per-host header (alternative)”If you’d rather not use a credential helper at all, set Git’s
http.extraHeader for the githosted host:
git config --global http.https://githosted.dev/.extraHeader \ "Authorization: Bearer gw_xxxx"Now any git clone https://githosted.dev/... call sends an
Authorization: Bearer … header without needing HTTP Basic. This
is what most CI environments end up doing.
CI / GitHub Actions
Section titled “CI / GitHub Actions”In a workflow, the token comes from a secret and gets injected as
an extraHeader for the duration of the job:
- name: Clone githosted repo env: GITHOSTED_TOKEN: ${{ secrets.GITHOSTED_TOKEN }} run: | git -c http.https://githosted.dev/.extraHeader="Authorization: Bearer $GITHOSTED_TOKEN" \ clone https://githosted.dev/<ws>/<repo>.gitOr, if you’re already using the SDK in the same job, skip the
git clone entirely and use repo.read / repo.write against
the same token via GITHOSTED_TOKEN. The SDK is usually the simpler
path inside CI.
Docker build contexts
Section titled “Docker build contexts”The cleanest pattern for a Dockerfile that needs to pull from a githosted repo at build time is BuildKit secrets:
FROM alpine:3RUN apk add --no-cache gitRUN --mount=type=secret,id=githosted_token \ GITHOSTED_TOKEN=$(cat /run/secrets/githosted_token) && \ git -c http.https://githosted.dev/.extraHeader="Authorization: Bearer $GITHOSTED_TOKEN" \ clone https://githosted.dev/<ws>/<repo>.git /srcBuild with:
docker build --secret id=githosted_token,env=GITHOSTED_TOKEN .The token never lands in an image layer.
What works
Section titled “What works”git clone,git fetch,git pull,git push- Branches, tags, lightweight refs
- Annotated tags, commit messages, signatures (GPG / SSH-key signing — the server doesn’t validate the signature, but it preserves the signed commit object)
- Submodules — both directions, as long as both submodule and parent are reachable with the same token / credential helper
git lfs— yes, but treat large binaries as the exception, not the rule. See Concepts → Repos for our take
What doesn’t work yet
Section titled “What doesn’t work yet”- SSH access (
git@…). Planned and coming. Use HTTPS for now. - Anonymous public read. Coming with public repos — see the public-repos plan. Until then every clone needs a token.
- Read-only mirroring with no token. Same — gated until public repos ship.
- Authenticate — picking the right token for the job
- Use githosted in an agent — when an agent and a human both want to push to the same repo
- SDK files API — when you’d rather not shell out to Git at all