github-actionsopenid-connectamazon-iam

Error: Not authorized to perform sts:AssumeRoleWithWebIdentity during OIDC when a PR get merged into main


I'm trying to assume a role of AWS using OIDC in my github action file but it's saying "Error: Not authorized to perform sts:AssumeRoleWithWebIdentity" When we merge PR into main but if I change the setting to work on push into main then it works. I'm sharing the whole use case below.

In my AWS I have added my identity provider with the following settings

provider name : token.actions.githubusercontent.com audience : sts.amazonaws.com

In my Roles, I've following trust policy added

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::5599526xxxxx: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:organisation-name/repo:ref:refs/heads/main",
                        "repo:organisation-name/repo:pull_request"
                    ]
                }
            }
        }
    ]
}

In the permission section, I've added 1 custom permission as well which I'm attaching

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Resource": "*"
        }
    ]
}

Following is the Github Action File

name: Deploy to Amazon ECS
on:
  pull_request:  #If I change setting for push it will work but on this setting it throws the error
    branches:
      - main
    types:
      - closed
env:
  AWS_REGION: us-east-1              
            
permissions:
      id-token: write   # This is required for requesting the JWT
      contents: read    # This is required for actions/checkout
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: sandbox
    steps:
      - name: Git clone the repository
        uses: actions/checkout@v4

      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::5599526xxxxx:role/github-role
          role-session-name: samplerolesession
          aws-region: ${{ env.AWS_REGION }}   
          

Does anybody can suggest what is possibly wrong here?


Solution

  • Add this step to generate OIDC token explicitly and examine the OIDC token for claims on jwt.io. Full workflow:

    name: id-token
    
    on:
      workflow_dispatch:
      pull_request:
        types: [closed]
        branches: [main]
    
    jobs:
      get-id-token:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
        steps:
          - run: |
              ID_TOKEN=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://demo" | jq -r .value)
              echo $ID_TOKEN | base64
    

    You will need to base64 decode the token before viewing it on jwt.io.

    When I merged a PR, I saw

    "sub": "repo:owner-name/repo-name:pull_request"
    

    What do you see?