1. はじめに
IBM CloudのSecrets Managerは、シークレットと呼ばれる「秘密にしておきたい情報」を管理・保管しておくサービスである。例えばパスワードや鍵情報などは、システムにアクセスするための重要な情報ではあるが、多くのメンバーで共同作業をして連携システムが増えていくに連れて、
- ローカルに個別に配置しておくと、変更の度に全ての環境で個別に変更していく作業が大変(リモートに配置するべき?でも、そのリモートにアクセスするための認証情報はどこに保管するの?)
- ローカル上で誰でもアクセスされてしまうと困るので、その「秘密にしておきたい情報」をどうやって保護するかが難しい(「秘密にしておきたい情報」にパスワードをかけたら、そのパスワードは今度はどこに保管するべき?)
- 一時的に払い出したい場合にどうするの?(自動的に無効になる機能とかも欲しい。)
- (パスワード変更など)定期的な変更作業にどうやって対応するの?
などの問題に直面する。Secrets Managerは、こうした問題を解決してくれる「秘密にしておきたい情報」を統合管理するためのサービスである。
Secrets Managerの概要記事は以下も参照。
2. Secrets Managerで管理できるシークレット
「秘密にしておきたい情報」であるシークレットとして、Secrets Managerでは以下の5種類を管理できる。
- User credentials: いわゆるID/Password情報
- IAM credentials: IBM CloudのIAMにアクセスするためのService ID/API Key
- TLS certificates: CA証明書、サーバー証明書、クライアント証明書を管理できる。外部からimportすることも可能なので、例えばCertificate Managerからexportした証明書情報(秘密鍵、証明証、中間証明証)を使ってALB for VPCに証明書をimportすることもできる。クライアント証明書も、mTLS構成利用時のクライアント管理に利用できる。
- Key-Value: 任意のJSON形式のユーザーデータを保管可能。最大512KB。
- Other secret type: 任意の値。最大1MB。
Secrets ManagerにはAPI経由でアクセスできる。サンプルコードとして、CLI/curl/Java/Node/Python/Goなどの例が載っているが、何かしらの方法で事前にSecrets Manager自体にアクセスするためのIAM情報が必要になる。IBM Cloud: Trusted Profileを使ったVSI for VPCからの安全なAPI/CLI呼び出し方法を使えば、対象サーバーからパスワードレスでIAMの認証情報を取得できるので、結果としてパスワードレスでSecrets Manager内のシークレットにもアクセスできる。
以下では、User credentialsとIAM credentialsの使用例を記載する。(TLS certificatesについてはまた別の機会にします)。
3. 使用例(User credentials)
3-1. 設定
- Secretsの追加
- User credentialsを選択。
- Credentailの情報を入力。今回は、Expiration Dateやローテーション時間も指定してみた。
- 作成完了。今回作成したSecretsにアクセスするためのサンプル例も載っている。
- 先ほどの設定画面で、自動ローテーションを設定したが、手動ローテーションも可能
3-2. User credentialにアクセス
- 今回は、完全にパスワードレスでSecrets Managerにアクセスしたかったので、Trusted Profileを使ってIAM情報を取得し、curlでSecrets ManagerからUser credentialを取得する。
- Trusted Profileの設定はIBM Cloud: Trusted Profileを使ったVSI for VPCからの安全なAPI/CLI呼び出し方法を参照。
- Secrets Managerにはprivate endpoint経由でもアクセスできる。UI上にsnippetとして表示されるのはpublic endpointなので、IBM Cloud内部からアクセスするのであれば、以下の情報を元にprivate endpointsのURLに書き換えた方が良い。
- Secrets Managerのprivate endpoint情報
- UI上からの確認画面
[root@syasuda-metavsi ~]# 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)'`
[root@syasuda-metavsi ~]# 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)'`
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/username_password/24b424de-cbe5-dada-96f7-cdaabe6f44ff" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq
{
"metadata": {
"collection_type": "application/vnd.ibm.secrets-manager.secret+json",
"collection_total": 1
},
"resources": [
{
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:23:17Z",
"crn": "crn:v1:bluemix:public:secrets-manager:jp-tok:a/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:secret:24b424de-cbe5-dada-96f7-cdaabe6f44ff",
"custom_metadata": {},
"description": "test1",
"downloaded": true,
"expiration_date": "2022-09-30T00:30:00Z",
"id": "24b424de-cbe5-dada-96f7-cdaabe6f44ff",
"labels": [],
"last_update_date": "2022-09-30T00:23:17Z",
"locks_total": 0,
"name": "syasuda-user-credentaial1",
"next_rotation_date": "2022-10-30T00:23:17Z",
"secret_data": {
"password": "zaq12wsxcde34rfv",
"username": "syasuda1"
},
"secret_type": "username_password",
"state": 1,
"state_description": "Active",
"versions": [
{
"auto_rotated": false,
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:23:17Z",
"downloaded": true,
"id": "96d97508-adae-93a7-a267-84773362ca9a",
"payload_available": true,
"version_custom_metadata": {}
}
],
"versions_total": 1
}
]
}
3-3. 有効期限後の状態
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/username_password/24b424de-cbe5-dada-96f7-cdaabe6f44ff" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq
{
"metadata": {
"collection_type": "application/vnd.ibm.secrets-manager.secret+json",
"collection_total": 1
},
"resources": [
{
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:23:17Z",
"crn": "crn:v1:bluemix:public:secrets-manager:jp-tok:a/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:secret:24b424de-cbe5-dada-96f7-cdaabe6f44ff",
"custom_metadata": {},
"description": "test1",
"downloaded": true,
"expiration_date": "2022-09-30T00:30:00Z",
"id": "24b424de-cbe5-dada-96f7-cdaabe6f44ff",
"labels": [],
"last_update_date": "2022-09-30T00:23:17Z",
"locks_total": 0,
"name": "syasuda-user-credentaial1",
"secret_data": null,
"secret_type": "username_password",
"state": 5,
"state_description": "Destroyed",
"versions": [
{
"auto_rotated": false,
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:23:17Z",
"downloaded": true,
"id": "96d97508-adae-93a7-a267-84773362ca9a",
"payload_available": false,
"version_custom_metadata": {}
}
],
"versions_total": 1
}
]
}
4. 使用例(IAM credentials)
4-1. 設定
- 事前に、Secrets engines -> IAM credentialsで、以下の権限を持つIDのIBM Cloud API Keyを登録しておく。これにより、Secrets ManagerからIAM credentialsが作成可能になる。https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-configure-iam-engine&interface=ui&locale=en
- Secretsの追加
- IAM credentialsを選択
- IAMのcredential情報は、デフォルトではSecrets Managerにアクセスする度に変更される(セキュリティー的には望ましい)。リース完了までの間、同じcredential情報を参照したい場合は、
Reuse IAM credentials until lease expires
を有効にするが、今回はデフォルトのままにする。リース時間は、今回は10分にしておく。 - 作成するService ID/API Keyに、どの権限を付与するかを指定するため、アクセスグループを指定する。
- 作成完了。今回作成したSecretsにアクセスするためのサンプル例も載っている。
User credentialsのExpireは、そのクレデンシャル情報にアクセスできなくなるまでの時間でした。ExpireされたUser credentialにアクセスしても、ID/Passwordは取得できません。一方で、IAM credentialsにはExpireはありません。リース時間はあくまで、Secrets Managerから取得したIAM情報を使ってIBM Cloudのサービスにアクセスできる時間を指しています。よって、リース時間を過ぎても、再度Secrets ManagerにIAM認証情報を取得すれば、またIBM Cloudにアクセスできます。
4-2. IAM認証情報(API key)の取得
- 今回は、完全にパスワードレスでSecrets Managerにアクセスしたかったので、Trusted Profileを使ってIAM情報を取得し、curlでSecrets ManagerからUser credentialを取得する。
- Trusted Profileの設定はIBM Cloud: Trusted Profileを使ったVSI for VPCからの安全なAPI/CLI呼び出し方法を参照。
- Secrets Managerにはprivate endpoint経由でもアクセスできる。UI上にsnippetとして表示されるのはpublic endpointなので、IBM Cloud内部からアクセスするのであれば、以下の情報を元にprivate endpointsのURLに書き換えた方が良い。
- Secrets Managerのprivate endpoint情報
- UI上からの確認画面
[root@syasuda-metavsi ~]# 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)'`
[root@syasuda-metavsi ~]# 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)'`
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq
{
"metadata": {
"collection_type": "application/vnd.ibm.secrets-manager.secret+json",
"collection_total": 1
},
"resources": [
{
"access_groups": [
"AccessGroupId-9f12573e-4a8c-48dd-81ac-cfda33a355b1"
],
"api_key": "7L2sk1qoTdLLVZWhSXAc3cKvHqKjUHeRawqOWodcymzo",
"api_key_id": "ApiKey-acac0b7f-c413-4e72-9267-46d3422fc62c",
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:43:42Z",
"crn": "crn:v1:bluemix:public:secrets-manager:jp-tok:a/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:secret:15d825d2-7ab8-09d7-2ef3-a9a11fabb97c",
"custom_metadata": {},
"downloaded": true,
"id": "15d825d2-7ab8-09d7-2ef3-a9a11fabb97c",
"labels": [],
"last_update_date": "2022-09-30T00:46:32Z",
"locks_total": 0,
"name": "syasuda-iam-credential1",
"reuse_api_key": true,
"secret_type": "iam_credentials",
"service_id": "ServiceId-e93007aa-4079-4ff0-bf28-8c7ee755598c",
"service_id_is_static": false,
"state": 1,
"state_description": "Active",
"ttl": 600,
"versions": [
{
"auto_rotated": false,
"created_by": "IBMid-110000HEJF",
"creation_date": "2022-09-30T00:43:42Z",
"downloaded": false,
"id": "f2ce7dd1-8a47-ea4c-a292-eb8a4b9b450a",
"payload_available": false,
"version_custom_metadata": {}
},
{
"auto_rotated": false,
"created_by": "iam-Profile-c7737399-ea96-4878-acf0-5a2690fd3493",
"creation_date": "2022-09-30T00:46:32Z",
"downloaded": true,
"id": "b0eee30d-f1f2-d4fa-7d32-215160bd1ba8",
"payload_available": true,
"version_custom_metadata": {}
}
],
"versions_total": 2
}
]
}
4-3. ibmcloud CLIへのログイン試行
先程取得したAPI Keyを使ってログインを試行する。
[root@syasudacentos7 ~]# ibmcloud login --apikey 7L2sk1qoTdLLVZWhSXAc3cKvHqKjUHeRawqOWodcymzo -r jp-tok
API endpoint: https://cloud.ibm.com
Authenticating...
OK
Targeted account IBM (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Targeted region jp-tok
API endpoint: https://cloud.ibm.com
Region: jp-tok
User: ServiceId-e93007aa-4079-4ff0-bf28-8c7ee755598c
Account: IBM (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Resource group: No resource group targeted, use 'ibmcloud target -g RESOURCE_GROUP'
CF API endpoint:
Org:
Space:
4-4. Reuse IAM credentials until lease expires
無効時の動作確認
Secrets ManagerからIAM情報を取得する度に、API keyは変わる。これは、Reuse IAM credentials until lease expires
を無効にしているからである。
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-089ae2cd-3fa1-45cc-b3b6-ee9da105a0d2"
"p0d1sRdvPUjWBWOqpRP1SoyS5wl8ahrCR4GpnCFcD5ce"
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-9dfee6b6-4d8b-4990-94ba-499a42d6f09f"
"63ERPf4mJhO8PZbkxfmeIa8b4LEGRm7P6WOewW4E_o6b"
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-110e29e6-8dcd-4330-97ac-9a251cb45e36"
"v3GpQNakvYGinRbnSgsX3MeiUnqe9t5SUaaScpZlW_8Y"
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-d54b25e9-864f-4719-a16d-bf3d4c65e8ab"
"fsXfdifMekRC3VvpxU1mzptN3PO5SqoqlhJKrmsH_Hb3"
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-7a2a5e78-3188-467d-afa9-dcd199d9540a"
"rB6UznvriCHJD6QAO4Y1KHA86_rdktWs9PrtxH8BoP3X"
[root@syasuda-metavsi ~]# curl -sX GET "https://xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.private.jp-tok.secrets-manager.appdomain.cloud/api/v1/secrets/iam_credentials/c0643817-5cee-9b69-8203-d06195a484d9" -H "Authorization: Bearer $iam_token" -H "Accept: application/json" | jq '.resources[].service_id, .resources[].api_key'
"ServiceId-34628a6e-4a14-40eb-aea9-5b249325293c"
"azh9ACGPd4ifIWEge8j3IJPzRzMEMPrJwQ0Veui7YeqN"
新しくIAM情報を取得すると、リース完了まで待つことなく、過去のAPI Keyは利用できなくなる。
[root@syasudacentos7 ~]# ibmcloud login --apikey rB6UznvriCHJD6QAO4Y1KHA86_rdktWs9PrtxH8BoP3X -r jp-tok
API endpoint: https://cloud.ibm.com
Authenticating...
Credentials were rejected.
Code: BXNIM0415E, message: Provided API key could not be found.
API endpoint: https://cloud.ibm.com
Region:
Not logged in.
FAILED
Unable to authenticate.
[root@syasudacentos7 ~]# ibmcloud login --apikey azh9ACGPd4ifIWEge8j3IJPzRzMEMPrJwQ0Veui7YeqN -r jp-tok
API endpoint: https://cloud.ibm.com
Authenticating...
OK
Targeted account IBM (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Targeted region jp-tok
API endpoint: https://cloud.ibm.com
Region: jp-tok
User: ServiceId-34628a6e-4a14-40eb-aea9-5b249325293c
Account: IBM (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Resource group: No resource group targeted, use 'ibmcloud target -g RESOURCE_GROUP'
CF API endpoint:
Org:
Space:
4-5. リース時間経過後の、アクセス
[root@syasudacentos7 ~]# ibmcloud login --apikey azh9ACGPd4ifIWEge8j3IJPzRzMEMPrJwQ0Veui7YeqN -r jp-tok
API endpoint: https://cloud.ibm.com
Authenticating...
Credentials were rejected.
Code: BXNIM0415E, message: Provided API key could not be found.
API endpoint: https://cloud.ibm.com
Region:
Not logged in.
FAILED
Unable to authenticate.
再度、Secrets ManagerにアクセスしてAPI Keyを取得すればまたIBM Cloudにアクセス可能である。