CircleCI のセキュリティを強化するために GCP 認証 に OIDC を導入する
はじめに
こんにちは。株式会社 Belong で SRE をしている shigwata です。
ご存知の方も多いかと思いますが、今年の年初に CircleCI のインシデントが発生しました。このインシデントにより機密情報の漏洩が疑われ、多くの企業が対策を迫られたことは記憶に新しいかと思います。
Belong では、CI/CD に CircleCI と GitHub Actions を利用しています。GitHub Actions では、OIDC を利用した GCP 認証していましたが、CircleCI は OIDC に対応していなかったため、GCP のサービスアカウントキーを利用した認証していました。
機密情報であるサービスアカウントキーの漏洩が疑われたため、独自に開発していたキーローテーションツールを利用してすべてのサービスアカウントキーを更新しました。しかし今後のことを考えた場合、セキュリティ強化は行うべきであるため今回の件をきっかけに OIDC に移行する計画が立ち上がりました。
本記事では、OIDC をなぜ導入すべきかに触れつつ、Terraform を使って CircleCI に OIDC を用いた GCP 認証を導入する手順について紹介します。
OIDC を導入するメリット
OIDC を導入する前は、サービスアカウントキーを GCP のコンソールから発行し、環境変数に登録する必要がありました。しかし、サービスアカウントキーにはデフォルトで有効期限が設定されません。そのため漏洩しないようにユーザの責任で管理し、キーローテーションなどをする必要があります。
OIDC を利用すると、サービスアカウントキーを利用しなくても有効期限の短いトークンによる認証が可能となります。これにより、より安全な認証が行えるようになります。
設定手順
CircleCI のドキュメントに従って、OIDC を使って認証できるように設定します。
- GCP のセットアップ
- CircleCI 設定ファイルへの GCP の追加
GCP のセットアップ
Belong ではインフラの管理に Terraform を利用しているため、Terraform でサンプルコードを用意しました。
使用する際には、CIRCLECI_ORGANIZATION_ID
を CircleCI Web アプリの [Organization Settings > Overview] の Organization ID に書き換えてください。
locals {
# GCPプロジェクト
project_id = "<PROJECT_ID>"
circleci_organization_id = "<CIRCLECI_ORGANIZATION_ID>"
circleci_project_id = "<CIRCLECI_PROJECT_ID>"
}
# サービスアカウント作成
resource "google_service_account" "sa" {
project = local.project_id
account_id = "test-storage-sa"
}
# サービスアカウントに付与したいロールを設定
resource "google_project_iam_member" "project" {
project = local.project_id
role = "roles/storage.admin"
member = "serviceAccount:${google_service_account.sa.email}"
}
# pool作成
resource "google_iam_workload_identity_pool" "circleci" {
provider = google-beta
workload_identity_pool_id = "circleci"
}
# プロバイダー作成
resource "google_iam_workload_identity_pool_provider" "circleci" {
provider = google-beta
workload_identity_pool_id = google_iam_workload_identity_pool.circleci.workload_identity_pool_id
workload_identity_pool_provider_id = "circleci-prvdr"
attribute_mapping = {
"attribute.aud" = "assertion.aud"
"attribute.iss" = "assertion.iss"
"attribute.project_id" = "assertion['oidc.circleci.com/project-id']"
"google.subject" = "assertion.sub"
}
oidc {
allowed_audiences = [local.circleci_organization_id]
issuer_uri = "https://oidc.circleci.com/org/${local.circleci_organization_id}"
}
}
resource "google_service_account_iam_member" "wif-sa" {
service_account_id = google_service_account.sa.name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.circleci.name}/attribute.project_id/${local.circleci_project_id}"
}
CircleCI 設定ファイルへの GCP の追加
認証に必要な $CIRCLE_OIDC_TOKEN
を利用するには Context を読み込む必要があります。
また下記の環境変数を Context に追加する必要もあります。
サンプルでは gcp-oidc
という名前で作成します。
name | value |
---|---|
GOOGLE_PROJECT_ID | {GCP プロジェクト} |
OIDC_SERVICE_ACCOUNT_EMAIL | {サービス アカウントのメールアドレス} |
OIDC_WIP_ID | circleci |
OIDC_WIP_PROVIDER_ID | circleci-prvdr |
config.yml のサンプルコードは次のようになります。
version: 2.1
orbs:
gcp-cli: circleci/gcp-cli@3.0.1
jobs:
build:
executor: gcp-cli/default
steps:
- run:
command: |
# OIDC トークンを一時ファイルに保存する
echo $CIRCLE_OIDC_TOKEN > "$HOME/oidc_token"
# 生成された OIDC ID トークンの資格情報を作成する
gcloud iam workload-identity-pools create-cred-config \
"projects/${GOOGLE_PROJECT_ID}/locations/global/workloadIdentityPools/${OIDC_WIP_ID}/providers/${OIDC_WIP_PROVIDER_ID}"\
--output-file="~/gcp_cred_config.json" \
--service-account="${OIDC_SERVICE_ACCOUNT_EMAIL}" \
--credential-source-file="$HOME/oidc_token"
- run:
command: |
# 生成された認証情報を利用するように gcloud を設定する
gcloud auth login --brief --cred-file "~/gcp_cred_config.json"
# ADC の設定
echo "export GOOGLE_APPLICATION_CREDENTIALS='~/gcp_cred_config.json'" | tee -a "$BASH_ENV"
- run:
command: |
# GCPにアクセスする処理を書く
workflows:
main:
jobs:
- build:
name: Generate Creds File and Authenticate
context:
- gcp-oidc
Belong では実際には上記のコードを CircleCI プライベート Orb で管理しています。
現在は、circleci/gcp-cli Orb の setup コマンドで OIDC に対応したことで導入しやすくなっています。しかし setup 内で gcloud のインストール コマンドが呼び出されてしまうため、社内の使い方に合わず利用していません。この PR で skip_install パラメータが提案されているので期待しています。
まとめ
サービスアカウントキーから OIDC への切り替えはセキュリティ性が高く、GCP サービスを安全に利用できるようになります。 Google Cloud プロジェクト管理の観点からも、OIDC を使用することで管理がより簡単になります。 この記事が、CircleCI で GCP を利用する際のセキュリティを強化し、効率的な管理方法を提供する手助けになると幸いです。
また弊社 Belong では一緒にサービスを育てる仲間を募集しています。 もし弊社に興味を持っていただけたら <エンジニアリングチーム紹介ページ> をご覧いただけたら幸いです。