Google Cloud (GCP) 権限昇格 JIT-Access

こんにちは。

本記事は株式会社インティメート・マージャーの[Advent Calendar 2023](https://qiita.com/advent-calendar/2023/intimatemerger)の21日目の記事になります。

:::note info
20日目の記事
[Rechartsの軸ラベルを見切れないようにする方法]()
:::


# はじめに

Google Cloud（旧GCP）などのクラウドサービスを利用する上で「権限」というのは欠かせない要素の一つです。

もしこの権限を適切に設定していないと、悪意のある人物やプログラムにクラウド上のリソースを好き勝手使われて多額の請求を突きつけられてしまう可能性があります。

また、IPAの「情報セキュリティ10大脅威2023」の組織編の第9位にあるような「不注意による情報漏えい等の被害」の原因にも繋がることもあります。

https://www.ipa.go.jp/security/10threats/10threats2023.html

これらのことから、組織でクラウドサービスを利用する上で権限を適切に設定することは最重要事項になってきます。


# 最小特権の原則（Principle of Least Privilege）

この権限を設定する上で守るべき原則というものがあり**最小特権の原則**といいます。一言で説明すると「脆弱性や情報漏洩を避けるために、余計な権限を与えるな」というものです。

また、これに似た言葉に**Need-to-knowの原則**というものがあります。
この原則は「必要とする人にのみ権限を与えるべき」というものです。


# ジャストインタイム・アクセス（Just In Time Access）

こうれらの原則を守るべくジャストインタイム・アクセス(JIT-Access)という概念があります。

Amazon Web Services(AWS)では以前から`AssumeRole`や`SwitchRole`というJIT-Accessにあたる機能がありました。

しかし、最近までGoogle Cloudでは公式からそのような機能は提供されておらず、自前で実装するか以下のようなサードパーティ製のツールを利用するしかありませんでした。

https://qiita.com/koduki/items/d30a82e06a364800b786

https://tech.mfkessai.co.jp/2021/07/granter/


# Google Cloud公式JIT-Access

ところがちょうど1年ほど前にようやく公式からJIT-Accessを実現するためのコードがOSSで公開されました！

https://github.com/GoogleCloudPlatform/jit-access

https://cloud.google.com/architecture/manage-just-in-time-privileged-access-to-project

::: note info
こちらのOSSは新サービスではないので自身のGoogle Cloudプロジェクト上のサーバレスなプラットフォーム（`Cloud Run`か`Google App Engine`）で立ち上げる必要があります。
:::

仕組みとしてはバージョン1.5.0の時点で以下のようになっており、とあるロールに関する適格アクセス権（権限昇格のための権限）を得ているユーザがJIT-Accessアプリケーションにリクエストすることで期限付きの権限を取得するというものです。

アプリケーション自体は、基本的に`Cloud Asset Inventory`からユーザの情報を取得し、適格アクセス権を持っていることを確認してから`Resource Manager`経由で該当のロールを付与するというシンプルなものです。

```mermaid
sequenceDiagram
  actor User
  participant S as JIT-Access
  participant A as Cloud Asset Inventory
  participant I as Resource Manager
  participant P as Cloud Pub/Sub
  participant L as Cloud Logging

  opt if search project
    User ->>+ S: (0) GET /api/projects
    S ->>+ A: Request Resources<br>(filtered by a permission "resourcemanager.projects.get")
    A -->>- S: Accessible Resources
    S -->>- User: List of Projects
  end

  User ->>+ S: (1) GET /api/projects/<project_id>/roles
  S ->>+ A: Request Resources<br>(filtered by the project_id)
  A -->>- S: Accessible Resources
  S ->> S: Extract JIT-Eligible Roles<br>(with "has({}.jitaccessconstraint)")
  S -->>- User: List of non-activated Roles

  User ->>+ S: (2) POST /api/projects/<project_id>/roles/self-activated<br>{activationTimeout, justification, roles[]}
  loop for each role
    S ->> I: Activate the JIT-Eligible Role with the Timeout
    S ->> P: Send Notification if Configured
    S ->> L: Write Log
  end
  S -->>- User: Summary of Activated Roles
```

## 必要な設定等

Cloud Runなどで動かす場合は、サービスアカウントを利用することが一般的であり上記の図からも分かる通り以下の２つの権限を先に付与しておく必要があります。

- Cloud Asset Inventory関連: `roles/cloudasset.viewer`
- Resouce Manager関連: `roles/iam.securityAdmin`

::: note warn
上記サービスアカウントは非常に強い権限を持つので「余計なキーは発行しない」などの対策をして管理には十分気をつけましょう。
:::

Cloud Pub/Subに関しては[ドキュメントに記載の設定](https://github.com/GoogleCloudPlatform/jit-access/wiki/Configure-Pub-Sub-notifications)を行うことでPublishが可能になり、この設定を行う上で以下の権限が必要になります。

- Cloud Pub/Sub関連: `roles/pubsub.publisher`

::: note info
Cloud Loggingに関しては標準出力に出力しているだけなので特に権限設定は必要ありません。
:::



また、公式ドキュメント内で出てくるIAM条件の

```
has({}.jitAccessConstraint)
```

という記載に関してはGoogle独自のCEL言語で書かれており一見よく分からないのですが、ドキュメントを読んでみたところ「empty mapに"jitAccessConstraint"というfieldが存在するか否か」という意味で常に`False`を返すための式でした。

- 参考ドキュメント
    - https://github.com/google/cel-spec/blob/master/doc/langdef.md#aggregate-values
    - https://github.com/google/cel-spec/blob/master/doc/langdef.md#macros
    - https://cloud.google.com/iam/docs/conditions-overview

また、以下のコードで適格アクセス権であることを判別しており、これを指定しないと(1)でのロール選択時に表示されません（余計なスペースは無視してくれています）。

```java
/** Condition that marks a role binding as eligible for JIT access */
private static final Pattern JIT_CONDITION_PATTERN = Pattern
.compile("^\\s*has\\(\\s*\\{\\s*\\}.jitaccessconstraint\\s*\\)\\s*$");
```
https://github.com/GoogleCloudPlatform/jit-access/blob/02b10b8788e7e118a538226a6e9816aaebc4c4ac/sources/src/main/java/com/google/solutions/jitaccess/core/entitlements/JitConstraints.java#L39

上記のロールを選択して権限昇格することで、下記のように**適格アクセス権とは別で**期限付きの権限が付与されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632701/e9b7f8f2-d2b7-468d-7d8c-95f080c8234b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632701/823ca8d5-9959-fcd1-643c-5ff9ccade73f.png)


# まとめ
本記事ではGoogle Cloud上で権限管理を行う上で必須とも言える原則を守るためのツールを紹介しました。

また、初めて使う上で少し気になる部分を書き起こしてみました。
少しでも利用を検討されている方の参考になれば嬉しいです。

# あとがき
ここまで読んでいただいてありがとうございました！

明日はついに弊社社長による生成AIを利用した競馬予想に関するお話です！
ぜひお楽しみに！！

https://qiita.com/advent-calendar/2023/intimatemerger