# Ephemeral Credentials

A credential whose lifetime is short enough — typically a day or less, often minutes — that it expires before it can spread. The point isn't just "shorter rotation cycle"; it's that there is nothing to rotate. The credential is minted per session, used, and discarded.

## Why this matters

Long-lived credentials accumulate problems linearly in time: people who have seen them, places they've been copied, attempts to guess them, usage against cryptographic limits. Ephemeral credentials reset the clock continuously. A leaked one-hour token is mostly a non-event by the time anyone notices. (See [[long-lived-keys]] for the full failure-mode catalog.)

The other reason: rotation is a process, and processes that aren't exercised rot. Quarterly rotation runbooks tend to be wrong by the time you need them in an emergency. A system that rotates every minute by construction can't have stale rotation tooling.

## How it works

Ephemeral credentials need a *long-lived* trust anchor that mints them. The substitution isn't "no long-lived keys anywhere" — it's "fewer long-lived keys, concentrated in infrastructure that exists to manage them":

- **OIDC federation.** A workload presents a signed identity assertion (from GitHub Actions, AWS IAM, an IdP) to a resource server, which mints a short-lived access token in exchange. The trust anchor is the OIDC issuer's signing key, which is one well-managed long-lived key per issuer instead of one per user/workload.
- **Just-in-time provisioning.** A bastion or control plane checks whether the requester is currently allowed in (via SSO, MFA, ticketed access) and mints a per-session credential. AWS EC2 Instance Connect and SSH certificate authorities work this way.
- **Signed assertions.** SSO replaces per-app passwords with per-login signed assertions from the IdP. The user never has a long-lived secret at the app; the app trusts the IdP signature.

## Examples in practice

- **EC2 Instance Connect** — replaces persistent SSH keys with per-session credentials minted after a fresh authorization check.
- **PyPI / crates.io / NPM Trusted Publishers** — a specific GitHub Actions workflow exchanges its OIDC token for a short-lived publish credential. No stored registry token. Astral's release pipeline is built around this; see [[open-source-security-astral]].
- **SSO assertions** (SAML, OIDC) — per-login signed assertions instead of long-lived per-app passwords.
- **AWS STS / GCP service-account impersonation** — workloads assume a role for a session-bounded credential rather than holding a static key.
- **SSH certificate authorities** — short-validity SSH certs minted by a CA after authentication, instead of long-lived `authorized_keys` entries.

## Limits

The trust anchor remains long-lived. An IdP signing key, an SSH CA key, an OIDC issuer key — these are all credentials whose compromise would be catastrophic. The win is concentration: one or a handful of carefully-managed keys instead of N long-lived keys spread across teams. See [[long-lived-keys]] for the residual-management practices (scope tightly, mathematical lifetime bounds, quarterly rotation, dedicated owners).

## See also

- [[long-lived-keys]] — the case for making this substitution
- [[supply-chain-security]] — the most common context where stored registry tokens are the wrong answer
- [[jwt-for-sessions]] / [[paseto]] — short-lived bearer tokens, related but not the same use case
