Secrets ManagerとGitHub Actionsを組み合わせて認証情報を管理する
こんにちは、データ事業本部のキタガワです。
最近GitHub Actionsに入門しました。
今回はSecrets ManagerとGitHub Actionsを組み合わせて認証情報を管理する方法を紹介します。
ここで作成したソースコードは以下のリポジトリにありますので、参考にしてみてください。
背景
GitHub Actionsにはシークレット機能があり、これを利用して認証情報などの機微な情報を安全に管理できます。シークレットに登録した値はGitHub Actionsの環境変数としてアクセスでき、ログなどにも出力されないため、外部に漏洩することを防ぐことができます。
ただ、階層構造での管理やパスワードローテーションには対応していないため、運用面で物足りなさを感じることもあります。調べてみたところSecrets ManagerをGitHub Actionsから利用する方法があることがわかりました。
環境変数にセットした値はマスクされるらしく、この部分に関しても安心して使用できます。
直近ではサードパーティSaaSシークレットの管理やローテーションができるアップデートも行われており、以下のブログではSnowflakeのKey Pairのローテーションが紹介されています。
GitHub ActionsのSecretsは追加の設定などが不要で手軽に使用することができますが、これらの利点があるSecrets Managerを採用することも大いに検討できるのではないでしょうか。
利用方法
使い方は簡単で、アクションが用意されているので、それを利用するだけです。
- name: Step name
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
secret-ids: |
ENVVAR, secretId1
上記の例だと secretId1 の値が ENVVAR という環境変数にセットされます。また parse-json-secrets: true を指定すると、JSON形式で保存されたシークレットを環境変数に展開できます。
例えば上記の例で secretId1 が {"key1": "value1", "key2": "value2"} というJSON形式で保存されていた場合、ENVVAR_KEY1 と ENVVAR_KEY2 という環境変数にそれぞれ value1 と value2 がセットされます。
やってみる
前提として以下のリソース等が必要になります。
- GitHubリポジトリ
- AWS アカウントと適切な権限(IAM、Secrets Managerの操作権限)
- AWS CLIがインストールされていること
- Terraformがインストールされていること
AWS CLIとTerraformのバージョンは以下のとおりです。
❯ aws --version
aws-cli/2.17.23 Python/3.11.9 Darwin/25.1.0 exe/x86_64
❯ terraform --version
Terraform v1.14.1
on darwin_arm64
構成概要
今回は以下のような構成を想定しています。
Terraformで作成するリソースは以下の通りです。
| リソース | 用途 |
|---|---|
| IAM OIDC Provider | GitHub ActionsとのOIDC連携 |
| IAM Role | GitHub Actionsが引き受けるロール |
| IAM Policy | Secrets Managerへのアクセス許可 |
| Secrets Manager Secret | 認証情報の保存 |
AWSリソースの作成(Terraform)
まずGitHub Actionsに必要なAWSリソースを作成します。
ファイル構成
作成するファイルは以下の通りです。
.
├── main.tf # リソース定義
├── variables.tf # 入力変数
├── outputs.tf # 出力値
└── terraform.tfvars # 環境設定(要作成)
それぞれのファイルを前述の構成図に沿って見ていきましょう。
1. 変数の定義(variables.tf)
まず、環境ごとに異なる値を変数として定義します。
variable "github_org_or_user" {
description = "GitHub organization name (for org repos) or username (for personal repos)"
type = string
}
variable "github_repo" {
description = "GitHub repository name"
type = string
}
variable "aws_region" {
description = "AWS region"
type = string
default = "ap-northeast-1"
}
terraform.tfvars を作成し、自身の環境に合わせてそれぞれの値を設定します。
github_org_or_user = "your-github-org-or-user-name"
github_repo = "your-github-repo-name"
aws_region = "ap-northeast-1"
2. OIDC Providerの作成(main.tf)
GitHub ActionsからAWSへの認証にはOIDCを使用します。まずOIDC Providerを作成します。
resource "aws_iam_openid_connect_provider" "github_actions" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
}
これにより、GitHubが発行するOIDCトークンをAWSで検証できるようになります。なお、thumbprint_list については現在指定不要のようです。
2023年6月27日に GitHub Changelog でサムプリントを2種類設定するという記事が公開されていましたが、2023年7月6日からAWS側で証明書の検証が可能になったため、サムプリントの指定は不要のようです。
このブログにおいても指定を行わずともOIDCでの認証が成功していることを確認しています。
3. IAM Roleの作成(main.tf)
次に、GitHub Actionsが引き受けるロールを作成します。ここで重要なのが信頼ポリシーの condition の部分です。
data "aws_iam_policy_document" "github_actions_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
# 特定のリポジトリからのみアクセスを許可
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:${var.github_org_or_user}/${var.github_repo}:*"]
}
}
}
resource "aws_iam_role" "github_actions" {
name = "github-actions-secrets-manager-role"
assume_role_policy = data.aws_iam_policy_document.github_actions_assume_role.json
}
token.actions.githubusercontent.com:sub の条件により、指定したリポジトリからのアクセスのみを許可しています。これがないと他のリポジトリからこのロールを引き受けられてしまうため、セキュリティ上非常に重要です。
4. Secrets Managerへのアクセス権限(main.tf)
IAM Roleに対して、Secrets Managerへのアクセス権限を付与します。
data "aws_iam_policy_document" "secrets_manager_access" {
statement {
effect = "Allow"
actions = ["secretsmanager:GetSecretValue"]
resources = [aws_secretsmanager_secret.db_credentials.arn]
}
statement {
effect = "Allow"
actions = ["secretsmanager:ListSecrets"]
resources = ["*"]
}
}
resource "aws_iam_role_policy" "secrets_manager_access" {
name = "secrets-manager-access"
role = aws_iam_role.github_actions.id
policy = data.aws_iam_policy_document.secrets_manager_access.json
}
公式ドキュメント によるとGitHub Actionsが引き受けるロールに必要なのは以下のアクセス許可です。
- 取得するシークレットに対する
GetSecretValue- すべてのシークレットに対する
ListSecrets- (オプション) シークレットが カスタマー管理キー で暗号化されている場合には、KMS key に対する
Decrypt
今回シークレットはデフォルトのAWS管理キーで暗号化されているため、Decryptは不要です。また公式では ListSecrets も必要と記載されていますが、試したところ今回の構成では付与しなくても動作しました。
5. シークレットの作成(main.tf)
最後に、Secrets Managerにシークレットを作成します。
resource "aws_secretsmanager_secret" "db_credentials" {
name = "sample/db-credentials"
description = "Database credentials for sample application"
recovery_window_in_days = 7
}
resource "aws_secretsmanager_secret_version" "db_credentials" {
secret_id = aws_secretsmanager_secret.db_credentials.id
secret_string = jsonencode({
host = "db.example.com"
port = 5432
username = "app_user"
password = "initial-password-v1"
database = "myapp"
})
}
JSON形式で保存しておくと、GitHub Actions側で parse-json-secrets: true を指定することで各フィールドを個別の環境変数として展開できます。ここでは例としてDBの擬似的な接続情報を設定しています。
なお、この例ではTerraformのコードにパスワードなどをハードコーディングしていますが、実際にはAWS CLIなどを通してセキュアな方法で登録することを推奨します。
6. 出力値の定義(outputs.tf)
デプロイ後に必要な値を出力します。
output "iam_role_arn" {
description = "IAM role ARN for GitHub Actions"
value = aws_iam_role.github_actions.arn
}
ファイル構成のおさらい
| ファイル | 内容 |
|---|---|
| variables.tf | GitHubリポジトリ情報とリージョンの変数定義 |
| terraform.tfvars | 自身の環境に合わせた変数値 |
| main.tf | OIDC Provider、IAM Role/Policy、Secrets Manager |
| outputs.tf | GitHub Actionsで使用するIAM Role ARNの出力 |
準備ができたらデプロイします。
デプロイ
デプロイは以下のコマンドを実行します。
# Terraformの初期化
terraform init
# Terraformの実行
terraform apply
デプロイが完了すると iam_role_arn が出力されるので、これをGitHub Actionsのシークレットへ AWS_ROLE_ARN として登録します。

GitHub Actionsの設定
続いてGitHub Actionsの設定を行います。GitHub Actionsを利用するリポジトリのトップに .github/workflows/ というディレクトリを作成し、ここにYAMLファイルを配置します。ファイルの名前は任意ですが、今回は sample-github-actions.yml とします。
ファイルには次のような内容を記載します。
name: "Sample GitHub Actions"
on:
push:
branches: [main]
workflow_dispatch: # 手動実行用
env:
AWS_REGION: ap-northeast-1
# OIDC 認証に必要な権限
permissions:
id-token: write
contents: read
jobs:
sample-github-actions:
name: Sample GitHub Actions
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Get secrets from Secrets Manager
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
secret-ids: |
DB_SECRETS, sample/db-credentials
parse-json-secrets: true
- name: Use secrets (demo)
run: |
echo "Database host: ${{ env.DB_SECRETS_HOST }}"
echo "Database port: ${{ env.DB_SECRETS_PORT }}"
echo "Database name: ${{ env.DB_SECRETS_DATABASE }}"
echo "Database user: ${{ env.DB_SECRETS_USERNAME }}"
echo "Database password: ${{ env.DB_SECRETS_PASSWORD }}"
設定ファイルの各項目について簡単に説明します。
実行条件(on)
on:
push:
branches: [main]
workflow_dispatch:
実行条件には push と workflow_dispatch を指定しています。push は通常のプッシュで実行され、workflow_dispatch は手動で実行されるようになっています。
権限の設定(permissions)
permissions:
id-token: write
contents: read
OIDC認証を使用するには id-token: write の権限が必要です。これによりGitHub ActionsがOIDCトークンを発行できるようになります。
AWS認証(configure-aws-credentials)
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
先ほどGitHub Secretsに登録した AWS_ROLE_ARN を使用してAssumeRoleを行います。アクセスキーを使わずOIDC経由で安全に認証できます。
シークレットの取得(aws-secretsmanager-get-secrets)
- name: Get secrets from Secrets Manager
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
secret-ids: |
DB_SECRETS, sample/db-credentials
parse-json-secrets: true
Secrets Managerからシークレットを取得します。
secret-ids の形式は 環境変数名, シークレット名 です。parse-json-secrets: true を指定しているため、JSONの各キーが DB_SECRETS_HOST や DB_SECRETS_PORT などの環境変数に展開されます。
環境変数の利用
- name: Use secrets (demo)
run: |
echo "Database host: ${{ env.DB_SECRETS_HOST }}"
echo "Database port: ${{ env.DB_SECRETS_PORT }}"
...
展開された環境変数は ${{ env.環境変数名 }} で参照できます。ここではデモとしてDBの接続情報をechoしています。値は自動的にマスクされるため、ログには出力されません。
動作確認
ここまで作成してきたファイルをGitHubにプッシュして動作確認を行います。
git add .
git commit -m "Add GitHub Actions"
git push
push後にGitHub Actionsが自動的に実行されます。

問題なく設定できていればSample GitHub Actionsに緑のチェックマークが表示されます。またここをクリックしUse secrets (demo)の実行ログを確認すると、Secrets Managerからシークレットを取得し、環境変数に展開されたことが確認できます。

出力した値はマスクされるため、ログに出力されていないことも確認できます。
まとめ
今回はSecrets ManagerとGitHub Actionsを組み合わせて認証情報を管理する方法を紹介しました。GitHub Actionsのシークレット機能で十分なケースも多いですが、より高度な管理が必要な場合はSecrets Managerも選択肢に入れてみてください。
参考







