Home› Blog› AWS Architecture Series #70 — The trust anchor is not the boundary…
AWS Architecture AWS Architecture Series

AWS Architecture Series #70 — The trust anchor is not the boundary

Long-lived access keys on machines outside AWS are the credential nobody can rotate and everybody has. IAM Roles Anywhere removes them by exchanging an X.509 certificate for a temporary session, which is the right trade — and it moves the authorisation decision into your PKI, where AWS cannot see most of it.

Verified against current vendor documentation on 2 October 2026. Pricing, limits and API behaviour were checked against the official docs on that date. Cloud services change fast — if you are reading this much later, treat the specifics as a starting point and re-check the linked sources.

Business Challenge

The problem Roles Anywhere solves is real and worth solving. “Using IAM Roles Anywhere means you don't need to manage long-term AWS credentials for workloads running outside of AWS.” A build agent, an on-premises job server, a VM in another cloud — instead of an access key pair that lives until somebody remembers it, the workload presents an X.509 certificate and receives a temporary session.

The mechanism is a trust anchor: “A trust anchor is a reference to either AWS Private CA or an external CA certificate… There can be several trust anchors in one AWS account.”

Register the CA, point a role at the service, and you are done. The word "anchor" does a lot of work in that sentence, and it is the wrong word for what the object does.

1Any trust anchor in the account can reach any Roles Anywhere role in it

AWS puts this under a heading called Account trust boundary, and the heading is the answer: “For IAM Roles Anywhere, the trust boundary is established at the account level.”

What that means in practice: “Certificates issued by any trust anchor in the account can be used to assume any target role in that same account, unless you specify conditions in the role's trust policy.”

So two teams, two CAs, two trust anchors, two roles in one account is not two isolated paths. It is four, and the two you did not intend are indistinguishable from the two you did. Registering a CA for one purpose grants it the union of everything Roles Anywhere can reach in that account.

Fix

Every Roles Anywhere role gets an aws:SourceArn condition naming its trust anchor. Without it the anchor is decorative.

2And nothing above the account constrains it

The second bullet under that heading is one sentence and it is the one worth carrying away: “There is no automatic integration with organization-wide controls.”

An organisation that governs identity centrally — and today's daily is about exactly that machinery — does not get Roles Anywhere governance for free. The trust decision lives in the account, in a role's trust policy, written by whoever created the role.

That is a governance surface in the one place org-level tooling does not look, and it is created by a team solving a credential-hygiene problem, usually quickly, usually with the console's default.

Fix

Treat rolesanywhere:CreateTrustAnchor as a privileged action and deny it outside a reviewed path.

3Revoking the certificate in your PKI does not revoke AWS access

Revocation exists, and it is pull-only: “Certificate revocation is supported through the use of imported certificate revocation lists (CRLs)… You can import a CRL that is generated from your CA using ImportCrl…”

And then the sentence that decides your incident response: “Callbacks to CRL Distribution Points (CDPs) or Online Certificate Status Protocol (OCSP) endpoints are not supported.”

AWS never asks your PKI whether a certificate is still good. It knows only what you last imported. So a certificate revoked in your CA keeps working until somebody runs ImportCrl — and the gap between those two events is not visible from either side.

Fix

Make CRL import part of the revocation procedure itself, not a scheduled job that runs afterwards.

Architecture

The exchange is: certificate → CreateSession → temporary credentials, with the role's trust policy as the only gate.

Diagram: how IAM Roles Anywhere turns an X.509 certificate into an AWS session, and the four places the mapping is lossier than it looks. A workload outside AWS holds a certificate issued by a certificate authority, which is registered in the account as a trust anchor; a reference to either AWS Private CA or an external CA certificate, and there can be several trust anchors in one account. The workload calls CreateSession. IAM Roles Anywhere validates the signature using the algorithm required by the key type, then checks the certificate was issued by a CA configured as a trust anchor in the account. End entity certificates must be X.509v3, must have basic constraints CA false if that field is present, must include the Digital Signature key usage, and must be signed with SHA256 or stronger because MD5 and SHA1 are rejected; trust anchor certificates must instead include Certificate Sign key usage and basic constraints CA true. The role being assumed must have a trust policy granting the IAM Roles Anywhere service principal three actions: sts AssumeRole, sts SetSourceIdentity and sts TagSession. The central warning is the account trust boundary: certificates issued by any trust anchor in the account can be used to assume any target role in that same account unless conditions are specified in the role trust policy, and there is no automatic integration with organization-wide controls, so the aws SourceArn condition naming the expected trust anchor is what actually scopes the anchor. AWS recommends aws SourceArn, aws SourceAccount or sts SourceIdentity conditions to prevent Roles Anywhere acting as a confused deputy. The certificate fields become policy inputs as principal tags: subject, issuer, and subject alternative name, exposed as aws PrincipalTag x509Subject, x509Issuer and x509SAN keys. Four lossy mappings are recorded. First, the source identity prefix changes with the length of the common name: CN= when the common name is set and 61 characters or fewer, an empty string when it is 62 to 256 characters, and ID= when no common name is set, while a common name over 256 characters makes CreateSession fail outright, so a condition written against the CN= prefix silently stops matching when a name crosses 61 characters. Second, only the first value of each subject alternative name type is mapped, for DNS names, directory names and URI names, so a condition on a second DNS entry never matches. Third, repeated relative distinguished names are flattened into one slash-separated string in certificate order, so three organizational unit values become Security slash Engineering slash Research and a condition depends on the order the certificate happens to use. Fourth, the session name is set automatically to the hex-encoded serial number of the certificate, so CloudTrail shows serial numbers while source identity carries the common name. A closing panel notes that revocation is import-only because callbacks to CRL distribution points and OCSP endpoints are not supported, that a profile may hold many roles but only one session policy, and that all Roles Anywhere resources are regional and must be created in the same account and Region to be used together.
One gate, and four places the certificate's identity changes shape on the way through it.

What the trust policy has to say

Three actions, not one: “The policy must grant the permissions: sts:AssumeRole, sts:SetSourceIdentity, sts:TagSession.”

The second and third are what make the certificate's contents available as policy inputs, which is the part worth understanding: “IAM Roles Anywhere extracts values from the subject, issuer, and Subject Alternative Name (SAN) fields of the authenticating certificate and makes them available for policy evaluation via the sourceIdentity and principal tags.”

So a trust policy can condition on aws:PrincipalTag/x509Subject/CN, aws:PrincipalTag/x509Issuer/CN, aws:PrincipalTag/x509SAN/DNS and the rest. That is a genuinely good design — your PKI's naming becomes your authorisation vocabulary, and it composes with everything #37 covers about trust policies generally.

The scoping condition is separate and it is the one from the challenge above: “When a client obtains temporary security credentials from IAM Roles Anywhere, the aws:SourceArn and aws:SourceAccount will be set based on the ARN of the trust anchor specified in the call to CreateSession.” AWS's reason for insisting on it is named: it “prevents IAM Roles Anywhere from acting as a potential confused deputy.”

Four places the certificate's identity changes shape

This is the half that will cost someone an afternoon, because in each case the certificate is valid, the session is issued, and a condition that reads correctly does not fire.

The source identity prefix depends on the length of the common name. Three rules: “"CN=": the common name of the subject in the certificate is set and less than or equal to 61 characters… "ID=": the common name of the subject in the certificate is not set… "" (empty string): the common name of the subject in the certificate is set and has a length from 62 to 256 characters.”

A condition written as StringEquals sts:SourceIdentity "CN=buildagent-..." works for every certificate until one is issued with a 62-character CN, at which point the prefix is gone and the condition fails. Past 256 the call does not degrade, it stops: “IAM Roles Anywhere does not support subject common names longer than 256 characters, and the CreateSession request fails.”

Only the first SAN value of each type is mapped. “IAM Roles Anywhere will map the first value of the following types: DNS Names, Directory Name (DN), and URI Names.” A certificate carrying two DNS SANs exposes one. A condition on the second never matches, and the certificate contains it.

Repeated RDNs are flattened into one string, in certificate order. “Because principal tags do not support multiple values, IAM Roles Anywhere combines multiple values into a single string, separating them with forward slashes (/) in the order they appear in the certificate.” So CN=alice, OU=Security, OU=Engineering, OU=Research becomes one tag with the value Security/Engineering/Research.

An equality condition on that tag is an assertion about the order your CA happens to emit OUs in. Reissue with the same three OUs in a different order and the policy stops matching.

The session name is the serial number, not the name. “IAM Roles Anywhere sets this automatically, using the hex-encoded serial number of the authenticating certificate.” So the assumed-role ARN in CloudTrail identifies the certificate, not the workload; the human-readable identity is in source identity instead. AWS's own worked conversions: “Decimal serial number 291 converts to hex 123, which becomes ID=0123… Decimal serial number 17767 converts to hex 4567, which becomes ID=4567.”

Read the principal-tag caveat carefully, because its subject is easy to misread

The trust policy section says the extracted values “need to match the pattern defined in STS session tags. The service ignores values that do not match this pattern. You cannot use these values in policy conditions.” Read in isolation that last sentence appears to forbid the very thing every example on the page does. It does not: its subject is the ignored values — the ones that failed the session-tag pattern. The tags that do match are usable, which is why the page then says they are “also available to be used in conditions in the identity-based policy attached to the role” and shows five policies conditioning on them. Worth knowing because the practical consequence is real: a certificate field containing characters the session-tag pattern rejects is dropped silently, and a condition on it fails closed with nothing to show you why.

Why This Architecture Holds Up

The certificate requirements are strict, and that is load-bearing

For end-entity certificates: “The certificates MUST be X.509v3… If the CA field is present in the basic constraints extension, its value MUST be false. The key usage MUST include Digital Signature. The signing algorithm MUST include SHA256 or stronger. MD5 and SHA1 signing algorithms are rejected.”

The CA: false requirement is the interesting one — it stops an intermediate CA certificate being used as a workload identity, which would otherwise let anything that could issue certificates also authenticate as one.

And the trust anchor's validity window is a snapshot, not a subscription

“For AWS Private CA trust anchors, only the validity period can be modified after creation. When the validity period changes, you must call UpdateTrustAnchor to register this change. IAM Roles Anywhere honors certificates based on the validity period found during the most recent TrustAnchor Create/Update event.” So the validity AWS enforces is the one it read when you last created or updated the anchor. Change it in Private CA and nothing takes effect until UpdateTrustAnchor runs. This is the same shape as the CRL behaviour: Roles Anywhere holds a copy of your PKI's state and does not refresh it on its own.

The profile is the second gate, and it has one slot

“A profile can have many IAM roles, but only one session policy. Any session returned by a CreateSession call that references the profile will have its permissions limited by the session policy.”

That shapes how you lay profiles out: a profile is the unit of session-policy granularity, so roles whose sessions need different ceilings belong in different profiles regardless of how convenient one profile would be. And a session policy only subtracts — it is the seventh gate from #35, in a place you may not have expected to find it.

Everything is Regional, including the pairing

“All IAM Roles Anywhere resources are regional and they must be created in the same account and region to be used together.” A trust anchor and a profile in different Regions are not a configuration, and the multi-Region story is replication of the whole set rather than one anchor serving many Regions.

That cuts both ways and the good side is worth naming: because the account is the trust boundary and resources are Regional, a per-workload account remains the cleanest isolation available. The documented multi-account guidance is an onward pointer rather than a feature, which is itself informative — there is no org-level construct here to reach for.

Key Architecture Decisions

Decision Choice Reasoning
Scoping a role to its CA aws:SourceArn on the trust anchor ARN, always Without it, any trust anchor in the account can assume the role.
Isolating two workloads Separate accounts, not separate trust anchors The trust boundary is the account; anchors do not partition it.
Creating trust anchors Privileged, reviewed action A new anchor widens what can reach every existing Roles Anywhere role.
Identity conditions x509Issuer and SAN, over bare subject CN The CN also drives the source-identity prefix, which changes at 61 characters.
Conditioning on OU Avoid equality on multi-valued RDNs They flatten to one slash-joined string in certificate order.
Revocation ImportCrl inside the revocation runbook No CDP or OCSP callbacks; AWS knows only what was imported.
Private CA validity changes Always follow with UpdateTrustAnchor The enforced window is the one read at the last create or update.
Session ceilings One profile per distinct ceiling A profile carries many roles but only one session policy.

The audit that finds the open path

One query, and it is cheap: list every role in the account whose trust policy names rolesanywhere.amazonaws.com, and check each for an aws:SourceArn or aws:SourceAccount condition. Every role without one is reachable by every certificate every registered CA has ever issued.

Then count trust anchors. One is a design. Several, created at different times by different teams, is the case the account trust boundary was written to warn about.

Closing Thought

Roles Anywhere is a good trade. Exchanging a certificate for a fifteen-minute session is strictly better than an access key with no expiry, and the mechanism does what it says. The thing to notice is where it moved the decision to.

With an access key, the authorisation story is entirely inside AWS and entirely visible to AWS tooling. With Roles Anywhere, half of it is in your PKI: which CA signs, what goes in the CN, how many OUs a certificate carries and in what order, when a revocation list was last exported. None of those are IAM changes, none of them appear in an IAM diff, and three of them can silently stop a condition from matching.

That makes the certificate template a security control, which is not where most organisations keep their security controls. The practical consequence is small and specific: write the aws:SourceArn condition on day one, and treat the certificate profile your CA issues from as part of the policy, because that is what it is.

Next in this series

Security & Identity — AWS Private CA: what a private CA costs to operate rather than to create, why the hierarchy you choose is close to permanent, and where certificate lifetime stops being a security parameter and becomes an availability one.

Comments

How was your experience?
Your feedback helps improve this site.
PoorExcellent