Build1 distinct publisher3 min readPublished
One practitioner's account of moving three Jenkins fleets onto AssumeRoleWithWebIdentity lists the same mistakes every time, and two of them leave the build lights green.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The enforcement in this model does not sit in the Jenkins plugin. Registering Jenkins as an IAM OIDC identity provider is a one-time job per AWS account, and AWS fetches and caches the JWKS thumbprint from the discovery URL at that moment [13]. After that, everything deciding which pipeline can reach which account lives in each role's trust policy. Hence the author's rule: pin `sub` to a concrete job path and `aud` to the exact identifier the plugin issues, with `StringEquals` rather than `StringLike` anywhere near production [14]. His published example pins `sub` to `repo:my-org/infra:ref:refs/heads/main` and `aud` to `sts.amazonaws.com` [15].
Sort the four documented failure modes by what an operator actually notices [17]. Two of them turn pipelines red, including the case that gives no error at registration time: AWS has to reach Jenkins over valid public HTTPS to fetch the discovery and JWKS documents, so an internal-only instance or a self-signed cert fails token validation quietly and only surfaces when a job first tries to assume a role [12]. Red pipelines get diagnosed, eventually. The other two, a trust policy wildcarded across the org and a single shared role covering both lint and deploy jobs, produce successful builds with more authority than the job needs [8][11][18]. Nothing in Jenkins complains, and unlike a static key there is no rotation ticket that periodically drags the grant back into view [1].
That is the part of the migration worth pricing. A static access key is indifferent to where Jenkins lives; it keeps working from anywhere until someone revokes it by hand [4]. A trust policy keyed to an issuer hostname is not indifferent at all: a new load balancer, a new domain, or a rebuilt box with a fresh cert changes the discovery URL and the JWKS endpoint, and the policies pinned to the old issuer stop matching [10]. You are trading an unbounded credential lifetime for a hard dependency on Jenkins keeping its public HTTPS identity stable [12]. That dependency is cheaper, but it is owned by whoever manages DNS and certs, not by whoever wrote the IAM policy.
The compensation is at rest. Jenkins holds no AWS credential in the model; it generates a signed assertion at runtime and AWS validates it against the trust policy before issuing anything [6][2]. A leaked token is short-lived and bound to a subject claim, so it expires whether or not anybody noticed [5]. A leaked key does neither [4].
One caveat on the evidence. The enumeration comes from a single migrator describing three Jenkins fleets, not a survey, and he says the mistake pattern was consistent across teams [7]. The two items you can verify against your own setup before shipping are whether the `aud` your plugin issues matches the string in the trust condition exactly [14] and whether your discovery endpoint resolves and presents a valid certificate from outside your network [12]. Neither check requires believing his sample.
Ranked by verification strength, evidence, and original report placement.
An OIDC token is short-lived, tied to a specific subject claim, and expires on its own even if nobody notices a leak.
In this model Jenkins does not store an AWS credential at rest; it generates a signed assertion at runtime that AWS validates against a trust policy before issuing anything.
The source describes every static AWS key in a Jenkins credential store as working from anywhere, forever, until someone remembers to rotate it, which the author says is rare.
Jenkins, via an OIDC-capable plugin or custom step, mints a signed JWT describing the job (repo, branch, build ID, configurable claims), and AssumeRoleWithWebIdentity exchanges that token for temporary credentials.
AWS STS accepts the token because the Jenkins issuer URL has been registered as a trusted OIDC provider and will only accept tokens matching specific claim conditions.
A static key is a bearer credential with no expiry, no scoping to a specific pipeline, and no cryptographic proof of who is asking; if it leaks it works everywhere until manually revoked.
Follow any of these and your For You feed starts watching them — no settings page required.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
One self-reported practitioner account, concrete config, no corroboration
The mechanism and configuration claims are specific and independently checkable in principle — a named STS API, a printed IAM trust policy with StringEquals conditions on aud and sub, a Federated oidc-provider ARN, and a pipeline stage. But the cluster contains a single article from a single publisher, the failure-frequency and three-fleet migration claims are first-person and unverifiable, no plugin name or version is given, and no external documentation, incident report or test result is cited.
No adoption signal in the cluster
The source reports no release, deployment count, benchmark, usage disclosure, pricing or licence event. The only usage datum is the author's own claim of three unnamed Jenkins fleets, which is neither dated nor quantified, so no adoption level can be measured without inferring facts the source does not supply.
Mostly self-limiting, with one overstated security framing
The piece is unusually restrained for the genre — most of its length is spent on how the pattern fails rather than on why it wins — so the gap is small. It tips slightly positive because the absolute framings ('no secret ever crosses the wire', 'nothing to steal because nothing was ever stored') are not reconciled with its own example writing assume-role output to creds.json in the job workspace, and because the claim that the mistake pattern is 'remarkably consistent across teams' generalises from three unnamed migrations.
Personal-brand cross-post, no disclosed vendor or product stake
The article states it was originally published on the author's own site and is republished under his byline on a developer community platform, so the visible incentive is reputational and audience-building. No product, service, sponsorship, employer or affiliate relationship is disclosed, and nothing being sold depends on the conclusions; the guidance points at first-party AWS and Jenkins capabilities rather than a commercial offering.
Moderate on mechanism, low on prevalence
Confidence is bounded by single-source, single-publisher coverage with no independent verification and a truncated body. It is not lower because the technical claims are internally consistent, operationally specific and framed as attributable practitioner experience rather than as measurement, and because the four failure modes are described in enough detail to be checked by any team running the migration.
build
Two Actions, One Loose Policy: The Bedrock Wildcards That Widen A Least-Privilege Grant1 distinct publisher
build
GuardDuty says exfiltration and the patch is four hours out: revoke the sessions first1 distinct publisher
build
Dropping long-lived AWS keys is half an EKS migration; the cluster still gets a vote1 distinct publisher
product
One unvalidated region string sent signed AWS API calls to attacker.com1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 27, 2026