前回は、データベースに自分のPCから各種ツールを使ってIdP経由でデータベースにログインするダイレクト・アクセスという方式について紹介しました。今回は、このDeep Data Securityをアプリケーションにどう実装してくかという観点で考えてみたいと思います。
一概にアプリケーションといえど多種多様な種類がありますが、例えば、ERPやSCMような業務アプリケーション、BtoC向けのWebアプリケーション、DWHなどのデータ分析、最近ではEnterprise AIなど多岐に渡ります。それらがOracle Databaseをデータストアとして使用する場合、単一の代表ユーザーがアプリケーションに必要なひと通りすべてのデータにアクセスできる権限を持ち、アプリケーション側でデータ表示の制御をしていることは一般的な手法ではないでしょうか?
以前からこの共有ユーザーの権限の集中というのは課題になっていました。最近では、MCPサーバーでデータベース内を容易かつ網羅的にアクセスできてしまうことから、権限の集中したアカウントからの情報漏洩リスクはより差し迫ってきているのではないかと思います。
Deep Data Securityは、エンドユーザーを対象にしたアクセス制御の機能です。アプリケーションは必ずユーザー認証というプロセスがあるはずので、その認証されたユーザー自身でデータベースにアクセスして必要なデータだけを参照できるというのが理想です。これを実現する方法としては、前回紹介した エンドユーザー・セキュリティ・コンテキストを使用します。
エンドユーザー・セキュリティ・コンテキストとは、エンドユーザーのアイデンティや属性情報を格納しており、IdPからのアクセストークンによって生成できます。これをアプリケーション内で明示的にデータベース・セッションに対してアタッチすることで、あたかも既存のデータベース・ユーザーのセッションをIdPのエンド・ユーザーに差し替えてSQLを実行するということが可能です。この方法についてIdPをEntra IDとした場合の紹介したいと思います。
エンドユーザー代理によるデータベース・アクセス
Deep Data Securityでは、Idp(Entra ID / OCI IAM)、アプリーション、データベースのそれぞれの関係において、このエンドユーザー・セキュリティ・コンテキストを渡す二つのアクセスがあります。まず、OBOフローによるデータベース・アクセスです。
このスライドでは、アプリケーションはコネクションプーリング等でデータベースに接続する仕組み(赤線の部分)を実装しているとします。marvinというエンドユーザー(IdPユーザー)でログインすると、アプリケーションはユーザー認証をIdPに任せ、marvinのユーザー・トークンを取得します。そしてこのユーザー・トークンを使用して、 エンドユーザーの代理としてデータベースのアクセス・トークンを取得します。なので、データベースへのアクセスの主体はエンドユーザー自身です。
この二つのトークンからエンド・ユーザー・セキュリティ・コンテキストを生成し、それをデータベースセッションにアタッチします。そうすると、セッションはmarvinというエンドユーザーに切り替わり、Deep Data Securityの定義されたデータロールが付与され、データ権限に基づいてアクセス制御されるという流れになります。
実際にプログラム内でやることは、例えば、Javaの場合、以下のようにoracle.jdbc.EndUserSecurityContextクラスをアプリケーションに実装します。Pythonや.NET、各フレームワークにも実装方法が用意されています。
コネクションプーリングの場合、プールから借りてきたコネクションにエンドユーザー・セキュリティ・コンテキストをアタッチして、エンド・ユーザーとしてSQLを実行する。そして、コネクションを返す際に忘れずにデタッチする。
データベースのセッションを張りなおすのではなく、再利用することで接続コストを抑えつつ、エンドユーザー・レベルでのアクセス制御を実現します。
アプリケーション主体によるデータベース・アクセス
もうひとつは、アプリケーション主体によるアクセスという方式があります。
違いとしては、エンドユーザー代理の場合、ユーザートークンからデータベースのトークンを取得しました。今回はデータベースのトークンは、サービスプリンシパルで取得します。
Entra ID の「サービスプリンシパル(Service Principal)」は、アプリケーション用のID(アカウント)のこと。人間がログインする時は「ユーザーアカウント」を使いますが、アプリ・スクリプト・CI/CD・自動処理が Entra ID に認証するときに使うのがサービスプリンシパルです。
一方でEntra IDへの認証からユーザートークンを取得するというフローは変わらず、これで必要なユーザー・トークンとデータベース・トークンは一通り揃います。そして、ユーザー認証時に使用したEntra IDのアプリケーション ID (スライドではfrontapp)自身に対してもApplication Identityを割り当てることでデータロールをマッピングさせるということが可能です。
Application Identityとは、IdPのアプケーションIDにマッピングして、以下のようにローカル・データ・ロールを付与することができます。
#Entra IDのクライアント (アプリケーション) IDを指定して作成
CREATE APPLICATION IDENTITY app_id MAPPED TO 'AZURE_CLIENT_ID=0aa44-78fc-4655-bfac-05f3555';
#データロールの作成
CREATE OR REPLACE DATA ROLE drole_appid;
#データ権限の作成
CREATE OR REPLACE DATA GRANT dg_appid_access ..... TO drole_appid;
#Application Identityにデータ・ロールを付与
GRANT DATA ROLE drole_appid TO app_id;
これによりアプリケーションとユーザーそれぞれのデータロールが最終的にmarvinに付与されたアクセス制御になります。エンドユーザー・セキュリティ・コンテキストの生成からアタッチ以降の流れはOBOの場合と同じです。
使用する複数のアプリケーションがあるとして、エンドユーザーは、アプリケーションそれぞれに指定された基本となるデータロールが必ず割り当てられ、それを補足するようにユーザーの持つデータロールが付与され、それぞれを合わせたデータ権限にてアクセス制御になるというのがユースケースです。
ここではドキュメントに沿うような形であえて区別化するような説明をしました。ただ、IdP側のApplicationはこれ以外にも様々な構成をとることができますし、Application IdentityもOBOで使用できたりと、一概にこれじゃなきゃ駄目ということではなくDeep Data Securityをアプリケーションに実装するための例として参考にして頂ければ幸いです。
また、ドキュメントには、最近Spring Bootのアプリケーションによるチュートリアルが公開されました。このアプリケーションは、上記のアプリケーション主体によるデータベース・アクセスの方式で動作します。
設定手順がちょっと色々面倒ではありますが、正しく設定できれば動作しますので、習うより慣れろでまずは試してみると良いのではないかと思います。
改めて整理すると、Deep Data Securityをどう使うのかによって実装する方式が変わります。下記スライドの左側のように、自身のPC内のツール・アプリケーションを対象にするということであれば、使用者にIdPのユーザーを払い出して、Oracle Databaseの接続設定をパスワード認証からトークン認証に変えることで、Deep Data Securityのデータロールに基づくアクセス制御に切り替えることができます。
AI Agentを組み合わせたエンタープライズ向けのアプリケーションでOracle DatabaseはMPCサーバのリソースの一つということであれば、右側のイラストのようにアプリケーション内でDeep Data Securityを実装するという方向になります。
また、Oracle Databaseが直接OAuth2.0をサポートしているのはEntra IDとOCI IAMですが、SAMLフェデレーションでOktaやAWS等の外部IdPを認証基盤として使用することも可能です。
3回にわたりDeep Data Securityについてご紹介してきました。Oracle AI Database 26ai(23.26.2〜)Standard Editionから利用できる新しいアクセス制御機能を、ぜひ検証・活用いただければと思います。



