Skip to content

BuildNot yet confirmed elsewhere1 publisher3 min readPublished

Jenkins static AWS keys work from anywhere; the OIDC replacement fails in four known ways

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

How we use AISend a correction

Illustration accompanying Jenkins static AWS keys work from anywhere; the OIDC replacement fails in four known ways
Generated illustration

What happened

  • A practitioner write-up sets out how Jenkins mints a signed JWT describing the job and exchanges it for temporary AWS credentials through AssumeRoleWithWebIdentity.
  • The author says he has moved three separate Jenkins fleets off static IAM users and found the same mistakes each time.
  • The most common one: trust conditioned only on aud, or sub wildcarded as repo:my-org/*:*, so any job in any repo can assume the production deploy role.
  • Another: a single shared IAM role, giving read-only lint jobs the same permissions as the deploy job.
  • A third: policies pinned to an issuer URL that changes when Jenkins moves, which surfaces as opaque AccessDenied errors on AssumeRoleWithWebIdentity.

Why it matters

  • constraint IAM authorisation now depends on Jenkins keeping its hostname and certificate, so DNS and load balancer work becomes access-control work owned by a different team.
  • exposure A wildcarded sub keeps the org-wide reach of the old key while removing the rotation task that used to bring that reach back to someone's attention.
  • capability With nothing stored at rest, a stolen Jenkins disk or backup no longer yields a usable AWS grant, which changes what a host compromise is worth.
  • decision Role-per-job versus one shared role has to be settled before the first pipeline ships, because the shared version works fine and therefore never prompts a revisit.

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 [12]. 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 [13]. His published example pins `sub` to `repo:my-org/infra:ref:refs/heads/main` and `aud` to `sts.amazonaws.com` [14].

Sort the four documented failure modes by what an operator actually notices [16]. 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 [11]. 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 [7][10][17]. Nothing in Jenkins complains, and unlike a static key there is no rotation ticket that periodically drags the grant back into view [3].

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 [6]. 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 [9]. You are trading an unbounded credential lifetime for a hard dependency on Jenkins keeping its public HTTPS identity stable [11]. 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 [2][4]. A leaked token is short-lived and bound to a subject claim, so it expires whether or not anybody noticed [1]. A leaked key does neither [6].

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 [18]. 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 [13] and whether your discovery endpoint resolves and presents a valid certificate from outside your network [11]. Neither check requires believing his sample.

What to watch

  • Whether a second practitioner reports the same four failure modes, since the enumeration currently rests on one migrator's three fleets.
  • Any change to how AWS caches the JWKS thumbprint at provider registration, which is the mechanism that makes an issuer host change silent.
  • Whether the aud value the Jenkins OIDC plugin issues stays stable across plugin upgrades, given that the recommended trust policies pin it with StringEquals.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence38
Adoption
Insufficient
Hype gap+12
Incentives28
Confidence44
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    An OIDC token is short-lived, tied to a specific subject claim, and expires on its own even if nobody notices a leak.

  2. [2]

    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.

  3. [3]

    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.

    ReportedSupportedSource: dev.to post by Oleksandr Kuryzhev, originally published on kuryzhev.cloudView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · August 27, 2026

    Setting Up Jenkins AWS OIDC Authentication to Replace Static Keys

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Loading related stories