GCPのCompute EngineからSecret Managerを利用する

まず前提として、GCP(現称: Google Cloud)でGPUを利用できる仮想サーバーをCompute Engineを使って立てて、DockerでKaggle環境を構築していました(その時の記事→https://qiita.com/kyotoman/items/af838f7adf84f8de0f3c )。  
その環境で[Weights & Biases](https://www.wandb.jp/)を使って、学習メトリクスを確認したり学習結果の管理をしようとしました。
このWeights & Biases(以下wandb)を利用するには、公開鍵をwandbに登録しておいて、手元の秘密鍵で認証を行う必要があります。
この秘密鍵の管理のためにGCPのSecret Managerを利用しました。

当然ですが別にwandbに限った話ではなく、一般的にGCPのCompute Engineで仮想サーバーを立てて、そこでSecret Managerを使ってサードパーティーの認証を行うといった時には同じような手順を踏むため、後の参考と備忘録のためにもここに記しておきます。
# 結論
以下の手順でCompute EngineからSecret Managerで管理する秘密鍵情報を取得できる。
1. Secret Managerに生成した秘密鍵を登録する
2. compute engineのデフォルトのサービスアカウントに「Secret Manager のシークレット アクセサー」のロールを付与する
3. 「APIとIDの管理」で、デフォルトのサービスアカウントに、アクセススコープとして
「すべての Cloud API に完全アクセス権を許可」を選択する(**セキュリティ的にあまりよろしくないので注意**)

# 具体的な手順
## Secret Managerに生成した秘密鍵を登録する
まずはCompute Engineで利用したい外部サービスの秘密鍵を、そのサービスの方で生成しておきます。
今回の例ではwandbの秘密鍵を、wandbのマイページの設定から作成しました。
次にその秘密鍵をSecret Managerで登録します。
登録方法は、コンソールの左上にあるハンバーガーメニューで「セキュリティ」→「Secret Manager」と移動し、「＋シークレットを作成」で登録します。
登録すると、下の画像のようになります。
![スクリーンショット 2023-12-03 22.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/d885575b-c2af-9cee-490d-25871a3bc9c2.png)

## compute engineのデフォルトのサービスアカウントに「Secret Manager のシークレット アクセサー」のロールを付与する
個人的にここが1番詰まったところです。
当初はGCPに登録したGoogleアカウントに、Secret Manager周りのロールを付与すれば問題ないだろうと考えていました。
しかしそれでいざ秘密鍵を取得しようとしても失敗してしまいました。
結局の解決方法は、Compute EngineのデフォルトのサービスアカウントにSecret Managerのロールを渡すことでした。
公式ドキュメントを読んでみると、どうやらCompute EngineにアクセスするためにはGoogleアカウント(ユーザーアカウント)ではなくて、サービスアカウントを使う必要があるようです。(→ https://cloud.google.com/iam/docs/service-account-overview?hl=ja&_ga=2.233787612.-339224807.1693317888&_gac=1.180385109.1700490683.Cj0KCQiApOyqBhDlARIsAGfnyMrlvbUNXvbNYro9xoRSOuql14zSrcu8Uqsy2yYLJOPeKKDt8MC-9EoaAjQEEALw_wcB)
![スクリーンショット 2023-12-03 9.54.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/b5c96bc7-a23e-f58b-9c87-c7b5b47bf2d1.png)

## 「APIとIDの管理」でデフォルトのサービスアカウントに、アクセススコープとして「すべての Cloud API に完全アクセス権を許可」を選択する
VMインスタンスがSecret Managerから秘密情報を取得するにはもう一段階あります。
まずコンソールから「Compute Engine」を押下して、作成したVMインスタンス一覧のページに移動します。
そしてSecret Managerから秘密情報を取得したいインスタンスの名前をクリックして編集状態にします。
そこでアクセススコープという選択肢がありますが、デフォルトでは「デフォルトのアクセス権を許可」が選択されていると思います。
これを「すべてのCloud APIに完全アクセス権を許可」に変更することで、Secret Managerから情報を取ってくることができるようになります。
ただし最小権限の原則からは、「APIごとにアクセス権を設定」で必要なAPIだけを許可することが望ましく、フルアクセスすることはセキュリティ上の問題があるということに注意してください。
![スクリーンショット 2023-12-03 22.27.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/6125011c-3619-8da9-69b8-bbf069cea58a.png)

# 分からない点や改善点
##  「API と ID の管理」で、どのアクセス権がSecret Managerから秘密情報を取得させるものなのか
![スクリーンショット 2023-12-03 22.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/0fa853af-19fb-2bd3-17fd-7c90a53ad94e.png)
↑何やら大量にAPIがあってどれがSecret Managerのアクセス権を司っているかがよく分からない。これっぽいなと思ったものでいくつか試してみたが、いずれも「google.api_core.exceptions.PermissionDenied: 403 Permission 'secretmanager.versions.access' denied for resource〜」というエラーが出てしまう。
## Google Colaboratoryではアクセス権の設定などをしなくても簡単にSecret Managerが使えている謎

実は最初はGoogle Colaboratoryでディープラーニングを行なっていて、そこでwandbを利用していました。
その時は画像のようなコードを書くだけで、Googleアカウントの認証ができてGCPのSecret Managerの情報もすんなり取得できていました。
これをGCPで仮想サーバーを立てて同じことができると思っていたのですが、そう簡単にいかなかったのがこの記事を書いた所以です。
仮想サーバー上ではGoogleアカウントの認証ができていないのかと思って、「gcloud auth login」をしたりしましたがそれでもダメでした。
それで最終的には、Compute Engineのサービスアカウントへのロールの付与や、APIのアクセススコープの変更にたどり着きました。
仮想サーバーでSecret Managerの情報が取れるようになったのはそれで嬉しいのですが、それではなぜGoogle Colaboratoryではそういった面倒なことをしないで済んでいたのかが謎のままです・・・。
![スクリーンショット 2023-12-03 22.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708192/e3c7f032-2981-caba-bc15-0970298eec13.png)