2022年12月9日金曜日

OCI PL/SQL SDKを使ってOCI Vaultのシークレットを操作する

 Oracle Cloud Infrastructureの環境では、暗号化キーといったセンシティブな情報の保存先として、ボールト(Vault)のサービスを使用できます。

ボールトのサービスを呼び出すPL/SQL SDKが提供されているので、これを使ってシークレットとして暗号キーを保存と取り出しを実装してみます。

ボールトが作成済みであることが前提条件です。

ボールトの作成手順については、日本オラクルから公開されている以下のチュートリアルが参考になります。

OCIチュートリアル - Oracle Cloud Infrastructureを使ってみよう
プライベート認証局と証明書の発行

https://oracle-japan.github.io/ocitutorials/intermediates/certificate/

シークレットの作成、更新、削除を行うAPIを呼び出す際に使用するクリデンシャルは、以下の手順に沿って作成します。

作成されるクリデンシャルはMY_OCI_CREDになります。

APEXにて以下のテスト用アプリケーションを作成します。以下の操作を行なっています。
  1. Generate Keyをクリックし暗号化キーを生成する。暗号化キーはGenerated Keyに返される。
  2. Secret Nameを指定する。CreateをクリックしてGenerated Keyに表示されている暗号化キーをシークレットとして保存する。Secret IDCurrent Version Numberが返される。
  3. Generate Keyをクリックし、暗号化キーを更新する。
  4. Updateをクリックし、Secret IDのシークレットを新たに生成されたGenerated Keyの値で更新する。Current Version Numberが返される。
  5. Getをクリックし、シークレットとして保存されている暗号化キーをKeyに返す。Generated Keyと同じ値になる。
  6. Time Of Deletionを設定し、Deleteをクリックする。Secret IDのシークレットの削除がスケジュールされる。

OCIコンソールより、一連の操作を行なったシークレットを確認します。

バージョンが2つあり、すでに削除がスケジュールされていることが確認できます。


以下より、実施した作業を紹介します。


マスター暗号化キーの作成



シークレットを作成する際に指定する暗号化キーを作成します。

OCIのコンソールよりボールトの詳細ページを開きます。

ボールトのOCIDはAPI呼び出しの際に使用するため、あらかじめコピーしておきます。

リソースマスター暗号化キーを選択し、キーの作成をクリックします。


画面右よりドロワーが開きます。

保護モードとしてソフトウェアが使えます。名前は任意ですがSFM_MASTER_KEYとしました。キーのシェイプ: アルゴリズムAESキーの長さは選択できる最長の長さである256ビットを選択します。

以上で作成をクリックします。


少し時間がかかりますが、マスター暗号化キーが作成されます。

マスター暗号化キーのOCIDもAPIの呼び出しに使用するため、コピーをとっておきます。




ポリシーの作成



クリデンシャルMY_OCI_CREDの元となるユーザーがシークレットを操作できるように、ポリシーを作成します。

OCIコンソールよりアイデンティティポリシーを開きます。

ポリシーの作成をクリックします。


作成するポリシーの名前はSecretAdminPolicyとしています。コンパートメントにはルートを選んでいます。ポリシー・ユースケースとしてキーおよびシークレット管理を選択し、共通ポリシー・テンプレートとしてセキュリティ管理者がボールト、キーおよびシークレットを管理できるようにしますを選択します。

ポリシーを適用するグループとしてAPEXObjectManagersを選択し、場所としてルートを指定しています。クリデンシャルMY_OCI_CREDを作成する手順にグループAPEXObjectManagersの作成も含まれています。

以上で作成をクリックします。


ポリシーSecretAdminPolicyが作成されます。



テナンシのOCIDの取得



シークレットを操作するAPIの呼び出しには、ボールト、マスター暗号化キーの他にコンパートメントのOCIDが必要です。

OCIコンソールよりコンパートメントを開き、使用するコンパートメントのOCIDコピーしておきます。




PL/SQL SDKの実行権限の付与



シークレットを操作するPL/SQL SDKのパッケージの実行権限を、APEXのワークスペース・スキーマに与えます。以下の例ではワークスペース・スキーマをwksp_apexdevとしています。環境に合わせてワークスペース・スキーマ名を置き換えます。


データベース・アクション開発SQLより実行します。



パッケージSFM_SECRET_UTILの作成



パッケージSFM_SECRET_UTILを作成します。

create_secretupdate_secretget_key_from_secretdelete_secretの4つのファンクションまたはプロシージャが実装されています。


SQLワークショップSQLスクリプトを使って実行します。




検証用アプリケーションの作成



アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。アプリケーションの名前シークレットの操作としました。

アプリケーションの作成を実行します。


アプリケーションが作成されます。

アプリケーション定義置換を開き、置換文字列としてG_COMPARTMENT_OCIDG_MASTER_KEY_OCIDG_VAULT_OCIDG_REGIONG_CREDENTIALを設定します。


ページ・デザイナホーム・ページを開きます。

ボタンおよびページを作成し、以下のように配置します。

ページ・アイテムP1_TIME_OF_DELETIONのみタイプ日付ピッカーです。それ以外はテキスト・フィールド、ボタンもデフォルトの設定です。


ボタンGENERATE_KEYのクリックに対応したプロセスを作成します。

識別名前暗号キーの作成タイプコードの実行を選択します。PL/SQLコードには以下を記述します。暗号化キーがGenerated Keyに設定されます。

:P1_GENERATED_KEY := rawtohex(dbms_crypto.randombytes(32));


ボタンCREATEのクリックに対応したプロセスを作成します。

識別名前シークレットの作成タイプAPIの呼び出しを選択します。パッケージSFM_SECRET_UTILに含まれるファンクションCREATE_SECRETを呼び出します。


ファンクションの結果として作成されたシークレットのOCIDが返されます。ページ・アイテムP1_SECRET_IDに設定します。


シークレットに保存する暗号化キーであるp_keyとして、以下のPL/SQL式を指定します。

hextoraw(:P1_GENERATED_KEY)


パラメータp_secret_nameシークレット名です。ユーザーがページ・アイテムP1_SECRET_NAMEに入力します。すでに同名のシークレットが存在する場合、エラーが発生します。


出力パラメータのp_current_version_numberは、ページ・アイテムP1_CURRENT_VERSION_NUMGBERに設定します。シークレットの作成時は1が返されます。


引数p_compartment_ocidp_master_key_ocidp_vault_ocidp_regionp_credentialについては、置換文字列G_COMPARTMENT_OCIDG_MASTER_KEY_OCIDG_VAULT_OCIDG_REGIONG_CREDENTIALアイテムとして設定します。

ボタンUPDATEのクリックに対応したプロセスを作成します。

識別名前シークレットのアップデートタイプAPIの呼び出しを選択します。パッケージSFM_SECRET_UTILに含まれるファンクションUPDATE_SECRETを呼び出します。


ファンクションの結果としてバージョン番号が返されます。アイテムP1_CURRENT_VERSION_NUMBERに設定します。通常、現在のバージョン番号より1つ大きい値になります。


パラメータp_keyの設定はCREATEと同じです。

パラメータp_secret_idとしてページ・アイテムP1_SECRET_IDの値が渡されます。ボタンCREATEを押したときに、ページ・アイテムP1_SECRET_IDには、作成されたシークレットのOCIDが設定されています。


ボタンGETのクリックに対応したプロセスを作成します。

識別名前暗号キーの取り出しタイプAPIの呼び出しを選択します。パッケージSFM_SECRET_UTILに含まれるファンクションGET_KEY_FROM_SECRETを呼び出します。


ファンクションの結果として暗号化キーがRAW型で返されます。パラメータデータ型VARCHAR2を選択しているため、暗黙でファンクションrawtohexが実行されてページ・アイテムP1_KEYに値が設定されます。

そのためP1_GENERATED_KEYP1_KEYは同じ表示になります。


パラメータp_secret_nameにはP1_SECRET_NAMEが渡されます。


パラメータp_secret_idおよびp_version_numberは出力パラメータで、それぞれページ・アイテムP1_SECRET_IDP1_CURRENT_VERSION_NUMBERに設定されます。

ボタンDELETEのクリックに対応したプロセスを作成します。

識別名前シークレットの削除タイプAPIの呼び出しを選択します。パッケージSFM_SECRET_UTILに含まれるファンクションDELETE_SECRETを呼び出します。


パラメータp_secret_idには、ページ・アイテムP1_SECRET_IDの値が渡されます。

パラメータP1_TIME_OF_DELETIONはシークレットが実際に削除される日付を指定します。シークレットは即時で削除することはできません。ページ・アイテムP1_TIME_OF_DELETIONも最低でも1日以上立ってから削除されるよう、日付ピッカーにて削除日時を選択します。


上記の中で特に説明のないパラメータの設定は、他のボタンのパラメータと同じ設定になります。

以上でアプリケーションは完成です。実行すると、記事の先頭のGIF動画のように、パッケージのコードの動作確認ができます。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/oci-secret-plsql-sdk.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。