mcpField
A
aws-github-oidc-scoped-role

aws-github-oidc-scoped-role

github.com/mizchi云与 DevOps41641 次安装1 周前更新
代码仓库

关于 aws-github-oidc-scoped-role

这份技术技能指南介绍如何配置 GitHub Actions OIDC 信任和受限的 AWS IAM 角色,重点是将高权限角色限定到特定工作流,并规避 Bedrock 与权限配置中的常见问题。

主要功能

  1. 01将信任范围限定到工作流文件
  2. 02配置 OIDC 条件
  3. 03说明 AI Agent 角色模式
  4. 04记录 IAM 和 Bedrock 常见问题

适用场景

  1. 01限制 GitHub Actions 对 AWS 角色的访问
  2. 02设置只读型 AWS AI Agent 角色
  3. 03排查 Bedrock AccessDenied 错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mizchi/skills --skill aws-github-oidc-scoped-role

安装后在 Claude Code 中输入/aws-github-oidc-scoped-role确认已加载。

附带文件README.md

详细介绍

AWS GitHub Actions OIDC — 受限 IAM 角色

OIDC 提供方设置

data "tls_certificate" "github_oidc" {
  url = "https://token.actions.githubusercontent.com"
}

resource "aws_iam_openid_connect_provider" "github" {
  url             = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.github_oidc.certificates[0].sha1_fingerprint]
}

每个 AWS 账户配置一个提供方。如果该提供方已存在,请改用 data 数据源。

范围:sub(仓库 + 分支)与 job_workflow_ref(特定工作流文件)

大多数教程会使用 sub 声明,将 OIDC 信任范围限定为仓库 + 分支:

# Minimal scope — any workflow in the repo on main can assume this role
condition {
  test     = "StringLike"
  variable = "token.actions.githubusercontent.com:sub"
  values   = ["repo:ORG/REPO:ref:refs/heads/main"]
}

对于特权角色(例如 AI Agent、部署角色),请使用 job_workflow_ref 将范围限定为特定工作流文件。这样可防止仓库中新增的任何工作流使用该角色:

# Tight scope — only the specific workflow file from main can assume this role
condition {
  test     = "StringLike"
  variable = "token.actions.githubusercontent.com:sub"
  values   = ["repo:ORG/REPO:*"]  # AWS requires sub to be non-empty; use wildcard here
}
condition {
  test     = "StringEquals"
  variable = "token.actions.githubusercontent.com:job_workflow_ref"
  values   = ["ORG/REPO/.github/workflows/my-workflow.yml@refs/heads/main"]
}

始终需要 aud 条件:

condition {
  test     = "StringEquals"
  variable = "token.actions.githubusercontent.com:aud"
  values   = ["sts.amazonaws.com"]
}

AI Agent 角色模式(ReadOnlyAccess + Bedrock + Deny 覆盖)

对于可读取 AWS 资源并调用 Bedrock 模型的 AI 分类/分析角色:

resource "aws_iam_role" "ai_agent" {
  name               = "myapp-ai-agent"
  assume_role_policy = data.aws_iam_policy_document.ai_agent_assume.json
}

# Broad read access to inspect infrastructure
resource "aws_iam_role_policy_attachment" "ai_agent_readonly" {
  role       = aws_iam_role.ai_agent.name
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

# Bedrock model invocation
resource "aws_iam_role_policy" "ai_agent_bedrock" {
  name = "bedrock-invoke"
  role = aws_iam_role.ai_agent.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "bedrock:InvokeModel",
          "bedrock:InvokeModelWithResponseStream",
          "bedrock:Converse",
          "bedrock:ConverseStream",
        ]
        Resource = [
          # Direct foundation model ARNs
          "arn:aws:bedrock:*::foundation-model/anthropic.*",
          # Cross-region inference profiles (jp.anthropic.*, us.anthropic.*, global.anthropic.*, etc.)
          "arn:aws:bedrock:*:*:inference-profile/*anthropic.*",
        ]
      },
      # Anthropic models on Bedrock are AWS Marketplace SaaS products.
      # Even when already subscribed at the account level, the *assuming role*
      # must have Marketplace view/subscribe permissions or Bedrock returns
      # AccessDenied regardless of the subscription status.
      {
        Effect = "Allow"
        Action = [
          "aws-marketplace:ViewSubscriptions",
          "aws-marketplace:Subscribe",
        ]
        Resource = "*"
      },
    ]
  })
}

# ReadOnlyAccess includes secretsmanager:GetSecretValue and kms:Decrypt.
# Deny these explicitly so the agent cannot read secrets or tfstate.
resource "aws_iam_role_policy" "ai_agent_deny" {
  name = "deny-sensitive-reads"
  role = aws_iam_role.ai_agent.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Deny"
        Action   = ["secretsmanager:GetSecretValue", "kms:Decrypt"]
        Resource = "*"
      },
      {
        Effect   = "Deny"
        Action   = ["s3:GetObject"]
        Resource = [
          "arn:aws:s3:::${var.tfstate_bucket}",
          "arn:aws:s3:::${var.tfstate_bucket}/*",
        ]
      },
    ]
  })
}

GitHub Actions 工作流端

permissions:
  id-token: write   # required for OIDC token issuance
  contents: read

jobs:
  ai-triage:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v6
        with:
          role-to-assume: ${{ secrets.AWS_AI_AGENT_ROLE_ARN }}
          aws-region: ap-northeast-1
          role-session-name: ai-triage-${{ github.run_id }}

常见陷阱

  • 使用 Bedrock 时缺少 aws-marketplace 权限:即使账户级别的 Bedrock 订阅已激活,被担任的角色也需要 aws-marketplace:ViewSubscriptions(有时还需要 Subscribe),否则 Bedrock API 调用会返回 AccessDenied。大多数 Bedrock IAM 文档都没有提到这一点。

  • 跨区域推理配置文件 ARN:Bedrock 跨区域推理使用 inference-profile 资源类型,以及带区域前缀的模型 ID(jp.anthropic.*、us.anthropic.*、global.anthropic.*)。标准的 foundation-model/anthropic.* ARN 仅涵盖同区域调用。你需要同时配置这两种 ARN。

  • sub 条件不能为空:即使使用 job_workflow_ref,AWS OIDC 验证也要求至少有一个 sub 条件。请使用通配符(repo:ORG/REPO:*)作为回退值——实际的范围限制由 job_workflow_ref 实现。

  • job_workflow_ref 包含完整的 ref:其值为 ORG/REPO/.github/workflows/FILE.yml@refs/heads/main,而不只是文件路径。省略 @refs/heads/main 后缀意味着任何分支都能触发角色担任。

  • ReadOnlyAccess 包含敏感的读取操作:secretsmanager:GetSecretValue、kms:Decrypt、s3:GetObject 均包含在 ReadOnlyAccess 中。对于只需检查基础设施的 Agent 角色,请添加显式 Deny 语句以防止凭证泄露。

评论

支持 Markdown