Skip to content

Authenticate

Every programmatic call to githosted carries a token. Pick the narrowest one that does the job, hand it to your code via the environment, and rotate it when in doubt. There’s no OAuth flow, no JWT exchange, no “service account” indirection — just a string that starts with gw_ or gr_.

ContextWhat to useWhy
Local laptop, interactivegho auth login (CLI)One-time browser OAuth; CLI stores the token in your OS keychain and wires git’s credential helper for you. git clone / fetch / push work without ever showing you a token.
CI, deploy hooks, scriptsMint a workspace or repo token in the dashboard, expose as GITHOSTED_TOKENNon-interactive: no browser, no keychain. The SDK auto-reads GITHOSTED_TOKEN; git operations use the extraHeader pattern with the same value.
Agent sandbox (Modal, Daytona, E2B…)Mint a short-lived repo-scoped token via client.create_token(...) and inject it into the sandbox as GITHOSTED_TOKENSandboxes get compromised; repo scope + short TTL caps the blast radius. See Sandbox auth for the full pattern with platform examples.
Multi-tenant app / SaaS backendCustomer’s backend holds one workspace token; uses client.create_token(...) to mint a per-tenant or per-session repo-scoped child for downstream agents/jobsSame blast-radius story as sandboxes plus an audit trail per tenant. The customer never hands their gw_ to end-user code.

The decision is rarely about which token — it’s about what runs the code. Once that’s pinned, the token shape and delivery path follow.

Two axes: scope and permission.

TokenSeesReach for it when
Workspace (gw_…)Every repo in the workspace, plus the right to create new reposAn agent or app needs to manage many repos in the same workspace — one repo per session, one repo per tenant, etc.
Repo (gr_…)Specific repos listed when the token was createdA token only needs to touch a known set of repos. Smaller blast radius if it leaks.
PermissionReads (ls, read, log, diff)Writes (write, delete, git push)
readyesno
writeyesyes

Read-only tokens are good for sandboxes that consume a repo but shouldn’t be able to mutate it.

Default rule of thumb: for an agent or app that creates new repos, mint a workspace + write token. For a CI job that only fetches code, mint a repo + read token scoped to the repos it touches.

  1. Sign in at app.githosted.dev.
  2. Click into your workspace from the dashboard.
  3. Click Tokens in the top right.
  4. Click Create Token and fill in:
    • Name — describe where the token will live (ci-deploy, agent-runs-prod, local-dev-laptop). Future-you will want to know which token to revoke when something leaks.
    • KindWorkspace or Repo. If Repo, select the allowlist of repos it can touch.
    • PermissionRead or Write.
    • Expiration — 7 days, 30 days, 90 days, 1 year, or none. Shorter is better. Default to 90 days unless you have a reason to go longer.
  5. Hit Create. The full token value (gw_… or gr_…) appears exactly once — copy it now.

Three ways, in order of preference.

The SDK auto-reads GITHOSTED_TOKEN if you don’t pass anything explicit:

Terminal window
export GITHOSTED_TOKEN=gw_
from githosted import Client
client = Client() # reads GITHOSTED_TOKEN from the environment
import { Client } from "@githosted/sdk";
const client = new Client(); // reads GITHOSTED_TOKEN from process.env

This is the right shape for CI, Docker containers, agent sandboxes, serverless runtimes — anywhere a deploy mechanism already injects secrets via the environment.

Useful when you’re juggling multiple workspaces or testing a different token without messing up your shell:

client = Client(token="gw_…")
const client = new Client({ token: "gw_…" });

Don’t hard-code the literal value into checked-in code. Read it from a config file, a secrets manager, or .env.

3. Credentials file (Python only, for laptops)

Section titled “3. Credentials file (Python only, for laptops)”

The Python SDK looks at ~/.githosted/credentials if GITHOSTED_TOKEN isn’t set:

[default]
token = gw_…

Convenient for ad-hoc scripts on your laptop. Don’t commit it.

SurfaceWhere the token lives
Local laptopOS credential helper (macOS Keychain, Linux libsecret, Windows Credential Manager) — don’t check it into a repo, don’t leave it in shell history
GitHub ActionsRepository / organization secret, exposed as GITHOSTED_TOKEN to the job
Vercel / Cloudflare WorkersProject environment variable named GITHOSTED_TOKEN
AWS Lambda / ECSSecrets Manager → injected at runtime via the task / function definition
Agent sandbox (Modal, Daytona, E2B…)The sandbox’s own secrets primitive, exposed as GITHOSTED_TOKEN to the running code. See Sandbox auth

Whichever path: the token value should never be in a Git commit, a log line, or a chat message. The SDK never logs the token; we recommend redacting it in your own logs too.

The next API call returns unauthenticated (HTTP 401) with a machine-readable error class indicating expiry. The SDK raises AuthenticationError (Python) or AuthError (TypeScript) — wrap the call site if you want to recover gracefully.

Tokens stop working at the second they expire. There’s no grace window. Mint a new one before the old one’s deadline if you’re running long-lived agents.

If you suspect a token has leaked — committed by mistake, posted in chat, or sitting on an old laptop — revoke it from the dashboard immediately. Tokens → … → Revoke flips the token’s status server-side; the next call using it returns unauthenticated within seconds.

Server-side, every token is stored as HMAC-SHA256(server_pepper, token) — we cannot recover the original value, only verify it. So a “forgot the value” recovery path doesn’t exist; it’s revoke and re-create.

For tokens that live in production (CI, deployed services), pick a TTL that matches your rotation cadence:

  • 30 days for sensitive write tokens that touch production data
  • 90 days for typical workspace tokens
  • 1 year for read-only tokens

The SDK doesn’t block you from going beyond a year; we just don’t recommend it. Tokens with no expiry are an anti-pattern that the operator dashboard flags.