Assuming an AWS IAM Role via Federation

Assuming an AWS IAM Role via Federation (STS)

1. Why: the problem this solves

Before federation, giving an external identity --- a human at a partner company, a CI/CD pipeline, a mobile app user --- access to AWS meant one of two bad options:

  • Create an IAM user for them. Now you're managing a long-lived AccessKeyId/SecretAccessKey pair outside AWS's control: it doesn't expire, it can leak into a repo or a laptop, and revoking it requires you to notice and act.
  • Hand out your own credentials. Worse --- no per-person audit trail, no way to scope what they can touch, no way to revoke one user without breaking everyone.

Neither option scales past a handful of users, and both fail the same test: the credential outlives the need for it. A CI job that runs for 90 seconds shouldn't hold AWS keys that are valid forever. A contractor who leaves the company shouldn't require someone to remember to delete an IAM user.

What's actually needed is a way to say: "Trust proof of identity from a system I already trust (our IdP, GitHub, Google), and in exchange, hand out AWS credentials that work for a few minutes and then evaporate." That's exactly what AWS Security Token Service (STS) federation does --- it trades an authentication token from an external Identity Provider (IdP) for temporary, scoped, self-expiring AWS credentials.

2. What: definition and boundaries

AWS STS federation is a token-exchange service: it accepts a signed proof of identity issued by an external IdP and, if that IdP and the target role both agree to trust each other, returns short-lived AWS credentials scoped to one IAM role.

What it is not:

  • It does not authenticate anyone. STS never checks a password or an MFA code --- that already happened at the external IdP before STS is ever called.
  • It does not grant permissions by itself. STS only hands out credentials for a role; what that role can actually do is defined separately by the role's permission policy (out of scope for this doc).
  • It is not a long-term credential store. Everything it returns has an expiration, typically 15 minutes to 12 hours.

Where it sits: STS is the trust-translation layer between an external identity system and IAM. Upstream of it sits the IdP (Okta, Azure AD, ADFS, Google, GitHub Actions, Cognito). Downstream of it sits every other AWS API, which accepts the temporary credentials exactly like any other SigV4-signed request.

Two protocols reach STS, depending on what kind of token your IdP hands you:

Feature SAML 2.0 Federation OIDC / Web Identity Federation
Typical use case Enterprise workforce SSO Web/mobile apps, CI/CD (e.g. GitHub Actions)
Token type SAML Assertion (signed XML) JSON Web Token (JWT)
Common providers Okta, Ping, Azure AD, AD FS Google, Cognito, GitHub Actions
STS API call AssumeRoleWithSAML AssumeRoleWithWebIdentity
AWS CLI command aws sts assume-role-with-saml aws sts assume-role-with-web-identity

For enterprise workforce SSO specifically, AWS recommends IAM Identity Center over hand-rolled SAML federation --- it automates this trust setup across many accounts instead of you maintaining it per-account. See aws-adfs-assume-principles.md for how a raw ADFS/SAML flow looks end to end once it reaches EKS.

3. Concept map: the whole territory

3.1 Domain mapping

Real-world problem element System concept Why this abstraction
Someone/something needs to prove who they are, without an AWS password External Identity Provider (IdP) Authentication happens once, at the source of truth (Okta, GitHub, Google) --- AWS never touches a credential it didn't issue
AWS needs to decide "do I trust this issuer at all" IAM Identity Provider object (saml-provider / oidc-provider) A one-time registered trust anchor (certificate or thumbprint) that lets AWS cryptographically verify tokens from that IdP
AWS needs to decide "which identities from that IdP may act as this role" IAM Role Trust Policy Scopes trust down from "any token this IdP signs" to "only tokens matching this audience/subject," per role
The actual hand-off: proof → access STS API call (AssumeRoleWithSAML / AssumeRoleWithWebIdentity) One stateless verification-and-mint step; STS itself stores nothing
Access needs to be safe to hand out and forget about Temporary Security Credentials Self-expiring AccessKeyId/SecretAccessKey/SessionToken --- a compromised copy is only dangerous until it expires
The caller needs to actually use those credentials Authenticated Session Credentials loaded into env vars / CLI profile / SDK so every subsequent AWS call is SigV4-signed with them

3.2 Key players

  • External IdP (Okta, Azure AD, ADFS, Google, GitHub Actions OIDC issuer)

    • Owns: authenticating the human or workload and issuing a signed token/assertion.
    • Knows: the real identity (user, or CI job identity), its own signing keys, the audience it's issuing for.
    • Does not do: know anything about AWS roles or permissions --- it has no idea what AWS is going to do with the token.
  • IAM Identity Provider registration (arn:...:saml-provider/... or arn:...:oidc-provider/...)

    • Owns: the cryptographic trust anchor --- the certificate (SAML) or thumbprint/issuer URL (OIDC) AWS uses to validate signatures.
    • Knows: issuer metadata, nothing about individual users.
    • Does not do: grant any permission itself --- it only makes an IdP nameable as a Federated principal.
  • IAM Role Trust Policy

    • Owns: the decision of which federated principals may call sts:AssumeRole* on this specific role, and under what conditions (audience, subject claims, branch/repo restrictions, etc).
    • Knows: the Federated principal ARN and a Condition block.
    • Does not do: define what the role can do once assumed --- that's a separate permissions policy attached to the role.
  • AWS STS

    • Owns: verifying the presented token/assertion against the registered trust anchor, checking it against the trust policy's conditions, and --- if everything matches --- minting temporary credentials for exactly that role.
    • Knows: nothing persistent; it's a stateless verify-then-sign service.
    • Does not do: store identities, manage users, or remember past sessions.
  • Temporary Security Credentials / Session

    • Owns: representing time-bounded, role-scoped AWS access.
    • Knows: AccessKeyId, SecretAccessKey, SessionToken, Expiration.
    • Does not do: outlive its expiry or apply to any role other than the one requested.

3.3 Coordination at a glance

AWS Service API AWS STS External IdP User / CI Job AWS Service API AWS STS External IdP User / CI Job #mermaid-svg-KXPLLPMgKW7TxpWN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KXPLLPMgKW7TxpWN .error-icon{fill:#552222;}#mermaid-svg-KXPLLPMgKW7TxpWN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KXPLLPMgKW7TxpWN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KXPLLPMgKW7TxpWN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KXPLLPMgKW7TxpWN .marker.cross{stroke:#333333;}#mermaid-svg-KXPLLPMgKW7TxpWN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KXPLLPMgKW7TxpWN p{margin:0;}#mermaid-svg-KXPLLPMgKW7TxpWN .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KXPLLPMgKW7TxpWN text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KXPLLPMgKW7TxpWN .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-KXPLLPMgKW7TxpWN .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-KXPLLPMgKW7TxpWN #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-KXPLLPMgKW7TxpWN .sequenceNumber{fill:white;}#mermaid-svg-KXPLLPMgKW7TxpWN #sequencenumber{fill:#333;}#mermaid-svg-KXPLLPMgKW7TxpWN #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-KXPLLPMgKW7TxpWN .messageText{fill:#333;stroke:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KXPLLPMgKW7TxpWN .labelText,#mermaid-svg-KXPLLPMgKW7TxpWN .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .loopText,#mermaid-svg-KXPLLPMgKW7TxpWN .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-KXPLLPMgKW7TxpWN .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-KXPLLPMgKW7TxpWN .noteText,#mermaid-svg-KXPLLPMgKW7TxpWN .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-KXPLLPMgKW7TxpWN .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KXPLLPMgKW7TxpWN .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KXPLLPMgKW7TxpWN .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-KXPLLPMgKW7TxpWN .actorPopupMenu{position:absolute;}#mermaid-svg-KXPLLPMgKW7TxpWN .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-KXPLLPMgKW7TxpWN .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-KXPLLPMgKW7TxpWN .actor-man circle,#mermaid-svg-KXPLLPMgKW7TxpWN line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-KXPLLPMgKW7TxpWN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Verify signature against registered IdP trust anchor + role trust policy conditions Authenticate (SSO / workload identity) 1 Signed token (JWT) or assertion (SAML) 2 AssumeRoleWithWebIdentity / AssumeRoleWithSAML (RoleArn, token) 3 Temporary credentials (AccessKeyId, SecretAccessKey, SessionToken, Expiration) 4 SigV4-signed API request using temp credentials 5 Authorized response (or AccessDenied) 6

Caption: one hand-off --- proof of identity in, time-bounded AWS access out. The failure edge (trust policy condition mismatch → AccessDenied at the STS step) is covered in the trust-policy deep dive below.

4. Running example

Scenario: A GitHub Actions workflow needs to deploy infrastructure to AWS --- no static AWS keys stored in GitHub secrets.

  1. The workflow run starts. GitHub's OIDC issuer mints a JWT scoped to this exact job (claims include the repo, branch, and workflow).
  2. The job calls STS (AssumeRoleWithWebIdentity), presenting that JWT and the target RoleArn.
  3. STS checks the JWT's signature against the IAM OIDC provider registered for token.actions.githubusercontent.com, then checks the role's trust policy conditions (audience, and typically the sub claim restricting this to a specific repo/branch).
  4. STS returns temporary credentials, valid for the rest of the job.
  5. The workflow step exports them into its session and runs terraform apply / aws cli commands.
  6. When the job ends, the credentials are seconds from expiring anyway --- nothing to revoke.

This trunk touches every concept above. A second, parallel scenario --- Priya, an engineer, signs into the AWS console via Okta SSO --- walks the identical skeleton with SAML instead of OIDC, and is called out in each dive below as the comparison case.

5. Depth dives

5.1 External IdP: what the token actually looks like

Recap: issues the signed proof in step 1 of the example; nothing here is AWS-specific yet.

  • OIDC (GitHub Actions → JWT): a JSON Web Token, base64-encoded, cryptographically signed by GitHub's OIDC issuer. Claims include aud (audience), sub (e.g. repo:my-org/my-repo:ref:refs/heads/main), and standard iss/exp.
  • SAML (Okta → assertion): an XML <samlp:Response> containing a signed <Assertion>, base64-encoded before transport. Its claims are attributes rather than JWT fields, but play the same role.

Back to the example: in step 1, GitHub's issuer signs a JWT whose sub claim literally encodes "this exact repo, this exact branch, this exact workflow run." That specificity is what step 3's trust policy condition will check against.

Failure behavior: if the IdP's own auth fails (bad AD credentials, MFA challenge, GitHub issuer misconfigured), no token is ever produced --- the flow never reaches STS.

5.2 IAM Identity Provider registration: the trust anchor

Recap: the one-time setup that lets AWS verify signatures from a given IdP at all; referenced implicitly by step 3.

Both variants are registered once per IdP, then reused by every role that wants to trust it:

  • OIDC: register the issuer URL + audience + certificate thumbprint → produces an oidc-provider ARN.
  • SAML: upload the IdP's metadata XML (contains its signing certificate) → produces a saml-provider ARN.

Back to the example: the Federated principal in the trust policy below (oidc-provider/token.actions.githubusercontent.com) is this registration --- it's what tells AWS "I know how to check signatures from GitHub."

Failure behavior: certificate/thumbprint mismatch (e.g. IdP rotated its signing cert and AWS wasn't updated) → signature validation fails before conditions are even evaluated.

5.3 IAM Role Trust Policy: who may assume this role

Recap: the per-role gate evaluated in step 3 --- narrows "any token this IdP signs" down to "only these tokens."

OIDC / Web Identity (primary example):

json 复制代码
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

SAML (Okta comparison case):

json 复制代码
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:saml-provider/Okta"
      },
      "Action": "sts:AssumeRoleWithSAML",
      "Condition": {
        "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
        }
      }
    }
  ]
}

Back to the example: the sub condition (repo:my-org/my-repo:ref:refs/heads/main) is exactly why this role can only be assumed by workflow runs on main in that one repo --- a PR from a fork, or a run on another branch, fails this condition and never gets credentials, no matter how valid its JWT signature is.

Failure behavior: this is the single most common federation failure --- signature is valid, but the condition doesn't match (wrong branch, wrong audience). STS returns AccessDenied naming the role, not the condition, which is why mismatched sub/aud values are the first thing to check.

5.4 STS API call: the actual exchange

Recap: step 2--4 of the example --- the stateless verify-and-mint step.

bash 复制代码
# OIDC / Web Identity
aws sts assume-role-with-web-identity \
    --role-arn arn:aws:iam::123456789012:role/FederatedOidcRole \
    --role-session-name "OidcSession" \
    --web-identity-token "eyJhbGciOi..."

# SAML
aws sts assume-role-with-saml \
    --role-arn arn:aws:iam::123456789012:role/FederatedSamlRole \
    --principal-arn arn:aws:iam::123456789012:saml-provider/Okta \
    --saml-assertion "PHNhbWxwOkF1dGhuUmVx..."

Back to the example: GitHub Actions' aws-actions/configure-aws-credentials step wraps this exact assume-role-with-web-identity call --- it fetches the JWT from GitHub's OIDC endpoint and passes it straight through.

Failure behavior: clock skew, expired token, or a trust-policy mismatch (5.3) all surface here as an STS-level error before any AWS resource is ever touched.

5.5 Temporary Credentials & Session: using the output

Recap: step 4--5 --- what the caller actually gets and does with it.

Both API calls return the same shape of credential block:

bash 复制代码
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="wJalrXUtn..."
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2Vj..."

Any subsequent AWS CLI/SDK call in that shell (or CI step) picks these up automatically and signs requests with them.

Back to the example: the GitHub Actions job's remaining steps (terraform apply, etc.) run in the same shell environment where these three variables are now set --- no code in those steps needs to know federation happened at all.

Failure behavior: once Expiration passes, every subsequent call fails with ExpiredToken --- by design, there is nothing to revoke because there was never anything long-lived to begin with.

6. Full walkthrough

Tying it together, end to end, for the GitHub Actions run:

  1. Trigger: a push to main starts the workflow.
  2. IdP (5.1): GitHub's OIDC issuer signs a JWT: aud=sts.amazonaws.com, sub=repo:my-org/my-repo:ref:refs/heads/main.
  3. STS call (5.4): the job calls assume-role-with-web-identity with that JWT and RoleArn=FederatedOidcRole.
  4. Trust verification (5.2 + 5.3): STS checks the JWT's signature against the registered oidc-provider/token.actions.githubusercontent.com trust anchor, then checks the role's trust policy --- both the aud and sub conditions match this exact repo/branch.
  5. Credentials minted (5.5): STS returns AccessKeyId/SecretAccessKey/SessionToken, valid for the remainder of the job.
  6. Session used: the workflow exports them and runs terraform apply; every AWS API call is signed with these temporary credentials.
  7. Natural expiry: minutes later the job finishes; the credentials expire shortly after --- nothing to clean up, nothing to leak long-term.

AWS APIs AWS STS GitHub OIDC Issuer GitHub Actions Job AWS APIs AWS STS GitHub OIDC Issuer GitHub Actions Job #mermaid-svg-VEecyIitw8MFiFiF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VEecyIitw8MFiFiF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VEecyIitw8MFiFiF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VEecyIitw8MFiFiF .error-icon{fill:#552222;}#mermaid-svg-VEecyIitw8MFiFiF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VEecyIitw8MFiFiF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VEecyIitw8MFiFiF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VEecyIitw8MFiFiF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VEecyIitw8MFiFiF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VEecyIitw8MFiFiF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VEecyIitw8MFiFiF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VEecyIitw8MFiFiF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VEecyIitw8MFiFiF .marker.cross{stroke:#333333;}#mermaid-svg-VEecyIitw8MFiFiF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VEecyIitw8MFiFiF p{margin:0;}#mermaid-svg-VEecyIitw8MFiFiF .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VEecyIitw8MFiFiF text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-VEecyIitw8MFiFiF .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VEecyIitw8MFiFiF .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-VEecyIitw8MFiFiF .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-VEecyIitw8MFiFiF .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-VEecyIitw8MFiFiF #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-VEecyIitw8MFiFiF .sequenceNumber{fill:white;}#mermaid-svg-VEecyIitw8MFiFiF #sequencenumber{fill:#333;}#mermaid-svg-VEecyIitw8MFiFiF #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-VEecyIitw8MFiFiF .messageText{fill:#333;stroke:none;}#mermaid-svg-VEecyIitw8MFiFiF .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VEecyIitw8MFiFiF .labelText,#mermaid-svg-VEecyIitw8MFiFiF .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-VEecyIitw8MFiFiF .loopText,#mermaid-svg-VEecyIitw8MFiFiF .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-VEecyIitw8MFiFiF .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VEecyIitw8MFiFiF .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-VEecyIitw8MFiFiF .noteText,#mermaid-svg-VEecyIitw8MFiFiF .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-VEecyIitw8MFiFiF .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VEecyIitw8MFiFiF .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VEecyIitw8MFiFiF .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VEecyIitw8MFiFiF .actorPopupMenu{position:absolute;}#mermaid-svg-VEecyIitw8MFiFiF .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-VEecyIitw8MFiFiF .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VEecyIitw8MFiFiF .actor-man circle,#mermaid-svg-VEecyIitw8MFiFiF line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-VEecyIitw8MFiFiF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} verify signature vs oidc-provider trust anchor, verify aud + sub vs role trust policy Request OIDC token for this job 1 JWT (aud=sts.amazonaws.com, sub=repo:my-org/my-repo:ref:refs/heads/main) 2 assume-role-with-web-identity(RoleArn, JWT) 3 AccessKeyId / SecretAccessKey / SessionToken (short TTL) 4 terraform apply (SigV4-signed with temp creds) 5 Resources created 6

To sanity-check the resulting identity at any point in the flow:

bash 复制代码
aws sts get-caller-identity

This closes the loop on the Stage 1 problem: the GitHub Actions job never held a static AWS key, an operator never provisioned or later had to remember to revoke an IAM user, and access was scoped --- by branch, by repo, by minute --- down to exactly the window in which it was needed. The SAML variant (Priya via Okta) runs through the identical six steps, substituting an assertion for a JWT and AssumeRoleWithSAML for AssumeRoleWithWebIdentity --- same trunk, different token.

相关推荐
全云在线allcloudonline1 天前
上海阿里云代理商怎么选?跨区域交付能力核验清单
阿里云·云计算·企业上云
Qianyunzhiyun1 天前
AWS EC2实例启动失败?常见报错和解决办法
云计算·aws
Qianyunzhiyun2 天前
AWS EBS快照怎么创建?服务器备份详细教程
服务器·云计算·aws
百胜软件@百胜软件2 天前
零点零一×百胜E3+业务智能中台项目启动,中台赋能客制化机械键盘品牌“加数”发展
大数据·云计算
skywalk81632 天前
如何在FreeBSD的Linux仿真环境中运行GUI命令
云计算·腾讯云
云布道师2 天前
AutoMQ x 阿里云 OSS Tables:基于 Iceberg 构建流表一体的实时入湖
阿里云·云计算
xywww1682 天前
AWS 账号权限怎么分:根用户和 IAM 用户区别及日常使用建议
大数据·开发语言·人工智能·python·gpt·云计算·aws