GitHub ActionsのOIDC id tokenでGCPにアクセスしてみた
注意: この記事は古くなっています。現在は正式リリースされています。ドキュメントはこちら
巷で話題になってるGitHub Actionsのid tokenでGCPにアクセスしてみた。
AWS federation comes to GitHub Actions | Aidan Steele’s blog (usually about AWS)
これを参考に試してみた。
GCP側
以下、49482415725
, ryotarai-github-oidc-sample
はproject number, project ID(このprojectは削除済み)
これを参考にWorkload Identityまわりの設定をする。
まず、IAM, Resource Manager, Service Account Credentials, and Security Token Service (STS) API を有効にする。
gcloud iam workload-identity-pools create github-oidc-sample \ --location="global" \ --description="github-oidc-sample" \ --display-name="github-oidc-sample"
gcloud iam workload-identity-pools providers create-oidc github-oidc \ --workload-identity-pool="github-oidc-sample" \ --issuer-uri="https://vstoken.actions.githubusercontent.com" \ --location="global" \ --attribute-mapping="google.subject=assertion.sub" \ --allowed-audiences="https://github.com/ryotarai/github-oidc-gcp-sample"
github-oidc-sample, github-oidcは適当に名前をつけた箇所。
providerをつくるときにallowed-audiencesを指定しておくこと。デフォルトだとaudにはリポジトリのURLが入ってくるっぽいのでそれを指定しておく。
gcloud iam service-accounts add-iam-policy-binding viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.com \ --role=roles/iam.workloadIdentityUser \ --member="principal://iam.googleapis.com/projects/49482415725/locations/global/workloadIdentityPools/github-oidc-sample/subject/repo:ryotarai/github-oidc-gcp-sample:ref:refs/heads/main"
viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.com
は事前に作っておいたSA。このSAの権限が使えるようになる。
このmember
のフォーマットは
https://cloud.google.com/iam/docs/access-resources-oidc#iam-workload-pools-create-gcloudあたりを参照。上記の場合、特定のsubject(repo:ryotarai/github-oidc-gcp-sample:ref:refs/heads/main
)を指定している。
GitHub Actions
適当なAPIをつかうなにかを書いて
# client/main.go package main import ( "context" "log" "cloud.google.com/go/storage" ) func main() { ctx := context.Background() // Sets your Google Cloud Platform project ID. projectID := "ryotarai-github-oidc-sample" // Creates a client. client, err := storage.NewClient(ctx) if err != nil { log.Fatalf("Failed to create client: %v", err) } defer client.Close() // Creates a Bucket instance. iter := client.Buckets(ctx, projectID) attr, err := iter.Next() if err != nil { log.Fatalf("failed to iter: %s", err) } log.Printf("%+v", attr) }
ワークフローを設定
# .github/workflows/sample.yml name: sample on: push: jobs: build: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@v2 - run: sleep 5 # there's still a race condition for now - name: id token sample run: | gcloud iam workload-identity-pools create-cred-config \ projects/49482415725/locations/global/workloadIdentityPools/github-oidc-sample/providers/github-oidc \ --service-account=viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.com \ --output-file=cred-config.json \ --credential-source-url="$ACTIONS_ID_TOKEN_REQUEST_URL" \ --credential-source-headers="Authorization=bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ --credential-source-type=json \ --credential-source-field-name=value export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/cred-config.json" cd client GO111MODULE=on go run .
branchを変えるとsubjectが変わるので、権限不足で失敗することも確認