Why credctl federates via OIDC instead of IAM Roles Anywhere
Both AWS OIDC federation and IAM Roles Anywhere can give a workload outside AWS short-lived AWS credentials. It’s the most common design question about credctl’s architecture — and the reasons to pick one over the other aren’t widely written up.
Here’s what credctl settled on, why — and importantly, when you’d actually pick Roles Anywhere instead. (For the reference-style comparison of how each mechanism works, see the OIDC vs Roles Anywhere guide — this post is the decision narrative.)
The two paths in plain terms
Section titled “The two paths in plain terms”OIDC federation (sts:AssumeRoleWithWebIdentity). Your workload produces a signed JWT containing its identity. The signature is verifiable against a JWKS endpoint you host. AWS IAM trusts a specific OIDC provider (identified by JWKS URL + issuer + audience). When the workload calls STS with the JWT, STS fetches the JWKS, validates the signature, checks the claims against the role’s trust policy, and returns temporary credentials. This is the path GitHub Actions, Kubernetes (via IRSA), and most modern CI/CD systems use to authenticate to AWS without long-lived access keys.
IAM Roles Anywhere. Your workload presents an X.509 client certificate signed by a CA. AWS Roles Anywhere has a “trust anchor” pointing at that CA, plus a “profile” describing which IAM roles the cert is allowed to assume. The workload calls Roles Anywhere’s CreateSession endpoint with the cert and a signed challenge, gets temporary credentials back, and uses those against AWS. Roles Anywhere validates the cert chain against the trust anchor and the profile policies before issuing.
Both deliver the same end state: short-lived AWS credentials issued to a non-AWS workload, without anyone holding a long-lived access key. The difference is in what proves identity — a JWT signed by a key, or an X.509 cert.
credctl’s specific constraints
Section titled “credctl’s specific constraints”credctl is a CLI that runs on a developer’s laptop and authenticates to AWS using a hardware-bound key — Secure Enclave on macOS, TPM 2.0 on Linux. The key never leaves the chip. The key signs something that AWS validates, and AWS returns STS credentials.
That “something” is the question. It can be:
- A JWT signed by the hardware key (OIDC path)
- An X.509 challenge signed by the hardware key (Roles Anywhere path)
Both are technically achievable. Secure Enclave and TPM 2.0 both hold ECDSA P-256 keys and produce ECDSA signatures over arbitrary payloads.
But credctl had two other constraints that mattered for the choice:
- We want the same auth flow to work across AWS, GCP, and Azure. A developer’s laptop should authenticate to whichever cloud their workload runs in — without per-cloud cert lifecycle management. The same hardware key, the same identity, three clouds.
- We want zero customer-side infrastructure beyond the IAM trust setup. No CA to operate. No cert rotation. No revocation list to keep current.
Both push hard toward OIDC.
Why OIDC won for credctl
Section titled “Why OIDC won for credctl”Multi-cloud portability. AWS OIDC federation, GCP Workload Identity Federation, and Azure Federated Identity Credentials all accept the same JWT format — signed with ES256, standard iss/sub/aud/exp/iat claims, JWKS discoverable via /.well-known/openid-configuration. Different endpoints (AssumeRoleWithWebIdentity on AWS, the WIF token exchange on GCP, FIC on Azure), but the underlying protocol is interoperable. One identity, three clouds. Roles Anywhere is AWS-only — for the same workload identity on GCP we’d need WIF anyway, so we’d be operating two parallel systems.
No customer-side PKI. Roles Anywhere requires the customer to operate a CA that issues client certs to their workloads. Even with public CAs and ACM Private CA, this is a real ongoing operational burden: cert rotation, revocation lists (CRLs or OCSP), CA renewal. For credctl’s “install the CLI and federate” experience, asking customers to run a CA before they can authenticate is a non-starter. OIDC requires hosting a JWKS file (a few hundred bytes of JSON behind a CDN) and registering the OIDC provider in IAM once. That’s it.
Mature ecosystem. OIDC is the cloud auth lingua franca for non-cloud workloads. GitHub Actions, Kubernetes service accounts, CI/CD runners, and SPIFFE all federate via OIDC. We can lean on documented patterns, well-tested IAM examples, and developer familiarity. Roles Anywhere is younger and the ecosystem of examples — especially for “laptop CLI” rather than “server workload” — is thinner.
Richer claims structure. JWTs carry arbitrary claims. credctl can put device identifiers, attestation data, or future attributes into the sub and standard claims without changing the underlying protocol. X.509 cert SANs and extensions can do something similar but less flexibly, and modifications usually mean cert re-issuance.
Existing audit story. AWS CloudTrail records the JWT’s sub claim on every AssumeRoleWithWebIdentity call. Roles Anywhere logs a CreateSession event with the cert’s subject — slightly different audit shape, an extra event in the chain, and a different correlation story between issuance and use.
The trade-off we accepted
Section titled “The trade-off we accepted”OIDC’s main cost is that you have to host a JWKS endpoint that the cloud provider can reach over HTTPS. This is a customer-side trust dependency: AWS STS does an HTTP GET against the URL you registered in the OIDC provider, and trusts whatever JWKS comes back.
For credctl this is fine. The JWKS is small, immutable per device-key, and served from S3 + CloudFront in v1 (and the team broker in v2). It’s not on the credential path latency-wise — STS caches the JWKS aggressively. Outages of the JWKS host don’t break in-progress STS calls; they only prevent new federations against fresh JWTs that reference keys STS hasn’t seen before.
Roles Anywhere doesn’t have this requirement — AWS hosts the entire validation flow. If you genuinely cannot or will not host a publicly-reachable JWKS endpoint (some air-gapped environments, some regulated industries), this is a real point in Roles Anywhere’s favour.
When you’d actually pick Roles Anywhere
Section titled “When you’d actually pick Roles Anywhere”There are cases where Roles Anywhere is the better answer:
- You already have a corporate PKI that issues device certs as part of MDM (Jamf, Intune). Reusing those certs for AWS auth means zero new identity issuance — the device cert it already has becomes the AWS credential. OIDC would require generating new credctl-shaped keys and hosting a parallel JWKS.
- You can’t host a public JWKS endpoint. Air-gapped environments. Regulated environments where any public-internet trust dependency is unacceptable. Environments where the JWKS hosting is itself an audit boundary you don’t want to own.
- You’re AWS-only with no plans to authenticate the same identity to GCP or Azure. The multi-cloud portability argument falls away.
- You don’t want the JWT TTL revocation window and prefer cert-revocation semantics via CRLs or OCSP — even with the operational cost of that infrastructure.
For credctl’s target users — developers running CLIs on their own laptops, often across multiple clouds, often without enterprise MDM — none of these apply strongly enough to overcome OIDC’s portability and ergonomics.
The honest summary
Section titled “The honest summary”OIDC won for credctl because we want one identity that works across three clouds, with zero customer-side PKI, with a mature ecosystem of examples to lean on.
Roles Anywhere wins if you have an existing PKI you want to reuse, if you can’t host a public JWKS endpoint, or if you’re committed to AWS-only.
For a workload that looks like credctl’s — a CLI tool, a CI/CD runner, a service mesh, a Kubernetes federation — OIDC is almost always the right call. Roles Anywhere is the right call when the constraints push you that direction explicitly. The default should be OIDC.
Stay up to date
Get notified about new credctl releases, security best practices, and hardware identity insights.