Closed10

GitHub Actions からキーなしの認証で Google Spread Sheet を操作

hankei6kmhankei6km

GitHub Acrionts から Google Spread Sheet に値を追加したくなったので、せっかくなら OIDC でのキーなし認証を試してみることに。

いまのところ取得するところまではできている。

https://github.com/hankei6km/test-sheet-api

Run node src/index.js
Name, Major:
bbb, てすと
ccc, テスト
ddd, 実験
AAAA, test

しかし、サンプルなどを組み合わせていたら「なんとなく取得ができた」というだけで以下の点などがまだ整理できていない。その辺を整理できればとスクラップを作成。

  • コンソールから設定していったので状況を再現できるようにはなっていない
  • Google APIs Node.js Client との関係
    • クレデンシャルを一時ファイルとしてワークスペースに保存させない方法
    • スコープの定義とサービスアカウントの権限
hankei6kmhankei6km

API 実行のスコープ定義は必要、その上でサービスアカウントからスプレッドシートへのアクセス権限も必要

以下のように scopseshttps://www.googleapis.com/auth/spreadsheets.readonly などを指定しないと、API 実行時に The API returned an error: Error: Insufficient Permission となる。

const auth = new google.auth.GoogleAuth({
  // scopes: SCOPES,
});

スコープを定義しても Workload Identity プールと接続しているサービスアカウントに操作対象のスプレッドシートへのアクセス権限(共有設定)がないと The API returned an error: Error: The caller does not have permission になる。

hankei6kmhankei6km

sheets.googleapis.com 使うときに許可されているスコープはどこで決まるのかはいまのところは不明。

gcloud services disable で API を無効にすれば利用できなくなるが、それは意味が違うと思う。

その辺はサービスアカウントの権限で管理するのかな?

hankei6kmhankei6km

使わないプールは一旦 dsable する

削除しても 30 日は戻せるらしいが、まずは disable にして様子見が推奨されている。

https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers?hl=ja#delete-pool

注意: Workload Identity プールを削除する前に、プールの無効化または ID プロバイダの無効化を検討してください。結果としていずれかのワークロードで Google Cloud リソースにアクセスできなくなった場合、いつでもプールとそのプロバイダを再び有効にできます。ワークロードがアクセスを失わない場合は、プールを削除しても安全です。

設定はコンソールからできる(gcloud から diable にする方法は不明)。

設定すると $ gcloud iam workload-identity-pools describe "${POOL_NAME}" --location=globaldisabled: true が付くようになる(stateACTIVE のまま)。

実行すると以下のようなエラーになる。

The API returned an error: Error: Error code invalid_target: The target service indicated by the "audience" parameters is invalid. This might either be because the pool or provider is disabled or deleted or because it doesn't exist.
hankei6kmhankei6km

gcloud による設定

すでにサービスアカウントがある場合は

https://zenn.dev/vvakame/articles/gha-and-gcp-workload-identity#gcp側でやること

に以下を追加。

# Google Sheets API を有効にする
gcloud services enable sheets.googleapis.com --project "${PROJECT_ID}"
hankei6kmhankei6km

google-github-actions/auth の 入力(workload_identity_provider)に使う値の表示。

gcloud iam workload-identity-pools providers describe "${PROVIDER_NAME}" \
    --project="${PROJECT_ID}" --location="global" \
    --workload-identity-pool="${POOL_NAME}" \
    --format="value(name)"
hankei6kmhankei6km

トークンのフォーマット

利用できるフォーマットは google-github-actions/auth と利用するライブラリの組み合わせで変わる。

google-github-actions/authは以下で指定できるフォーマットが利用できる。
https://github.com/google-github-actions/auth#generating-oauth-20-access-tokens

ライブラリに google-auth-library を利用している場合は以下が利用できる。
https://github.com/googleapis/google-auth-library-nodejs#ways-to-authenticate

id_token を使うと steps.auth.outputs.access_token のようにステップの出力で受け渡しできて良さげに思えるが、デフォルトの方法が無難に思える。

デフォルトの場合は $GITHUB_WORKSPACEgha-creds-f94d21700d4a0451.json のようなファイルが作られる。

google-github-actions/auth はとくに設定しなければ(環境変数経由で?)上記 json を利用する。

注意点としては $GITHUB_WORKSPACE にファイルとして保存されるので、リリースなどに含まれてしまわないよう .gitignore で除外するようにとのこと。

https://github.com/google-github-actions/auth#prerequisites

If you plan to create binaries, containers, pull requests, or other releases, add the following to your .gitignore to prevent accidentially committing credentials to your release artifact:

hankei6kmhankei6km

動作確認

GitHub Actions では動作するようになったが、新しい機能を追加する場合などではローカルでも動かしたくなる。

ざっと調べた限りでは定番的なやり方はなさそう。

google-auth-library の場合は GOOGLE_APPLICATION_CREDENTIALS でサービスアカウントの鍵を指定できるので、テスト用のサービスアカウントで鍵を作成してダウンロードする方法は(良い悪いはともかく)実施できる。

この場合、以下を参考に鍵を必要なときだけ作成(ダウンロード)することを検討した方がよい。
https://cloud.google.com/blog/ja/products/gcp/help-keep-your-google-cloud-service-account-keys-safe

なお、keyrotator というツールでローテーションできるらしい。
https://github.com/Googlecloudplatform/keyrotator

あとは、ファイル名を gha-creds-*.json にしておくと、準備のときに追加した .gitignore のエントリーで除外される。

このスクラップは2022/03/15にクローズされました