关于 aws-github-oidc-scoped-role
这份技术技能指南介绍如何配置 GitHub Actions OIDC 信任和受限的 AWS IAM 角色,重点是将高权限角色限定到特定工作流,并规避 Bedrock 与权限配置中的常见问题。
主要功能
- 01将信任范围限定到工作流文件
- 02配置 OIDC 条件
- 03说明 AI Agent 角色模式
- 04记录 IAM 和 Bedrock 常见问题
适用场景
- 01限制 GitHub Actions 对 AWS 角色的访问
- 02设置只读型 AWS AI Agent 角色
- 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 语句以防止凭证泄露。