You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Action PR合并部署报错sts:AssumeRoleWithWebIdentity未授权

问题:PR合并触发的GitHub Action无法通过AWS角色认证,手动触发正常

问题背景

我有两个GitHub Action工作流,除触发方式外配置完全一致:

  • manual-deploy:通过workflow_dispatch手动触发,运行正常
  • deploy:在main分支的Pull Request合并完成时触发(pull_request事件类型为closed且github.event.pull_request.merged == true),执行时报错:Error: Not authorized to perform sts:AssumeRoleWithWebIdentity

怀疑是两个事件生成的OIDC Token的sub字段不同,想知道如何验证并解决该问题。

可正常运行的手动触发配置

name: manual-deploy
on:
  workflow_dispatch:

env:
  REACT_APP_VERSION: 0.1.0

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: checkout code
        uses: actions/checkout@v3
        
      - name: install node
        uses: actions/setup-node@v3
        # using later versions of node breaks due to react-scripts v5.0.1 incompatible with typescript v5;
        # this specific node version works though
        with:
          node-version: "16.14.2"

      - name: install dependencies
        run: npm install
        
      - name: run tests
        run: npm run test

      - name: get current date
        id: date
        # pacific time = UTC-7:00
        run: echo "REACT_APP_BUILD_DATE=$(date -u +'%m/%d/%Y %H:%M:%SPT' -d '7 hours ago')" >> $GITHUB_ENV
        
      - name: build project
        run: npm run build
        
      - name: configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ SECRETS.AWS_GITHUB_ROLE }}
          aws-region: us-west-2

      - name: deploy to S3 bucket
        run: aws s3 sync ./build/ s3://myProject --delete

      - name: invalidate cloudfront cache
        run: aws cloudfront create-invalidation --distribution-id ${{ SECRETS.AWS_CLOUDFRONT_DIST_ID}} --paths "/*"

无法运行的PR合并触发配置

name: deploy
on:
  pull_request:
    branches:
      - main
    types: closed
    paths-ignore:
      - '.github/workflows/**'

env:
  REACT_APP_VERSION: 0.1.0

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
    permissions:
      id-token: write
      contents: read
    steps:
      - name: checkout code
        uses: actions/checkout@v3
        
      - name: install node
        uses: actions/setup-node@v3
        # using later versions of node breaks due to react-scripts v5.0.1 incompatible with typescript v5;
        # this specific node version works though
        with:
          node-version: "16.14.2"
          
      - name: install dependencies
        run: npm install
        
      - name: run tests
        run: npm run test

      - name: get current date
        id: date
        # pacific time = UTC-7:00
        run: echo "REACT_APP_BUILD_DATE=$(date -u +'%m/%d/%Y %H:%M:%SPT' -d '7 hours ago')" >> $GITHUB_ENV
        
      - name: build project
        run: npm run build
        
      - name: configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ SECRETS.AWS_GITHUB_ROLE }}
          aws-region: us-west-2

      - name: deploy to S3 bucket
        run: aws s3 sync ./build/ s3://myProject --delete

      - name: invalidate cloudfront cache
        run: aws cloudfront create-invalidation --distribution-id ${{ SECRETS.AWS_CLOUDFRONT_DIST_ID}} --paths "/*"

当前AWS IAM角色信任策略

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<not-sure-if-this-is-sensitive-info>: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:myGitHub/myProject:ref:refs/heads/main"
                }
            }
        }
    ]
}

已尝试用调试模式重新运行工作流,但未获取到有效信息。


问题原因

你的AWS IAM角色信任策略中,sub字段仅允许了repo:myGitHub/myProject:ref:refs/heads/main(对应main分支直接触发或手动触发的场景),但PR合并触发的工作流,其OIDC Token的sub字段格式为repo:myGitHub/myProject:pull_request:<PR编号>,不符合当前策略的条件校验,因此认证失败。

如何验证sub字段格式

在失败的deploy工作流中添加一个步骤,解码并打印OIDC Token的sub值:

- name: 打印OIDC Token的sub字段
  run: |
    ID_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value')
    echo "解码后的sub字段:"
    echo $ID_TOKEN | cut -d. -f2 | base64 -d | jq -r '.sub'

添加后重新运行工作流,即可看到PR合并场景下实际的sub字段内容。

解决方案:更新IAM信任策略

修改角色的信任策略,同时允许手动触发和PR合并触发的sub格式:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<账户ID>: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:myGitHub/myProject:ref:refs/heads/main",
                        "repo:myGitHub/myProject:pull_request:*"
                    ]
                }
            }
        }
    ]
}

如果需要更宽松的配置(不推荐,存在过度授权风险),也可以用通配符覆盖所有该仓库的触发场景:

"StringLike": {
    "token.actions.githubusercontent.com:sub": "repo:myGitHub/myProject:*"
}

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:07:03