Expand description
What to present to a git host, and where it comes from.
Every host in this crate’s remit speaks git, and git has exactly two places
a credential can go: the HTTP Authorization header, or the ssh process
that carries the stream. Auth is those two, plus the absence of both.
§The credential is a callable, not a string
A store that takes token: String at construction works in a demo and
fails at three in the morning on the first refresh. A GitHub App
installation token lives one hour; a workload-identity token exchanged for
a provider token lives minutes; a watcher lives for the life of the
process. So Credential is a function, called per fetch, and the three
shapes it comes in are the three lifetimes a real credential has:
| Constructor | Called | For |
|---|---|---|
Credential::token, basic, ssh_agent, ssh_key, anonymous | once | a value that cannot change |
Credential::from_fn | every fetch | a value read from somewhere that can change — an environment variable, a file a sidecar rewrites |
Credential::expiring | when it is about to expire | a value the issuer stamped a lifetime on |
Credential::expiring is the one the item exists for. It is handed to
Cached, the same machinery Vault, Consul and Firestore use: obtained
once, reused until it is within
REFRESH_WITHIN of
expiry, refreshed under one lock so eight threads produce one exchange, and
thrown away the moment the host refuses it so the next fetch obtains a new
one. None of that is re-derived here.
§What is deliberately not here
The GitHub App JWT-to-installation-token exchange. It is two steps — sign
an RS256 JWT with the app’s private key, POST /app/installations/{id}/access_tokens — and both belong in the caller’s
closure. Signing needs an RSA implementation, and the pure-Rust one carries
an unpatched timing-sidechannel advisory that this workspace’s cargo deny
gate rejects; a program that already talks to GitHub almost certainly has a
client that does the exchange. What this crate owes that flow is the
refresh, and that is Credential::expiring.
An SSH key passphrase. ssh has no way to accept one that does not put
it on a command line, where ps can read it, or in a file this crate would
have to write. A passphrase-protected key is therefore used through an
agent — ssh-add it once — which is what an agent is for. Taking a
passphrase parameter and then leaking it would be worse than not taking one.
Structs§
- Credential
- Where an
Authcomes from, and how long it lasts.