Skip to main content

Module credentials

Module credentials 

Source
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_TOKEN environment variable.
  • GitLab (glab) → GITLAB_TOKEN environment variable.
  • git (fetch/push/clone) → an inline credential.helper that emits the secret read from an environment variable by name (see git_credential_helper); the secret value is never an argument.
  • Gitea (tea) and Jujutsu (jj) — no per-operation injection: tea authenticates only from its stored logins, and jj’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 Secret plus 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).
CredentialRequest
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 host is frequently None). #[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_TOKEN if present”.
FnProvider
A CredentialProvider backed by a synchronous closure (see provider_fn).
GitCredentialHelper
The pieces needed to authenticate a git HTTPS operation with a Credential without putting the secret in argv. See git_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.
StaticCredential
A provider that always yields the same Credential for every request — the common “use this one token” case.

Enums§

CredentialService
Which backend/tool is asking for a credential — lets a provider return different secrets per service. #[non_exhaustive]: new backends may be added.

Traits§

CredentialProvider
Supplies a Credential for a CredentialRequest, just-in-time. Returning Ok(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.helper invocation that supplies cred over HTTPS while keeping the secret out of argv (which is broadly observable). The returned config_args install an inline helper that prints the credential read from two environment variables; the secret value appears only in env, i.e. the child process environment. A leading empty credential.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 same host[:port] in its credential request and compares it byte-for-byte, so normalizing here would withhold a legitimate credential. Returns None for 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 (or None to defer to ambient auth). For async sources (a network vault), implement CredentialProvider directly.