IAM Conditionsを利用する時のカスタムロール設計・運用について考える
IAM Conditionsについて
概要は以下ドキュメントに記載がある。条件は、リソースの許可ポリシーのロール バインディングで指定します。
IAM Conditionsは引用文の通り、ロールに指定するものとなっている。
「ロールに指定」というのが結構大きな範疇に影響を及ぼすようで、想定通りの動作をさせるまでに結構時間がかかってしまった。その辺りの経緯も含めてここに記録しておく。
例えば、BigQueryから特定のリモート関数を呼び出し、特定のテーブルデータを用いた処理を実行するには以下権限が必要になる。
- bigquery.jobs.create
- bigquery.tables.getData
- bigquery.routines.get
- bigquery.connections.use
これらがどのリソースに対する許可を与えて作用するかについてはログを見て理解するのが一番早い。
処理を実行してエラーが出たり想定通りに動かなかった場合はそのジョブIDをCloud Loggingのクエリで検索すると目的のログが見つけやすいと思う。
あとは"methodName": "jobservice.insert"
とかも組み合わせて検索すると目的のログに絞り込みやすい。
今回は、特定のリモート関数を呼び出す処理のみ許可すると言ったことが実現したかったので、リモート関数がリソースになっている権限を探してみた。
"methodName": "jobservice.insert",
"authorizationInfo": [
...
{
"resource": "projects/XXXXXXXX/datasets/XXXXXXX/routines/target-function",
"permission": "bigquery.routines.get",
"granted": true,
"resourceAttributes": {}
},
...
]
今回、bigquery.routines.get
を適用するにあたって事前に定義されたロールBigQuery Data Viewerを使っていた。
このロールは、bigquery.tables.getData
も含んでいるからだ。
そこで、このロールにIAM Conditionsをつけてみる。以下はCommon Expression Language(CEL)での記載になっている。
resource.name == "projects/XXXXXXXX/datasets/XXXXXXX/routines/target-function" &&
resource.type == "bigquery.googleapis.com/Routine"
今回の指定方法ではresource.type
はなくてもあまり問題ないが、resource.name
には接頭辞の一致を条件として指定する時に使えるresource.name.startsWith
が存在する。
その場合、制限が意図せず幅広い範囲にかからないように追加でサービス属性の指定などを&&で追加しておいた方がいい。
ちなみに、IAM Conditionsのbigquery.googleapis.com
関連のリソース属性値については全てプレビューとなっている。(2024/10/31現在)
↑のIAM Conditionsを設定してしまうと予期せぬところでエラーが出る。このIAM ConditionsはBigQuery Data Viewer
の全てのロールに適用される。
今回の条件はbigquery.routines.get
には想定通りに効く。ではbigquery.tables.getData
はどうだろうか。この権限のログを改めて見てみる。
{
"resource": "projects/XXXXXXXX/datasets/XXXXXXX/tables/test-table",
"permission": "bigquery.tables.getData",
"granted": true,
"resourceAttributes": {}
},
今設定しているIAM Conditionsの条件だと、種類がリモート関数でリソース名がprojects/XXXXXXXX/datasets/XXXXXXX/routines/target-function
の場合しか権限に許可が出せない。
そのため、bigquery.tables.getData
が実行できずBigQueryのジョブがエラーで帰ってくる。
エラーメッセージにもテーブルに対する権限がなかった旨の記載がある。
Access Denied: Table [プロジェクト名]:[データセット名].[テーブル名]: User does not have permission to query table [プロジェクト名]:[データセット名].[テーブル名], or perhaps it does not exist.
上記のことを踏まえて、カスタムロールを作ってみる。基本的には以下のような構成になるはず。
- IAM Conditionsでリソース制限をかけたい権限が入ったロール
- それ以外の権限が入ったロール
まとめて複数人にIAM Conditionsで制限をかけたロールを付与したい場合は、複数人をまとめたGoogleグループを作成し、グループにロールを付与したものを継承する形で運用するのが一番楽そう。
Terraformで管理しているプロジェクトなら、IAM Conditionsを記載したテンプレートを用意しておくのも良いのかもしれない。
ただやはり同じロールを複数のメンバーアカウントに付与したいならGoogleグループからの移譲にするのが運用的には楽そう。