Present a token as a Git credential
git-credential-tovio.
Written By Dustin
Last updated 15 minutes ago
When a Git client talks to a Forge over smart-HTTP, it needs a credential. The git-credential-tovio helper presents a capability token as one. It is a separate binary because Git discovers helpers by the exact name git-credential-<name> on the PATH.
Wire it up
tovio git setup <host> seals a token in your OS keychain for that host and points Git's credential machinery at the helper. It reads the token from standard input only — never as a command argument — and refuses a terminal outright, so the token can never land in your shell history.
Get the token material with tovio agent token and pipe it in. Its --json form is the one to script against, because the human form prints a second informational line after the token:
tovio agent token cap_7f… --json \ | jq -j .result.token_material \ | tovio git setup forge.example.comAdd --local to write the configuration to one repository instead of your global Git config. If the helper is not on your PATH, git setup tells you.
Or by hand
git config --global credential.https://forge.example.com.helper tovioWhat it answers with
The username is the fixed placeholder tovio-token and the password is the capability token. The username only has to be non-empty; naming it explicitly makes a GIT_TRACE log readable.
What it refuses to do
storeanderasedo nothing. Git offers a helper the password it just used; writing it anywhere else would copy a scoped, expiring token into a second place that then has to be revoked separately.- HTTPS only, and exact host matching — a host with no sealed slot yields no token and the helper simply declines, so Git moves on to the next helper.
- An operation it does not recognise exits zero with no output. Git adds credential operations over releases, and a helper that fails on an unfamiliar one would break the credential chain for every host on the machine, not just for TOVIO.
The headless path
For CI and containers, set TOVIO_CREDENTIAL_TOKEN and optionally a comma-separated TOVIO_CREDENTIAL_HOSTS. When set, the environment is authoritative and the keychain is not consulted. Exact-host matching and the HTTPS rule still apply.
Prefer workload identity where you have it — an OIDC exchange for a short-lived session, with nothing durable stored. Use a token as a Git credential when OIDC is not available.
Why this rather than a password
- A capability token is scoped — paths, operations, expiry — where a password is not.
- It can be revoked immediately, along with anything delegated from it.
- Its use is recorded in the audit chain.
Scope it for the job
tovio agent new ci-reader --model ci-runner --task "build" --expires-in 4--expires-in is a number of hours, not a duration string — 4, not 4h. It defaults to 24 and is required by construction: there is no non-expiring token.
What Git can and cannot do
Clone, fetch, and push are all served over the materialized Git view. Two limits are worth knowing before you point CI at it:
- Reads are policy-filtered, and membership fails closed — a non-member or unauthenticated client receives an empty ref advertisement rather than a filtered one, so ref names do not leak.
- Pushes are limited to clear paths. A Git client cannot write a protected path, because it cannot perform the encryption that path requires. A protected-path push is refused, not silently dropped.