IBM Cloud: Trusted Profileを使ったVSI for VPCからの安全なAPI/CLI呼び出し方法

# 1. はじめに

APIやibmcloud CLIを利用する際には、まず最初に認証を行う必要があります。IBM Cloudでは今まで、大きく分けてID/Password方式と[API Keyによる認証方式](https://qiita.com/testnin2/items/3ff57e6c92eacd664ff3)を提供していました。これらの方法は一般的な方法ですが、一方で

- どのようにパスワードやAPI Keyをローテーションさせるか？（パスワードやAPI Keyの数だけ、定期的な変更およびパスワードファイルやAPI Keyファイルへの反映が必要になり、そのための手段を検討する必要がある）
- どうやって保護するか？（パスワードやAPI Keyをファイルに保管する場合は、運用スクリプトなどから読み出せるように適切な権限設定が必要）
- どうやって流出時の影響を避けるか？（パスワードやAPI Key情報が万が一流出したら、任意の環境からアクセス可能になってしまうため、それを防ぐ仕組みが必要）

といった事項を別途考慮する必要があります。こうした従来の方法は、パスワードやAPI Keyを利用者で保管・管理しなければいけないために避けれない問題です。

IBM Cloudでは新たにTrusted Profileを使った認証が可能になりました。Trusted Profileを使えば、例えばVPC上の特定のサーバーに特定のサーバーからのみパスワードやAPI KeyなしでIAM Tokenを取得し、APIやCLIを実行可能になります。VPC以外でも、IBM Kubernetes ServiceやRed Hat OpenShift on IBM Cloudの特定のService AccountからもTrusted Profile経由でAPI KeyなしにIBM CloudのIAM Tokenなどが取得可能になります。本稿ではVSI for VPCを利用した構成手順とテストを紹介します。

https://cloud.ibm.com/docs/cli?topic=cli-vsi-cri-login&locale=en
https://www.ibm.com/cloud/blog/introducing-trusted-profiles-for-vpc-virtual-server-instances


# 2. 設定方法

## 2-1. Trusted Profileの作成

- Manage -> Access(IAM)を選択。Createを押下。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e9d06b5b-0fc1-6e71-8736-a3664684e62f.png)
- 作成するTrusted Profileの名前や記述を記入<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ea0634f6-75d2-51b7-c94e-faffecea9c45.png)
- あとで設定するため、ここでは`Decide later`を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/f0cac76c-ccdb-8f13-aaab-20fae0e7af39.png)
- このTrusted Profileを利用した際に割り当てる権限を選択。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a26c1118-8853-a334-d536-62f6575e62b6.png)

:::note info
以下のようにリソースグループ単位やサブネット単位などより広範囲のリソースに許可を与えることも可能ですが、Trusted Profileが利用可能なリソースは最小限に絞ることが望ましいでしょう。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ee991c25-7ff8-02a1-6bb6-4f1df1b58553.png)



## 2-2. VSIを新規に注文してデフォルトのTrusted Profileを設定する場合

1. VSI注文時のオプションでメタデータサービスを有効化する。また、`select a trusted profile`から、今回作成したTrusted Profileを選択する。この設定をすることで、このVSIにとってのデフォルトのTrusted Profileが構成される。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/b18bdab8-453e-f2f3-4a31-0c30de4688d5.png)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/7f5ab084-4bf1-8c3f-0fff-e0bc874c0c57.png)
2. プロビジョニング後、メタデータサービスと**Default Trusted Profile**が構成されていることを確認。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e3239be2-f164-f253-45a2-4d928154d744.png) 
3. VSIの作成が完了すると、以下のようにこのTrusted Profileへの利用が可能なCompute resourcesが追加されており、このサーバーからTrusted Profileにアクセスできるように構成されていることを確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/899e722b-64e7-ce68-47e0-bb282efd32d6.png)

:::note warn
VSI注文時にしかDefault Trusted Profileは構成できませんし、後から変更することもできません。
Default Trusted Profileが構成されていれば、APIやCLI呼び出しのタイミングでTrusted Profileを指定しなくても、このデフォルトのTrusted Profileが利用されます。
Default Trusted Profileが構成されていない場合は、必ずAPIやCLI呼び出しのタイミングでTrusted Profileを指定する必要があります。
:::

## 2-3. 注文時にTrusted Profileを指定していないVSIに対して構成する場合

1. メタデータサービスを無効にした状態で作成された既存のVSIは、以下からのようにまず最初にメタデータサービスを有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/4f1977e9-a01c-8e82-4dcf-38babee577cb.png)
2. Trusted Profileの設定画面にて、該当のVSIを追加する。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/6d3f445a-573e-9a55-1ae3-2c37fc88ccff.png)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d9ec631b-ac19-9890-ed23-63766c114d7d.png)


なお、サーバーによっては以下のようにリンクローカルアドレスが設定されて、メタデータサービスのアドレスである169.254.169.254に繋がらない（`ホストへの経路がありません`というエラーになる）場合がある。この場合は、`/etc/sysconfig/network`で`NOZEROCONF=yes`を構成することでリンクローカルアドレスを削除すると良い。[参考](https://qiita.com/testnin2/items/7490ff01a4fe1c7ad61f)

```txt:NOZEROCONF=yes設定前
$ ip r
default via 10.0.0.1 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.4
169.254.0.0/16 dev eth0 scope link metric 1002
```
```txt:NOZEROCONF=yes設定後
$ ip r
default via 10.0.0.1 dev eth0
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.4
```

:::note warn
先述の通り、後からDefault Trusted Profileは構成できません。この方法でTrusted Profileの設定をしたVSIからは、APIやCLI呼び出しのタイミングでTrusted Profileを指定する必要があります。
:::

# 3. 実行方法(API)

以下では、IAM Tokenを取得するためにPublic Networkを経由していないことに注意。
https://cloud.ibm.com/apidocs/vpc-metadata


## 3-1.  Instance Identity Tokenを取得

```txt:
$ instance_identity_token=`curl -sX PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-31" -H "Metadata-Flavor: ibm" -d '{ "expires_in": 600}' | jq -r '(.access_token)'`
```
## 3-2. IAM Tokenを取得

```txt:デフォルトのTrustedProfileを利用する場合
$ iam_token=`curl -sX POST "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-31" -H "Authorization: Bearer ${instance_identity_token}" | jq -r '(.access_token)'`
```
```txt:TrustedProfileを指定する場合
$ iam_token=`curl -sX POST "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-31" -H "Authorization: Bearer ${instance_identity_token}" -d '{"trusted_profile": {"id": "Profile-c7737399-ea96-4878-acf0-5a2690fd3493"}}'| jq -r '(.access_token)'`
```

## 3-3. IAM Tokenを使って任意のAPIを呼び出す。

例えば、以下は東京リージョンにおけるVSI一覧の取得するAPI。東京リージョンのVPC用Endpointは以下から参照可能
https://cloud.ibm.com/docs/vpc?topic=vpc-service-endpoints-for-vpc

```txt:
$ curl -sX GET "https://jp-tok.private.iaas.cloud.ibm.com/v1/instances?version=2022-03-31&generation=2" -H "Authorization: Bearer ${iam_token}"| jq

```

# 4. 実行方法(CLI)

## 4-1. Trusted Profileを指定して、Public経由でログインする場合

```
$ ibmcloud login -a cloud.ibm.com --vpc-cri --profile Profile-c7737399-ea96-4878-acf0-5a2690fd3493  -r jp-tok
API endpoint: https://cloud.ibm.com
Authenticating...
OK

Targeted profile syasuda-trusted-profile (Profile-c7737399-ea96-4878-acf0-5a2690fd3493)

Targeted region jp-tok


API endpoint:       https://cloud.ibm.com
Region:             jp-tok
Compute Resource:   crn:v1:bluemix:public:is:jp-tok-1:a/039dbe6794084c7cb514a276dd2345da::instance:02e7_fe6b34c2-7609-47b6-8f62-b7aa0207ec8b
Profile:            syasuda-trusted-profile (Profile-c7737399-ea96-4878-acf0-5a2690fd3493)
xxx (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Resource group:     No resource group targeted, use 'ibmcloud target -g RESOURCE_GROUP'
CF API endpoint:
Org:
Space:
```

## 4-2. Trusted Profileを指定して、Private経由でログインする場合(CSEを利用)

:::note warn
us-south(Dallas)やus-east(WDC)でのみ利用可能です。Tokyo/Osakaリージョンでは使えません。
:::
:::note warn
CLIがバグっているのか、CSE経由でアクセスすると、ICOSのprivate endpoint(Classic InfrastructureのService Network)にアクセスして更新チェックをしようとしてしまいます。そのため、バージョンチェック機能は無効にした方が良いでしょう。もしバージョンの更新をしたいときは、その時だけ以下のコマンドを実行することでICOSへのアクセスをDirect接続にすることで更新可能です。
$ ibmcloud api private.cloud.ibm.com --vpc && ibmcloud update
:::

```
$ export IBMCLOUD_VERSION_CHECK=false
$ ibmcloud login -a private.cloud.ibm.com --vpc-cri --profile Profile-c7737399-ea96-4878-acf0-5a2690fd3493  -r us-south
API endpoint: https://private.cloud.ibm.com
Targeted region us-south

Authenticating...
OK

Targeted profile syasuda-trusted-profile (Profile-c7737399-ea96-4878-acf0-5a2690fd3493)


API endpoint:       https://private.cloud.ibm.com
Region:             us-south
Compute Resource:   crn:v1:bluemix:public:is:jp-tok-1:a/039dbe6794084c7cb514a276dd2345da::instance:02e7_c6ecde2d-0dba-4fdb-ba5b-07aec7fd0bb5
Profile:            syasuda-trusted-profile (Profile-c7737399-ea96-4878-acf0-5a2690fd3493)
Account:            IBM (039dbe6794084c7cb514a276dd2345da)
Resource group:     No resource group targeted, use 'ibmcloud target -g RESOURCE_GROUP'
CF API endpoint:
Org:
Space:
```

## 4-3. Trusted Profileを指定して、Private経由でログインする場合(VPEを利用)

- VPEを利用する時には、ibmcloud login時に`--vpc`オプションを利用します。

```
$ ibmcloud login -a private.cloud.ibm.com --vpc-cri --profile Profile-c7737399-ea96-4878-acf0-5a2690fd3493 --vpc -r us-south
```

- VPEで以下を有効にする必要があります。https://cloud.ibm.com/docs/cli?topic=cli-service-connection#cli-private-vpc
    - Account Management
    - Global Catalog
    - Global Search
    - Global Tagging
    - Usage Metering
    - Enterprise Management
    - Resource Controller
    - User Management

:::note warn
上記のVPEが利用可能なのは、us-south(Dallas)やus-east(WDC)のみであり、なおかつVPEには現時点でTransit Gateway経由でアクセスできないため、やはり東京リージョンや大阪リージョンからは利用できません。
:::