0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OCI Valutシークレットを使ってセキュアにキーを保存

Posted at

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...

image.png

更新

先ほどのシークレットを更新します。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
)

コンソール上で見るとバージョンが更新されています。
image.png

一覧

シークレットを一覧を取得します。
現在は一つしかありませんが複数あればステータス含めて取得できます。

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)
image.png

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?