The question this answers
Why is a short-lived role credential a fundamentally different security object from a long-lived access key?
The deploy pipeline and the payments service both need cloud permissions. Neither should hold a credential that outlives the job or the pod, and neither should have a secret stored anywhere a scanner could find it in a repository three years from now.
Credentials that are minted on demand from an attestation, scoped to one role, valid for minutes, renewed automatically, and revocable by revoking the role rather than by hunting for copies.
Two credentials, two very different incidents
A static access key is a pair of strings with no expiry. It works from anywhere, forever, until a human notices and deletes it. Because it is just text, it propagates: into a .env, a CI variable, a Slack message during onboarding, a Docker image layer, a laptop backup, a git log entry that survives the file being deleted. You cannot enumerate its copies, which means you can never say it is contained — only that you revoked the one you know about.
A role credential is minted on demand. The workload proves what it is — instance metadata, a projected service-account token, a signed CI assertion — and receives a token valid for minutes, automatically renewed while the workload runs. There is nothing to store, so there is nothing to copy. When the pod dies, the credential dies with it.
Put the two leaks next to each other. A one-hour token posted publicly is bad: an attacker has an hour, scoped to that role, from an origin your condition may already exclude. You revoke the role, you read the audit trail for a bounded window, and the incident has an end. A static key posted publicly is a different category of event: it may have been valid for two years already, you cannot tell which copy leaked, you have no upper bound on how long it was in use, and rotating it means finding every system that references it — which is exactly the inventory you do not have, which is why the rotation gets postponed.
This is the actual argument, and it is not "short-lived is more secure" in the abstract. It is that a short-lived credential makes an incident *boundable*, and boundability is what determines whether a security event is a Tuesday or a quarter.
- 1Attest< 10 ms
The platform vouches for the workload: instance metadata, a projected service-account token with an audience, or a signed assertion from the CI provider.
A metadata endpoint reachable through an SSRF bug lets an attacker start this flow from your application. Require the session-token protection.
- 2Exchange~50 ms
The identity service validates the attestation against a trust policy — which cluster, which service account, which repository and branch — and issues credentials for the role.
A trust policy that accepts any repository from the CI provider lets a stranger's pipeline assume your role. This is a real and recurring misconfiguration.
- 3Useminutes
The SDK signs API calls with the short-lived credential. The audit trail records the role and the attested source.
Code that reads the credential once at startup and caches it forever will fail after expiry in a way that looks like an outage.
- 4Renewautomatic
The SDK re-exchanges before expiry, transparently. No human action, no rotation ticket.
A long-running job whose credential provider is not wired for renewal fails mid-run — the classic overnight-batch failure.
- 5Expire15–60 min typical
The credential stops working. A copy taken by an attacker stops working at the same moment.
None — this is the property you bought.
- 6Revokeseconds
Detach or delete the role. Every future exchange fails, for every workload using it, immediately.
Revoking a shared role affects every workload on it, which is one more reason not to share roles.
Where each kind of workload gets its attestation
The mechanism differs by workload kind, and knowing which one applies is most of the implementation work. All four remove a stored secret.
A virtual machine queries a link-local metadata address and receives credentials for the role attached to the instance. A container in an orchestrator presents a projected, audience-scoped service-account token that a cloud identity provider validates and exchanges. A serverless function is handed its execution role's credentials by the platform at invocation. A CI pipeline federates: the provider signs an assertion describing the repository, the workflow and the branch, and your trust policy decides whether that specific combination may assume the role.
The CI case deserves the extra sentence, because it is where the highest-value long-lived keys used to live and where the trust policy is easiest to get wrong. A trust policy that checks only "this assertion came from the CI provider" will happily accept an assertion from any repository on that provider — including one an attacker created five minutes ago. The subject must be pinned to your organization, your repository, and usually your branch or environment.
Not everything can be a role. A third-party API key, a partner's credential, a database password where the provider offers no identity integration — those are genuinely static secrets and they belong in a secret manager with rotation and audit (Secrets in Infrastructure). The goal is not zero secrets; it is that the set of static secrets is small, deliberate and inventoried, rather than "wherever a key happened to be needed".
The trust policy is the half everyone forgets
A role has two policies and they answer different questions. The permission policy says what the role may do — this is what Anatomy of a Policy teaches. The trust policy says who may become the role, and it is the one that gets written once, copied from a blog post, and never reviewed.
That asymmetry matters because a perfect permission policy on a role anyone can assume is worth nothing. The panel below shows the shape that actually protects you: the subject is pinned to one repository and one branch, so an assertion from any other repository — including a fork, and including a completely unrelated project on the same CI provider — fails the exchange.
The practical review rule: for every role, read the trust policy first and ask *who, exactly, can become this*. If the answer contains a provider name and no organization, repository or cluster identifier, the role is assumable by strangers and the permission policy is decoration.
- federated assertions where issuer = our CI provider
- AND subject = org/our-repo:ref:refs/heads/main
- AND audience = our cloud account
- session duration: 15 minutes
- the deploy workflow on the main branch of our own repository, during a run
- any other repository on the same CI provider, including forks
- any branch other than main
- any long-lived key for this role — none exists to leak
Blast radius: To use this role an attacker must be able to make our CI provider issue an assertion for our repository's main branch — which means compromising the repository or the pipeline, at which point they have easier paths anyway. There is no stored credential to steal, and any session they do obtain dies in fifteen minutes.
Key points
- A static key has no expiry and no enumerable copy set, so an incident involving one has no upper bound and no clean containment.
- A role credential is minted from an attestation, lives for minutes, renews automatically and is never stored — so there is nothing to leak.
- The security argument is boundability: a short-lived credential turns an unbounded event into one with a start, an end and a scope.
- Every workload kind has an attestation path — instance metadata, projected token, execution role, CI federation.
- A role has two policies. The trust policy says who may assume it, and it is the one nobody reviews.
- Some secrets genuinely cannot be roles. Keep that set small, deliberate and inventoried in a secret manager.
The loop, answered
Every field is required, which is why no lesson here can recommend something without saying what it costs and what simpler thing to consider first.
- • The platform attests to the workload's identity without any secret being stored by the workload.
- • The identity service validates the attestation against the role's trust policy — issuer, subject, audience, and any extra conditions.
- • It issues credentials for the role with a short expiry, typically fifteen to sixty minutes.
- • The SDK signs API calls with them and re-exchanges transparently before expiry.
- • Revocation is detaching or deleting the role, which invalidates every future exchange immediately rather than requiring copies to be found.
- • Own the trust policies, and review them with the same seriousness as permission policies. Pin the subject.
- • Own the elimination programme for existing static keys: inventory, replace, then delete — deletion is the step that gets skipped.
- • Own credential-renewal correctness in long-running jobs, which is where short-lived credentials actually cause outages.
- • Own the small inventory of secrets that genuinely cannot be roles, with rotation and audit for each.
- • Own a repository and pipeline scanner that fails the build on a committed key, because the fastest wrong thing must be blocked mechanically.
- • A long-running job failing partway through because its credential expired and nothing renewed it — the classic overnight-batch incident.
- • A trust policy that accepts any repository from a CI provider, allowing a stranger's pipeline to assume your deploy role.
- • A static key committed to a repository and found by a scanner minutes later, already in use by someone else.
- • A key rotation breaking four services that copied it rather than referencing it, because nobody had the inventory.
- • Credentials cached at process start and never refreshed, producing an outage exactly one expiry period after every deploy.
- • An SSRF bug reaching the metadata endpoint and exfiltrating role credentials — short-lived, but long enough.
- • Role count grows with workloads, and that is correct; sharing roles to keep the count down merges blast radii and breaks revocation.
- • Credential exchange is a per-workload, per-refresh call — cheap, but it is a dependency, and a token-service outage is felt by everything at once.
- • Federation scales best for CI because it removes one stored secret per pipeline instead of adding one.
- • What runs out first is trust-policy review attention, since trust policies are written once and read never.
- • Short lifetime bounds exposure; the attestation requirement means an attacker needs a position inside your platform, not just a string.
- • Pin the trust policy subject to your organization, repository, cluster or namespace. An unpinned trust policy is the whole vulnerability.
- • Harden the metadata endpoint — require its session-token protection — because SSRF is the standard route to role credentials.
- • Prefer per-workload roles so revocation is surgical; a shared role means revoking it takes down everything on it.
- • Where a static secret is unavoidable, put it in a secret manager with rotation and audit, and treat its existence as a tracked exception. See Secrets in Infrastructure and The Secret Lifecycle.
- • Roles and credential exchange are effectively free; the cost is the engineering work to wire attestation per workload kind.
- • It removes recurring cost: no rotation projects, no secret-sprawl inventory, no incident response for a key found in a repository.
- • The unpriced cost of static keys is the incident with no upper bound — the one where you cannot say when the exposure began.
- • A modest real cost: more roles to name and own, and trust policies that must be maintained as repositories and clusters change.
- • Existence and age of every long-lived key. Any key older than your rotation policy is a finding, and the count should trend to zero.
- • Role assumption events with their attested source — a role assumed from an unexpected repository or address is the alert that matters.
- • Credential-expiry-related errors in long-running jobs, which is where this design actually breaks.
- • Trust policy changes, as first-class events. Widening who may assume a role is a bigger change than widening what it may do.
- • The signal that lies: successful deploys. They succeed identically with a pinned trust policy and with one any stranger can satisfy.
- • A secret manager holding a static key with automated rotation, where no identity integration exists. Second best, legitimate, and much better than an environment variable.
- • A static key with a strict network condition, when the workload is somewhere no attestation mechanism reaches — the condition restores some of the boundability.
- • Keep the static key for a short, dated migration window while roles are wired up, with a ticket and an owner. Explicitly temporary beats indefinitely postponed.
- • For a personal project with one developer and no production data, a scoped personal key is a reasonable, deliberate simplification.
- • Buys bounded exposure and surgical revocation; costs per-workload wiring and a class of expiry-related failures you have to design for.
- • Buys the removal of the secret; costs a dependency on the token service and the metadata endpoint being available and hardened.
- • Per-workload roles buy precise revocation; they cost more roles and more trust policies to maintain.
- • Federation buys the elimination of CI secrets; it costs a trust policy that is genuinely easy to write dangerously wrong.
What people believe, and what is true
A key in a secret manager is as good as a role.
Better than an environment variable, and still a credential with no expiry that can be copied out. The role has nothing to copy.
Short-lived credentials mean the application must handle rotation.
The SDK handles it. What the application must handle is not caching a credential forever, which is a one-line concern.
The permission policy is the important one.
A perfect permission policy on a role anyone can assume protects nothing. Read the trust policy first.