Google CloudのLegacy Basic RoleとBasic Roleの差分

Google CloudにはOwner, Editor, Viewerというロールがあり、これらを使うとプロジェクトの幅広い部分に権限を与えることができます。

一方で上記のロールは「Legacy Basic Role」と呼ばれており、新たに「Basic Role」というロールも導入されようとしています。Admin, Writer, ReaderというロールがOwner, Editor, Viewerに対応しています。公式ドキュメントでの説明では新旧のロールの具体的な差分がいまいち不明でしたので、調査をしてみました。

https://cloud.google.com/iam/docs/understanding-roles

# Owner vs Admin

調査コマンド

```sh
diff -u <(gcloud iam roles describe roles/owner) <(gcloud iam roles describe roles/admin)
```

調査結果

```diff
@@ -1,5 +1,4 @@
-description: Full access to most Google Cloud resources. See the list of included
-  permissions.
+description: Full access to all resources.
 etag: AA==
 includedPermissions:
 - accessapproval.requests.approve
@@ -1576,19 +1575,30 @@
 - bigquery.savedqueries.get
 - bigquery.savedqueries.list
 - bigquery.savedqueries.update
+- bigquery.tables.create
 - bigquery.tables.createIndex
 - bigquery.tables.createSnapshot
 - bigquery.tables.createTagBinding
+- bigquery.tables.delete
 - bigquery.tables.deleteIndex
 - bigquery.tables.deleteSnapshot
 - bigquery.tables.deleteTagBinding
+- bigquery.tables.export
+- bigquery.tables.get
+- bigquery.tables.getData
 - bigquery.tables.getIamPolicy
+- bigquery.tables.list
 - bigquery.tables.listEffectiveTags
 - bigquery.tables.listTagBindings
 - bigquery.tables.replicateData
 - bigquery.tables.restoreSnapshot
+- bigquery.tables.setCategory
+- bigquery.tables.setColumnDataPolicy
 - bigquery.tables.setIamPolicy
+- bigquery.tables.update
+- bigquery.tables.updateData
 - bigquery.tables.updateIndex
+- bigquery.tables.updateTag
 - bigquery.transfers.get
 - bigquery.transfers.update
 - bigquerymigration.subtasks.get
@@ -9484,9 +9494,18 @@
 - remotebuildexecution.workerpools.get
 - remotebuildexecution.workerpools.list
 - remotebuildexecution.workerpools.update
+- resourcemanager.folders.create
 - resourcemanager.folders.createPolicyBinding
+- resourcemanager.folders.delete
 - resourcemanager.folders.deletePolicyBinding
+- resourcemanager.folders.get
+- resourcemanager.folders.getIamPolicy
+- resourcemanager.folders.list
+- resourcemanager.folders.move
 - resourcemanager.folders.searchPolicyBindings
+- resourcemanager.folders.setIamPolicy
+- resourcemanager.folders.undelete
+- resourcemanager.folders.update
 - resourcemanager.folders.updatePolicyBinding
 - resourcemanager.hierarchyNodes.createTagBinding
 - resourcemanager.hierarchyNodes.deleteTagBinding
@@ -9494,7 +9513,10 @@
 - resourcemanager.hierarchyNodes.listTagBindings
 - resourcemanager.organizations.createPolicyBinding
 - resourcemanager.organizations.deletePolicyBinding
+- resourcemanager.organizations.get
+- resourcemanager.organizations.getIamPolicy
 - resourcemanager.organizations.searchPolicyBindings
+- resourcemanager.organizations.setIamPolicy
 - resourcemanager.organizations.updatePolicyBinding
 - resourcemanager.projects.createBillingAssignment
 - resourcemanager.projects.createPolicyBinding
@@ -10229,16 +10251,33 @@
 - stackdriver.projects.get
 - stackdriver.resourceMetadata.list
 - stackdriver.resourceMetadata.write
+- storage.anywhereCaches.create
+- storage.anywhereCaches.disable
+- storage.anywhereCaches.get
+- storage.anywhereCaches.list
+- storage.anywhereCaches.pause
+- storage.anywhereCaches.resume
+- storage.anywhereCaches.update
+- storage.bucketOperations.cancel
+- storage.bucketOperations.get
+- storage.bucketOperations.list
 - storage.buckets.create
 - storage.buckets.createTagBinding
 - storage.buckets.delete
 - storage.buckets.deleteTagBinding
 - storage.buckets.enableObjectRetention
+- storage.buckets.get
+- storage.buckets.getIamPolicy
+- storage.buckets.getIpFilter
 - storage.buckets.getObjectInsights
 - storage.buckets.list
 - storage.buckets.listEffectiveTags
 - storage.buckets.listTagBindings
+- storage.buckets.relocate
 - storage.buckets.restore
+- storage.buckets.setIamPolicy
+- storage.buckets.setIpFilter
+- storage.buckets.update
 - storage.folders.create
 - storage.folders.delete
 - storage.folders.get
@@ -10251,6 +10290,27 @@
 - storage.hmacKeys.update
 - storage.intelligenceConfigs.get
 - storage.intelligenceConfigs.update
+- storage.managedFolders.create
+- storage.managedFolders.delete
+- storage.managedFolders.get
+- storage.managedFolders.getIamPolicy
+- storage.managedFolders.list
+- storage.managedFolders.setIamPolicy
+- storage.multipartUploads.abort
+- storage.multipartUploads.create
+- storage.multipartUploads.list
+- storage.multipartUploads.listParts
+- storage.objects.create
+- storage.objects.delete
+- storage.objects.get
+- storage.objects.getIamPolicy
+- storage.objects.list
+- storage.objects.move
+- storage.objects.overrideUnlockedRetention
+- storage.objects.restore
+- storage.objects.setIamPolicy
+- storage.objects.setRetention
+- storage.objects.update
 - storageinsights.datasetConfigs.create
 - storageinsights.datasetConfigs.delete
 - storageinsights.datasetConfigs.get
@@ -10880,6 +10940,6 @@
 - workstations.workstations.start
 - workstations.workstations.stop
 - workstations.workstations.update
-name: roles/owner
-stage: GA
-title: Owner
+name: roles/admin
+stage: ALPHA
+title: Admin
```

Ownerと比較してAdminのほうが多くのパーミッションを持っていることが分かります。なので、OwnerからAdminへの移行でパーミッションが狭くなることはありません。
Adminのみが持っているパーミッションは主に以下のものです。

- BigQuery
- Resource Manager
- Cloud Storage

# Editor vs Writer

調査コマンド

```sh
diff -u <(gcloud iam roles describe roles/editor) <(gcloud iam roles describe roles/writer)
```

調査結果

```diff
@@ -1,5 +1,4 @@
-description: View, create, update, and delete most Google Cloud resources. See the
-  list of included permissions.
+description: Write access to all resources.
 etag: AA==
 includedPermissions:
 - accessapproval.requests.get
@@ -1493,15 +1492,24 @@
 - bigquery.savedqueries.get
 - bigquery.savedqueries.list
 - bigquery.savedqueries.update
+- bigquery.tables.create
 - bigquery.tables.createIndex
 - bigquery.tables.createSnapshot
+- bigquery.tables.delete
 - bigquery.tables.deleteIndex
+- bigquery.tables.export
+- bigquery.tables.get
+- bigquery.tables.getData
 - bigquery.tables.getIamPolicy
+- bigquery.tables.list
 - bigquery.tables.listEffectiveTags
 - bigquery.tables.listTagBindings
 - bigquery.tables.replicateData
 - bigquery.tables.restoreSnapshot
+- bigquery.tables.update
+- bigquery.tables.updateData
 - bigquery.tables.updateIndex
+- bigquery.tables.updateTag
 - bigquery.transfers.get
 - bigquery.transfers.update
 - bigquerymigration.subtasks.get
@@ -8280,11 +8288,20 @@
 - remotebuildexecution.workerpools.get
 - remotebuildexecution.workerpools.list
 - remotebuildexecution.workerpools.update
+- resourcemanager.folders.create
+- resourcemanager.folders.delete
+- resourcemanager.folders.get
+- resourcemanager.folders.getIamPolicy
+- resourcemanager.folders.list
 - resourcemanager.folders.searchPolicyBindings
+- resourcemanager.folders.undelete
+- resourcemanager.folders.update
 - resourcemanager.hierarchyNodes.createTagBinding
 - resourcemanager.hierarchyNodes.deleteTagBinding
 - resourcemanager.hierarchyNodes.listEffectiveTags
 - resourcemanager.hierarchyNodes.listTagBindings
+- resourcemanager.organizations.get
+- resourcemanager.organizations.getIamPolicy
 - resourcemanager.organizations.searchPolicyBindings
 - resourcemanager.projects.get
 - resourcemanager.projects.getIamPolicy
@@ -8954,20 +8971,39 @@
 - stackdriver.resourceMetadata.write
 - storage.buckets.create
 - storage.buckets.delete
+- storage.buckets.get
+- storage.buckets.getIamPolicy
+- storage.buckets.getIpFilter
 - storage.buckets.list
 - storage.buckets.listEffectiveTags
 - storage.buckets.listTagBindings
+- storage.buckets.update
 - storage.folders.create
 - storage.folders.delete
 - storage.folders.get
 - storage.folders.list
 - storage.folders.rename
-- storage.hmacKeys.create
-- storage.hmacKeys.delete
 - storage.hmacKeys.get
 - storage.hmacKeys.list
-- storage.hmacKeys.update
 - storage.intelligenceConfigs.get
+- storage.managedFolders.create
+- storage.managedFolders.delete
+- storage.managedFolders.get
+- storage.managedFolders.getIamPolicy
+- storage.managedFolders.list
+- storage.multipartUploads.abort
+- storage.multipartUploads.create
+- storage.multipartUploads.listParts
+- storage.objects.create
+- storage.objects.delete
+- storage.objects.get
+- storage.objects.getIamPolicy
+- storage.objects.list
+- storage.objects.move
+- storage.objects.overrideUnlockedRetention
+- storage.objects.restore
+- storage.objects.setRetention
+- storage.objects.update
 - storageinsights.datasetConfigs.create
 - storageinsights.datasetConfigs.delete
 - storageinsights.datasetConfigs.get
@@ -9575,6 +9611,6 @@
 - workstations.workstations.start
 - workstations.workstations.stop
 - workstations.workstations.update
-name: roles/editor
-stage: GA
-title: Editor
+name: roles/writer
+stage: ALPHA
+title: Writer
```

基本的な傾向はOwner vs Adminと同じですが、`storage.hmacKeys` 系のパーミッションがEditorのみに付与されている点に注意が必要です。

# Viewer vs Reader

調査コマンド

```sh
diff -u <(gcloud iam roles describe roles/viewer) <(gcloud iam roles describe roles/reader)
```

調査結果

```diff
@@ -1,4 +1,4 @@
-description: View most Google Cloud resources. See the list of included permissions.
+description: Read access to all resources.
 etag: AA==
 includedPermissions:
 - accessapproval.requests.get
@@ -711,7 +711,11 @@
 - bigquery.savedqueries.get
 - bigquery.savedqueries.list
 - bigquery.tables.createSnapshot
+- bigquery.tables.export
+- bigquery.tables.get
+- bigquery.tables.getData
 - bigquery.tables.getIamPolicy
+- bigquery.tables.list
 - bigquery.tables.listEffectiveTags
 - bigquery.tables.listTagBindings
 - bigquery.tables.replicateData
@@ -4139,9 +4143,14 @@
 - remotebuildexecution.logstreams.get
 - remotebuildexecution.workerpools.get
 - remotebuildexecution.workerpools.list
+- resourcemanager.folders.get
+- resourcemanager.folders.getIamPolicy
+- resourcemanager.folders.list
 - resourcemanager.folders.searchPolicyBindings
 - resourcemanager.hierarchyNodes.listEffectiveTags
 - resourcemanager.hierarchyNodes.listTagBindings
+- resourcemanager.organizations.get
+- resourcemanager.organizations.getIamPolicy
 - resourcemanager.organizations.searchPolicyBindings
 - resourcemanager.projects.get
 - resourcemanager.projects.getIamPolicy
@@ -4502,6 +4511,9 @@
 - speech.recognizers.recognize
 - stackdriver.projects.get
 - stackdriver.resourceMetadata.list
+- storage.buckets.get
+- storage.buckets.getIamPolicy
+- storage.buckets.getIpFilter
 - storage.buckets.list
 - storage.buckets.listEffectiveTags
 - storage.buckets.listTagBindings
@@ -4510,6 +4522,13 @@
 - storage.hmacKeys.get
 - storage.hmacKeys.list
 - storage.intelligenceConfigs.get
+- storage.managedFolders.get
+- storage.managedFolders.getIamPolicy
+- storage.managedFolders.list
+- storage.multipartUploads.listParts
+- storage.objects.get
+- storage.objects.getIamPolicy
+- storage.objects.list
 - storageinsights.datasetConfigs.get
 - storageinsights.datasetConfigs.list
 - storageinsights.locations.get
@@ -4820,6 +4839,6 @@
 - workstations.workstations.get
 - workstations.workstations.getIamPolicy
 - workstations.workstations.list
-name: roles/viewer
-stage: GA
-title: Viewer
+name: roles/reader
+stage: ALPHA
+title: Reader
```

基本的な傾向はOwner vs Adminと同じです。

# まとめ
Legacy Basic RoleをBasic Roleに置き換える場合、基本的には権限が広がる方向に変化するので、この操作によって権限エラーが発生するケースは基本的に発生しません。唯一の例外はEditorからWriterの置き換え時のHMACキーのパーミッションのみなので、このパーミッションを使っている場合は注意がやや必要です。