aws-github-oidc-scoped-role について
GitHub Actions の OIDC 信頼設定と、範囲を絞った AWS IAM ロールを構成するための技術ガイドです。特権ロールを特定のワークフローに限定し、Bedrock や権限設定の注意点も説明します。
主な機能
- 01ワークフローファイル単位の信頼範囲
- 02OIDC 条件の設定
- 03AI エージェントロールのパターン
- 04IAM と Bedrock の注意点
活用シーン
- 01GitHub Actions から AWS ロールへのアクセス制限
- 02読み取り専用 AWS AI エージェントロールの設定
- 03Bedrock の 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 アカウントごとにプロバイダーは 1 つです。すでに存在する場合は、代わりに 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 エージェントやデプロイロールなど)では、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 エージェントロールのパターン(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 のリージョン間推論では、リージョンプレフィックス付きのモデル ID(
jp.anthropic.*、us.anthropic.*、global.anthropic.*)を持つinference-profileリソースタイプを使用します。標準のfoundation-model/anthropic.*ARN で対象となるのは、同一リージョン内の呼び出しのみです。両方の ARN が必要です。 -
sub条件を空にしないこと:AWS の OIDC 検証では、job_workflow_refを使う場合でも、少なくとも 1 つの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 に含まれています。インフラの調査だけが必要なエージェントロールでは、認証情報の漏えいを防ぐため、明示的な Deny ステートメントを追加してください。