Expand description
Credential provisioning for the CLI wrappers.
Remote operations (a forge API call, a git/jj fetch or push against an
authenticated remote) need a secret the toolkit deliberately does not
store. By default every backend authenticates through its CLI’s own ambient
credential system (gh/glab logins, git credential helpers, the SSH agent)
— the toolkit holds nothing. This module adds an opt-in seam for callers
that want to supply a secret per operation instead: a CI job minting a
short-lived token, an agent acting for different accounts, a vault-backed
rotation. You implement (or pick a built-in) CredentialProvider; the
backend resolves it just-in-time and injects the secret through the relevant
CLI’s native non-interactive mechanism — never persisting it.
How the secret reaches each CLI (chosen so the value never lands in argv,
which is broadly observable; only an env-var name or a token value in the
process environment is used):
- GitHub (
gh) →GH_TOKENenvironment variable. - GitLab (
glab) →GITLAB_TOKENenvironment variable. - git (
fetch/push/clone) → an inlinecredential.helperthat emits the secret read from an environment variable by name (seegit_credential_helper); the secret value is never an argument. - Gitea (
tea) and Jujutsu (jj) — no per-operation injection:teaauthenticates only from its stored logins, andjj’s in-process git backend offers no per-invocation credential override. Both stay on ambient auth.
Secrets are wrapped in Secret, which redacts itself in Debug/Display
so a stray log line can’t leak a token. (It does not securely zero memory
on drop — that is out of scope; rely on OS-level protections for that.)
Structs§
- Credential
- A resolved credential: a
Secretplus an optional username. For a forge token only the secret is used; for git HTTPS the username pairs with the secret as the password (a personal-access token). - Credential
Request - The context of a credential request: which service, and the remote host if
the backend knows it (forge calls often defer host resolution to the CLI, so
hostis frequentlyNone).#[non_exhaustive]: more context may be added. - EnvToken
- A provider that reads a bare token from a named environment variable, at
request time. If the variable is unset/empty it yields
None(fall back to ambient auth) rather than erroring — handy for “use$MY_TOKENif present”. - FnProvider
- A
CredentialProviderbacked by a synchronous closure (seeprovider_fn). - GitCredential
Helper - The pieces needed to authenticate a
gitHTTPS operation with aCredentialwithout putting the secret inargv. Seegit_credential_helper. - Secret
- A secret value — an API token, a password — that redacts itself whenever
it is formatted, so it can’t leak into a log line or an error message. Read
the underlying value only at the point of use, via
expose. - Static
Credential - A provider that always yields the same
Credentialfor every request — the common “use this one token” case.
Enums§
- Credential
Service - Which backend/tool is asking for a credential — lets a provider return
different secrets per service.
#[non_exhaustive]: new backends may be added.
Traits§
- Credential
Provider - Supplies a
Credentialfor aCredentialRequest, just-in-time. ReturningOk(None)means “I have nothing for this request” — the backend then falls back to its ambient CLI auth, exactly as if no provider were configured.
Functions§
- git_
credential_ helper - Build a git
credential.helperinvocation that suppliescredover HTTPS while keeping the secret out ofargv(which is broadly observable). The returnedconfig_argsinstall an inline helper that prints the credential read from two environment variables; the secret value appears only inenv, i.e. the child process environment. A leading emptycredential.helper=first clears any inherited helper so only ours runs. - https_
host - Extract the
host[:port]from an HTTPS git URL (https://[user[:pass]@]host[:port]/…), verbatim — original case and port preserved — to scope a credential helper to the host an operation targets. git carries the samehost[:port]in its credential request and compares it byte-for-byte, so normalizing here would withhold a legitimate credential. ReturnsNonefor a non-HTTPS URL (an SSH remote never invokes the HTTPS credential helper, so gating it is moot), an IPv6-literal authority, or an unparseable one — in which case the helper stays ungated, no worse than before host scoping existed. - provider_
fn - Adapt a synchronous closure into a
CredentialProvider. The closure runs at request time and returns the credential (orNoneto defer to ambient auth). For async sources (a network vault), implementCredentialProviderdirectly.