Vaultシークレット
OCI Vaultは暗号鍵の管理だけでなく、シークレットと呼ばれるパスワードやAPIキーをセキュアに管理・運用する機能もあります。
無償枠が十分大きいのでこの枠内でほぼ収まるかと思います。
またロギングにて、いつ、だれがキー取得操作をしたかを追跡可能です。
使い方
Python SDKを使って下記一連の操作を実行していきます:
- シークレット作成
- 更新
- 一覧取得
- 値取得
- 削除
事前準備
Vault自体の作成と、AESのマスター暗号化キーを作成しておきます。
以下vault_idとkey_idはそのOCIDです。
シークレット作成
import oci
import json
import base64
import uuid
vault_id = 'ocid1.vault.oc1.iad.'
compartment_id = 'ocid1.compartment.oc1..'
key_id = "ocid1.key.oc1.iad."
config = oci.config.from_file()
vault_client = oci.vault.VaultsClient(config)
secret_data = {
"dbPassword": "dbpass_pwd",
"apiKey": "apikey_pwd",
"adminToken": "admintoken_pwd"
}
secret_json_str = json.dumps(secret_data)
secret_encoded = base64.b64encode(secret_json_str.encode('utf-8')).decode('utf-8')
secret_content_details = oci.vault.models.Base64SecretContentDetails(
content_type="BASE64",
content=secret_encoded
)
secret_name = 'secret_20241211'
create_secret_details = oci.vault.models.CreateSecretDetails(
compartment_id=compartment_id,
key_id=key_id,
secret_name=secret_name,
vault_id=vault_id,
secret_content=secret_content_details,
)
create_secret_response = vault_client.create_secret(
create_secret_details=create_secret_details,
opc_request_id=str(uuid.uuid4()),
opc_retry_token=str(uuid.uuid4())
)
secret_ocid = create_secret_response.data.id
print(f"シークレット '{secret_name}' が作成されました。OCID: {secret_ocid}")
シークレット名「secret_20241211」でパスワードはjson形式で保存します。
実行するとOCIDが払い出されます。このシークレットのOCIDは後からでも取得可能です。
シークレット 'secret_20241211' が作成されました。OCID: ocid1.vaultsecret.oc1.iad...
更新
先ほどのシークレットを更新します。secret_idは先ほどのシークレットOCIDです。
config = oci.config.from_file()
vault_client = oci.vault.VaultsClient(config)
secret_data = {
"dbPassword": "dbpass_pwd_v2",
"apiKey": "apikey_pwd_v2",
"adminToken": "admintoken_pwd_v2"
}
secret_json_str = json.dumps(secret_data)
secret_encoded = base64.b64encode(secret_json_str.encode('utf-8')).decode('utf-8')
secret_content_details = oci.vault.models.Base64SecretContentDetails(
content_type="BASE64",
content=secret_encoded
)
update_details = oci.vault.models.UpdateSecretDetails(
secret_content=secret_content_details
)
response = vault_client.update_secret(
secret_id=secret_id,
update_secret_details=update_details
)
一覧
シークレットを一覧を取得します。
現在は一つしかありませんが複数あればステータス含めて取得できます。
config = oci.config.from_file()
vault_client = oci.vault.VaultsClient(config)
all_secrets = []
list_secrets_response = vault_client.list_secrets(
compartment_id=compartment_id,
vault_id=vault_id,
limit=100
)
all_secrets.extend(list_secrets_response.data)
for secret in all_secrets:
if secret.lifecycle_state != 'ACTIVE':
continue
print(f"シークレット名: {secret.secret_name}, OCID: {secret.id}, Status: {secret.lifecycle_state}")
secret_versions_response = vault_client.list_secret_versions(
secret_id=secret.id,
limit=100
)
secret_versions = secret_versions_response.data
for version in secret_versions:
print(version)
下記のように取得できます。
キーがローテーションされ、最新はversion_number=2となります。
{
"content_type": null,
"is_content_auto_generated": false,
"name": null,
"secret_id": "ocid1.vaultsecret.oc1.iad.",
"stages": [
"CURRENT",
"LATEST"
],
"system_tags": null,
"time_created": "2024-12-11T02:09:44.068000+00:00",
"time_of_deletion": null,
"time_of_expiry": null,
"version_number": 2
}
{
"content_type": null,
"is_content_auto_generated": false,
"name": null,
"secret_id": "ocid1.vaultsecret.oc1.iad.",
"stages": [
"PREVIOUS"
],
"system_tags": null,
"time_created": "2024-12-11T01:53:38.783000+00:00",
"time_of_deletion": null,
"time_of_expiry": null,
"version_number": 1
}
取得
シークレット値を取得します。
先ほどローテーションしたのでそれぞれ取得してみます。
何も指定しないと最新が取得されます。
secrets_client = oci.secrets.SecretsClient(config)
secret_bundle = secrets_client.get_secret_bundle(secret_id=secret_id).data
secret_encoded = secret_bundle.secret_bundle_content.content
secret_decoded = base64.b64decode(secret_encoded).decode('utf-8')
secret_json = json.loads(secret_decoded)
print(secret_json)
{'dbPassword': 'dbpass_pwd_v2', 'apiKey': 'apikey_pwd_v2', 'adminToken': 'admintoken_pwd_v2'}
続いて、更新前の古い結果(version=1)を取得します。
secrets_client = oci.secrets.SecretsClient(config)
secret_bundle = secrets_client.get_secret_bundle(secret_id=secret_id, version_number=1).data
secret_encoded = secret_bundle.secret_bundle_content.content
secret_decoded = base64.b64decode(secret_encoded).decode('utf-8')
secret_json = json.loads(secret_decoded)
print(secret_json)
{'dbPassword': 'dbpass_pwd', 'apiKey': 'apikey_pwd', 'adminToken': 'admintoken_pwd'}
削除
特定シークレットを削除します。
※下はシークレット削除ですが、バージョン単位での削除も可能です。
vault_client = oci.vault.VaultsClient(config)
schedule_deletion_details = oci.vault.models.ScheduleSecretDeletionDetails(
time_of_deletion=datetime.now() + timedelta(days=7)
)
vault_client.schedule_secret_deletion(
secret_id=secret_id,
schedule_secret_deletion_details=schedule_deletion_details
)
print(f"Deletion scheduled for secret: {secret_id}")
Deletion scheduled for secret: ocid1.vaultsecret.oc1.iad.
現時刻から7日後に削除するよう設定しており、実行後は非アクティブとなります(Status: PENDING_DELETION)
参考リンク