TL;DR

  • Autonomous AI Database (ADB) から OCI Functions などを呼び出す際、リソース・プリンシパル を使うと認証情報の管理が不要になります。
  • IAM ポリシーと動的グループで権限を制御するため、セキュアかつ運用負荷が低いです。
  • DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL() で有効化するだけで、すぐに使い始められます。

背景:DB の中からOCIサービスを呼び出したい!

最近、OCI の Autonomous AI Database を触る機会が増えています。このサービス、単なるデータベースではなく、データベースの中で AI エージェントを動かしたり、他の OCI サービスとシームレスに連携したりできるのが非常に強力です。

先日開催された「Oracle AI デモ選手権」では、AI アシスタントが複数のサービスをオーケストレーションして分析結果を出すデモを作成しました。
(アーキテクチャの詳細は、こちらの記事「Oracle AI Demo選手権 — OCI上でマルチモーダルAIを組み合わせたアーキテクチャの紹介」で詳しく解説しています!)

アーキテクチャ全体構成図

アーキテクチャ図の以下の箇所で、ADBからOCI Functionsを呼び出しています。

ADBtoFn

そこで課題になったのが「認証情報の管理」です。

資格情報の管理、面倒ではないですか?

DB から外部サービスに接続する場合、通常は以下のような方法をとります。
1. 資格情報オブジェクトの作成: ユーザの API キーやトークンを DBMS_CLOUD.CREATE_CREDENTIAL で登録する。

しかし、この方法だと鍵の更新(ローテーション)が必要になりますし、DB 内に認証情報を保持すること自体、セキュリティポリシー的に避けたいケースもありますよね。

そこで登場するのが 「リソース・プリンシパル」 です。

リソース・プリンシパルとは?

リソース・プリンシパルを利用すると、ADB インスタンス自体が、 OCI サービスに対して自身を認証できるようになります。一時的なセッショントークンが自動的に発行・更新されるため、私たちがパスワードや秘密鍵を管理する必要は一切ありません。

ADB においては、以下の呼び出し方法でリソース・プリンシパルを利用可能です。

  • DBMS_CLOUD プロシージャおよびファンクション: 資格証明引数(credential_name)を取るものすべて
  • Oracle Cloud Infrastructure PL/SQL SDK API: OCI サービスを操作するための各種 API

 

以下のフロー図の流れで、ADBがリソース・プリンシパルを利用して、OCI Functionsを呼び出します。

ADBリソース・プリンシパル利用フロー

実装手順:やってみた

実際に ADB から OCI Functions を安全に呼び出すまでの手順をまとめます。

1. OCI 側の設定(IAM)

まずは「どの ADB が」「何の権限を持つか」を IAM で定義します。

動的グループの作成
特定の ADB インスタンスを識別するためのグループを作成します。

  • 一致ルールの例(特定のインスタンスを指定):
resource.id = 'ocid1.autonomousdatabase.oc1..xxxx'

※末尾の xxxx は、実際のインスタンスの OCID に置き換えてください。

ポリシーの定義
作成した動的グループに対して、Functions の実行権限(fn-invocation)を付与します。

  • ポリシー例:
Allow dynamic-group <動的グループ名> to use fn-invocation in compartment <コンパートメント名>

2. ADB でリソース・プリンシパルを有効化

次に、DB 側でこの機能を使えるようにします。ADMIN ユーザで以下のコマンドを実行するだけです。

-- 特定のユーザ(例: AIDEMO_APP)に許可する場合
EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL(username => 'aidemo_app');

これで、このユーザは OCI$RESOURCE_PRINCIPAL という名前の特別な資格情報が使えるようになります。

3. PL/SQL から呼び出し検証

準備が整ったので、実際に DBMS_CLOUD.SEND_REQUEST を使って Functions を叩いてみます。

DECLARE
l_uri VARCHAR2(1000) := 'https://xxxx.functions.oci.oraclecloud.com/.../actions/invoke';
l_body CLOB := '{"request_id": 123}';
l_response DBMS_CLOUD_TYPES.RESP;
BEGIN
-- 資格情報名に 'OCI$RESOURCE_PRINCIPAL' を指定するのがポイント!
l_response := DBMS_CLOUD.SEND_REQUEST(
credential_name => 'OCI$RESOURCE_PRINCIPAL',
uri => l_uri,
method => 'POST',
body => UTL_RAW.CAST_TO_RAW(l_body)
);

DBMS_OUTPUT.PUT_LINE('Status Code: ' || l_response.status_code);
DBMS_OUTPUT.PUT_LINE('Response: ' || DBMS_CLOUD.GET_RESPONSE_TEXT(l_response));
END;
/

実行結果

「Oracle AI デモ選手権」で作成した、商品の売上分析をオーケストレーションする Functions を呼び出した結果がこちらです。

Status Code: 200
Response: {"status": "success", "analysis": "売上不振の主な原因は次の3点です。1. 競合商品との価格差..."}

無事に、DB 内の PL/SQL から外部の Functions を実行し、分析結果を受け取ることができました!

まとめ:安全・簡単・スマート

リソース・プリンシパルを使うことで、「資格情報を埋め込まない」 というセキュリティのベストプラクティスを、非常に簡単に実現できました。

特に AI 系の実装では、DB、ストレージ、関数、生成 AI サービスなど、多くのコンポーネントを連携させる必要があります。そのたびに API キーを発行して回るのは非効率ですしリスクもあります。

これからは 「リソース・プリンシパル + IAM ポリシー」 による管理を標準にしていきたいですね。

参考