Deep Data Securityによるエンド・ユーザーのメモリー分離の実施

このガイドでは、OCI IAMおよびOracle Deep Data Securityを使用したOracle AI Agent Memoryアプリケーションのエンドユーザー分離を適用する方法について説明します。

警告:学習環境のみ。この例を本番環境にデプロイしないでください。

アプリケーションでは、Flaskの開発サーバー、インメモリー・セッション・ストア、環境ファイル・シークレットおよび簡略化されたトークン・ライフサイクル処理を使用します。データベース設定スクリプトは、データベース全体のアイデンティティ・プロバイダ設定および権限を変更します。使い捨てユーザーと、分離された非本番Oracle Autonomous AI Databaseのみを使用してください。

このガイドでは、意図的に小さいWebアプリケーションを作成します。

このルートは、アリスとボブ自身を比較するものではありません。エンド・ユーザー・トークンをOracle AI Databaseに渡します。Oracle Deep Data Securityでは、エージェント・メモリーの独自行ポリシーが強制されます。

このガイドでは、1つのデプロイメントを示します。サポートされているすべてのポリシー、プリンシパル、管理関数、ランタイム・コンテキストAPI、監査および失効タイミングを含む完全なセキュリティ機能については、ディープ・データ・セキュリティAPIおよびセキュリティ・リファレンスを参照してください。

このガイドでは、次のことを行います。

信頼チェーンの理解

ブラウザとアプリケーションでは、次の2つの異なるOAuthアクセス・トークンを使用します。

  1. エンドユーザー・トークンは、AliceまたはBobを識別し、ユーザーのIAMグループを含みます。
  2. クライアント資格証明を介して機密アプリケーションによって取得されるデータベース・アクセス・トークンは、アプリケーションがデータベース・リソースにアクセスできることを証明します。

Oracle AI Databaseは、エンドユーザー・セキュリティ・コンテキストをアタッチする前に両方のトークンを検証します。

Oracleは、この2トークン・モデルを「認証フローと前提条件の理解」に、および「エンドユーザー・セキュリティ・コンテキスト」の完全なライフサイクルを文書化します。

前提条件

必要なもの:

Oracle Deep Data Securityは、データベース強制のファイングレイン認可です。「Oracle Deep Data Securityとは」を参照してください。

OCI IAMアイデンティティ・ドメインの構成

すべてのOCI IAMを1つのアイデンティティ・ドメインで実行します。ドメインURL(https://idcs-<id>.identity.oraclecloud.com:443など)を記録します。

認可的なOracleウォークスルーは、アプリケーションメディエート・アクセス用のOCI IAMの構成です。次の例の値は、このガイドに付属する環境ファイルの例と一致しています。

データベース・リソースを登録します

「アイデンティティ・ドメイン」→「統合アプリケーション」で、次の手順を実行します。

  1. OracleDBという名前の「機密アプリケーション」を追加します。
  2. リソース・サーバーとして構成します。
    • プライマリ・オーディエンス: OracleDB
    • スコープ: DB_ACCESS_SCOPE
  3. クライアントとして構成し、クライアント資格証明を許可します。
  4. アクティブ化
  5. 「アプリケーションID」、「クライアントID」および「クライアント・シークレット」を記録します。

完全修飾データベース・スコープは、オーディエンスとスコープ名を連結したものです。

OracleDBDB_ACCESS_SCOPE

現在のコンソールのラベルおよびフィールドの説明は、OCI IAMへのデータベースの登録に従ってください。

Webアプリケーションの登録

OracleAgentMemoryWebという名前の2番目の機密アプリケーションを追加します:

  1. 「権限付与を認可として実施」を有効にします。
  2. リソース・サーバーとして構成します。
    • プライマリ・オーディエンス: OracleAgentMemoryWeb
    • スコープ: APP_ACCESS_SCOPE
    • アクセス・トークンの存続期間: この演習では3600秒
  3. 次の権限が付与されたクライアントとして構成します。
    • 認可コード
    • クライアント資格証明
  4. この正確なリダイレクトURLを追加します。
    http://127.0.0.1:8000/auth/callback
  5. クライアント・リソースの下で、次の両方へのアクセス権を付与します。
    • OracleDBDB_ACCESS_SCOPE
    • OracleAgentMemoryWebAPP_ACCESS_SCOPE
  6. アプリケーションをアクティブ化し、そのクライアントIDおよびクライアント・シークレットを記録します。

アプリケーションでは、認可コードをstateおよびPKCE S256とともに使用します。OCI IAMは、OCI IAMへのアプリケーションの登録に必要なクライアント構成をドキュメント化し、PKCE認可コードの例を提供します。

グループ要求を追加します。

Oracle AI Databaseは、エンドユーザー・トークンのgroup要求から外部マップされたデータ・ロールをアクティブ化します。OCI IAMカスタム・クレームは、コンソールではなくアイデンティティ・ドメインREST APIを介して構成されます。

Identity Domain Administratorとして、アイデンティティ・ドメインAPIを起動できる存続期間の短い個人アクセス・トークンをダウンロードします。その後、次のコマンドを実行します。

export OCI_IAM_DOMAIN_URL='https://<identity-domain-host>:443'
export OCI_IAM_ADMIN_TOKEN='<short-lived-personal-access-token>'

curl --fail-with-body \
  -X POST "$OCI_IAM_DOMAIN_URL/admin/v1/CustomClaims" \
  -H "Authorization: Bearer $OCI_IAM_ADMIN_TOKEN" \
  -H "Content-Type: application/scim+json" \
  -d '{
    "schemas": [
      "urn:ietf:params:scim:schemas:oracle:idcs:CustomClaim"
    ],
    "name": "group",
    "value": "$user.groups.*.display",
    "expression": true,
    "mode": "always",
    "tokenType": "AT",
    "allScopes": true
  }'

リクエストが成功すると、HTTP 201が返されます。ドメインにすでにこの要求がある場合は、複製を作成しないでください。OCI IAMでのグループ情報のカスタム・クレームの構成を参照してください。

Alice、Bobおよびアプリケーション・グループの作成

  1. ORACLEAGENTMEMORY_USERSというグループを作成します。
  2. テスト・ユーザーaliceおよびbobを作成します。
  3. 両方のユーザーをORACLEAGENTMEMORY_USERSに割り当てます。
  4. グループをOracleAgentMemoryWebに割り当てます。

データベースは後でこのグループ名をデータ・ロールにマップします。グループ名は大/小文字を区別せずに比較されますが、設定全体で同じスペルを使用します。OCI IAMでのユーザーの作成およびグループの割当てを参照してください。

環境を準備します

完全なWebアプリケーションdeepsec_oci_iam_webapp.zipをダウンロードします。このアーカイブには、この例が所有するスタンドアロン・データベースの設定および検査スクリプトも含まれています。SDKテスト・スイートからスクリプトをインポートまたはパッケージ化しません。

アーカイブを抽出し、そのプロジェクト・ディレクトリを入力し、ローカル設定およびランタイム環境ファイルを作成します。

unzip deepsec_oci_iam_webapp.zip
cd deepsec_oci_iam_webapp
cp deepsec.env.example .deepsec.env
cp deepsec.runtime.env.example .deepsec.runtime.env
python -c "import secrets; print(secrets.token_hex(32))"

生成された値をOAM_WEB_SECRET_KEYに配置し、必要なすべてのプレースホルダを両方のファイルに移入します。どちらのファイル名もGitによって無視されます。

database_scriptsディレクトリには、次のものが含まれます。

ファイル 職責
_common.sh .deepsec.envをロードし、必要な値を検証し、SQL*Plusをチェックし、構成時にTNS_ADMINをエクスポートするプライベート・ヘルパー。直接実行しないでください。
db_ociiam_setup.sh ターゲットAutonomous AI DatabaseのOCI IAM外部認証を有効にし、OCI_IAM_DOMAIN_DB_CRED$を置き換えます。
db_deepsec_user_setup.sh スキーマ所有者およびアプリケーション・プール・ユーザーを作成し、文書化された権限許可リストを付与します。
db_list_all_data_roles.sh ディープ・データ・セキュリティ・ロール、IAMマッピング、データ権限、述語、保護オブジェクト、エンド・ユーザーおよびアプリケーション・アイデンティティの読取り専用検査を実行します。

.deepsec.envは、データベース設定でのみ使用されます。セキュリティ管理者およびスキーマ所有者のパスワードが含まれます。.deepsec.runtime.envはFlaskプロセスによってロードされ、両方の特権パスワードを意図的に除外します。設定ファイルを、Webアプリケーションを起動するシェルにエクスポートしないでください。異なるパスを使用するには、設定にOAM_DEEPSEC_ENV_FILEを、WebプロセスにOAM_WEB_ENV_FILEを設定します。

重要なIAM値は、次のようにマップされます:

環境変数 OCI IAM値
OAM_DEEPSEC_OCI_DB_APP_ID データベース・アプリケーションのアプリケーションID
OAM_DEEPSEC_OCI_DB_CLIENT_ID データベース・アプリケーションのクライアントID
OAM_DEEPSEC_OCI_DB_CLIENT_SECRET データベース・アプリケーションのクライアント・シークレット
OAM_WEB_OCI_CLIENT_ID WebアプリケーションのクライアントID
OAM_WEB_OCI_CLIENT_SECRET Webアプリケーションのクライアント・シークレット
OAM_WEB_OCI_END_USER_SCOPE OracleAgentMemoryWebAPP_ACCESS_SCOPE
OAM_WEB_OCI_DATABASE_ACCESS_SCOPE OracleDBDB_ACCESS_SCOPE

OAM_DEEPSEC_CONFIG_DIRは、DSNがTNS別名で、tnsnames.oraが検出できない場合にのみ必要です。Walletの場所およびパスワードは、sqlnet.oraおよびDSNがすでにpython-oracledbに必要なすべてを提供している場合、オプションです。Autonomous AI Database接続オプションについては、Walletを使用したPythonアプリケーションの接続を参照してください。

埋込みプロバイダも構成します。アプリケーションではメモリーのみがリストおよび追加されますが、エージェント・メモリーはメモリー・コンテンツを格納するときに埋込みを作成します。テンプレートでは、OpenAI互換モデルを例として使用し、モデル、APIベース、キーおよびディメンションをプロバイダの値に置き換えます。

3つのデータベース・アカウントの構成

警告:この項のコマンドは、データベース全体の外部認証設定およびアカウント権限を変更します。最初にスクリプトを調べます。共有データベースまたは本番データベースに対して実行しないでください。

3つの異なるデータベース・ユーザーを使用します。

職責 アカウントの例 許可された作業
セキュリティ管理者 ADMIN OCI IAM統合を有効にし、データ・ロールおよびデータ権限を作成、付与、取消し、リストおよび削除します。Webリクエストには使用されません。
管理対象スキーマの所有者 OAM_SCHEMA_OWNER エージェント・メモリー表、索引、プロシージャおよびスケジューラ・ジョブを作成します。スキーマ・ライフサイクル操作にのみ使用されます。
アプリケーションDBユーザー OAM_APP_DB_USER セッションを開き、エンド・ユーザーのセキュリティ・コンテキストをアタッチします。通常のSELECT、INSERT、UPDATEまたはDELETE権限を受け取りません。

この分離により、有効なエンド・ユーザー・コンテキストがないリクエストは失敗クローズされます。Oracleのデータベース構成ガイドでは、接続プール・アカウントにCREATE SESSIONおよびCREATE END USER SECURITY CONTEXTを推奨しています。IAM統合のためのデータベースの構成を参照してください。

この例では、設定にAutonomous AI Database ADMINアカウントを使用します。カスタム・セキュリティ管理者アカウントは、2人のデータベース・ユーザーを作成および変更し、リストされたシステム権限を付与できる必要があります。エージェント・メモリー表は別のスキーマに属するため、ポリシー管理には、管理者自身のスキーマ内のCREATE DATA GRANTのみでなく、CREATE ANY DATA GRANT、DROP ANY DATA GRANTおよびADMINISTER ANY DATA GRANTが必要です。また、ポリシーで使用されるデータ・ロールを作成および削除する権限も必要です。

OCI IAMトークン検証の有効化

次の内容を確認して実行します。

bash database_scripts/db_ociiam_setup.sh

このスクリプトは、セキュリティ管理者として接続し、次のことを行います。

アクティブにできる外部アイデンティティ・プロバイダは1つのみです。このサンプル・スクリプトでは、force => TRUEを使用してOCI IAMパラメータを更新すると、別の外部認証構成が中断される可能性があります。Oracleは、IAM統合のためのデータベースの構成でAutonomous Databaseの正確なコールをドキュメント化します。

所有者およびプール・ユーザーの作成

次の内容を確認して実行します。

bash database_scripts/db_deepsec_user_setup.sh

スクリプトはADMINを変更しません。所有者およびアプリケーション・プール・ユーザーを作成し、次の権限を付与します。

-- Managed-schema owner
CREATE SESSION, CREATE TABLE, CREATE SEQUENCE,
CREATE VIEW, CREATE PROCEDURE, CREATE JOB

-- Runtime application pool
CREATE SESSION, CREATE END USER SECURITY CONTEXT

所有者は、Autonomous AI DatabaseのDATA表領域で割当て制限を受け取ります。プール・ユーザーは、所有者の表に対する直接の権限を受け取りません。例を必要な文にフォーカスしたままにするために、スクリプトは既存のユーザーをチェックしたり、現在の権限を調べたりしません。新しいアカウント名を使用します。ユーザーがすでに存在するか、別のSQL文が失敗すると、スクリプトは停止します。

ストアおよび独自行ポリシーの作成

スタンドアロンのサンプル環境をインストールします。

uv sync

その後、次の設定プログラムを実行します。

uv run python scripts/setup_memory.py

このコマンドは、OAM_WEB_MEMORY_STORE_IDに対してのみ意図的に破壊的です。これは、次のように使用されます。

  1. スキーマ所有者として接続し、エージェント・メモリー・スキーマを再作成します。
  2. セキュリティ管理者として接続し、独自行ポリシーを追加し、それをORACLEAGENTMEMORY_USERSに付与します。

addおよびgrant管理コールは冪等です。再実行すると、同じ管理対象ポリシーの定義および割当てが置換され、中断された試行によって残された部分管理DDLの修復が再試行されます。

このポリシーでは、OCI IAMグループの外部マップされたデータ・ロールと、行述語が格納されているuser_id値をORA_END_USER_CONTEXT.usernameと比較するデータ権限が作成されます。Oracleでは、CREATE DATA ROLEのマッピング構文およびデータ権限の作成の行認可がドキュメント化されています。

結果を調べます。

bash database_scripts/db_list_all_data_roles.sh

IAMマップされたロール、エージェント・メモリー・データ権限および保護された所有者スキーマ表が表示されます。この検査スクリプトはカタログ・ビューのみを問い合せます。ディープ・データ・セキュリティ・オブジェクトの作成、変更または削除は行いません。

Deep Secを使用したデータベース内埋込みモデルの使用

この項は、アプリケーションがOracleDBEmbedderをデフォルトのprovider="database"とともに使用し、Oracle AI Databaseに格納された埋込みモデル(通常はDMUSER.DOC_MODELなどのインポートされたONNXモデル)を使用する場合に適用されます。この構成では、直接埋込みはOracleのVECTOR_EMBEDDING SQL演算子を使用するため、モデルには次に説明するSELECT ON MINING MODEL権限が必要です。

OracleDBEmbedderでは、DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGを介したリモート・プロバイダもサポートされます(たとえば、provider="openai")。これらの構成では、Oracle AI Databaseからの埋込みリクエストは引き続き呼び出されますが、データベース常駐マイニング・モデルにはアクセスしません。この項のSELECT ON MINING MODEL手順は適用されません。エージェント・メモリー操作は、引き続きOracleMemoryEndUserSecurityContext内で実行する必要があります。

エージェント・メモリー・ポリシーは、エージェント・メモリー表へのアクセス権を付与します。Oracle AI Database埋込みモデルへのアクセス権を付与しません。モデルには、SELECT ON MINING MODELという独自のデータベース権限が必要です。

その権限をアプリケーション・プール・ユーザーに付与しないでください。リクエスト中、Deep Secは、プール・ユーザーの通常の権限ではなく、OCI IAMグループからマップされたデータ・ロールを介してユーザーを認可します。したがって、プール・ユーザーにのみ付与された権限は、エンドユーザー・セキュリティ・コンテキストがアクティブな間は使用できません。

モデルを使用する必要があるIAMグループごとに、マップされたデータ・ロールを1つ作成します。そのデータ・ロールに、モデルにアクセスできる通常のデータベース・ロールを付与します。次のSQLをデータベース・セキュリティ管理者として実行するか、ロールを作成してモデルへのアクセス権を付与する権限のある別のアカウントとして実行します。サンプル名をアプリケーションの名前に置き換えます。

-- This must exactly match the OCI IAM group passed to OciGroupPrincipal.
CREATE DATA ROLE APP_MEMORY_USERS_DATA_ROLE
  MAPPED TO 'IAM_OAUTH_GROUP=YOUR_IAM_GROUP';

-- This ordinary database role carries access to one embedding model.
CREATE ROLE APP_DOC_MODEL_ROLE;

GRANT SELECT ON MINING MODEL YOUR_USER.DOC_MODEL
  TO APP_DOC_MODEL_ROLE;

-- Give model access to the IAM group's Deep Sec data role.
GRANT APP_DOC_MODEL_ROLE TO APP_MEMORY_USERS_DATA_ROLE;

アプリケーションは、エージェント・メモリー・ポリシーを付与するときに同じグループ名を使用します。

grant_agent_memory_policies(
    admin_connection,
    owner_schema="OAM_SCHEMA_OWNER",
    memory_store_id="MEMORY",
    principals=[OciGroupPrincipal("YOUR_IAM_GROUP")],
    policies=[UserOwnRowsDeepDataSecurityPolicy()],
)

grant_agent_memory_policies()は、YOUR_IAM_GROUPにマップされた既存のロールを検索し、その同じロールにエージェント・メモリー表データ権限を追加します。2番目のロールは作成されません。実行時に、OCI IAMトークンにYOUR_IAM_GROUPが含まれるユーザーは、許可されたエージェント・メモリー行とDMUSER.DOC_MODELの両方にアクセスできます。

このモデル設定の前にアプリケーションがgrant_agent_memory_policies()をすでにコールしている場合、エージェント・メモリーはマップされたデータ・ロールをすでに作成しています。同じグループに別のマップ済ロールを作成しないでください。既存のロールを検索し、かわりに通常のモデル・ロールを付与します。

SELECT data_role
FROM sys.dba_data_roles
WHERE UPPER(mapped_to) = UPPER('IAM_OAUTH_GROUP=YOUR_IAM_GROUP');

GRANT APP_DOC_MODEL_ROLE TO <DATA_ROLE_RETURNED_BY_THE_QUERY>;

すべての実行時のOracleDBEmbedder操作をOracleMemoryEndUserSecurityContext内に保持します。スキーマ所有者、個別の管理者接続、またはエンド・ユーザー・セキュリティ・コンテキストのない接続を使用して、ユーザー・リクエストの埋込みを実行しないでください。これにより、Deep Sec認証境界がバイパスされます。

アプリケーションの理解

ダウンロード可能なプロジェクト deepsec_oci_iam_webapp.zipには、完全なWebアプリケーションおよびデータベーススクリプトが含まれています。主な用途は意図的に小さい。

OAuthの起動および完了

ログイン・ルートは、ランダムなstateおよびPKCE値を作成します。不透明なセッションIDのみがHttpOnlyのSameSite=Lax Cookieに配置され、トークンはプロセス・ローカルのデモ・セッション・ストアに残ります。

def start_authorization(config: RuntimeConfig) -> AuthorizationRequest:
    """Build a state-bound Authorization Code request with PKCE."""
    state = secrets.token_urlsafe(32)
    code_verifier = secrets.token_urlsafe(64)
    challenge = (
        base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest())
        .rstrip(b"=")
        .decode("ascii")
    )
    query = urllib.parse.urlencode(
        {
            "client_id": config.oauth_client_id,
            "response_type": "code",
            "redirect_uri": config.redirect_uri,
            "scope": config.end_user_scope,
            "state": state,
            "code_challenge": challenge,
            "code_challenge_method": "S256",
        }
    )
    return AuthorizationRequest(
        url=f"{config.domain_url}/oauth2/v1/authorize?{query}",
        state=state,
        code_verifier=code_verifier,
    )


def exchange_authorization_code(
    config: RuntimeConfig,
    code: str,
    code_verifier: str,
) -> EndUserToken:
    """Exchange one browser authorization code for an end-user token."""
    payload = _token_request(
        config,
        {
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": config.redirect_uri,
            "code_verifier": code_verifier,
        },
    )
    access_token, expires_at = _required_access_token(payload)
    return EndUserToken(
        access_token=access_token,
        username=_display_username(access_token),
        expires_at=expires_at,
    )

コールバックでは、stateが一定時間比較され、同じリダイレクトURIおよびPKCEベリファイアでコードが交換されます。アプリケーションは、データベース・アクセス・トークンを個別に取得します。

    def get(self, config: RuntimeConfig) -> str:
        """Return a current database-access token."""
        with self._lock:
            if self._token is not None and time.time() < self._expires_at - 60:
                return self._token
            payload = _token_request(
                config,
                {
                    "grant_type": "client_credentials",
                    "scope": config.database_access_scope,
                },
            )
            self._token, self._expires_at = _required_access_token(payload)
            return self._token

OCI IAMは、OCI IAM構成の検証で両方のトークン・リクエストをドキュメント化します。

すべてのエージェント・メモリー操作のスコープ指定

アプリケーションは、両方のトークンをpython-oracledbエンド・ユーザー・セキュリティ・コンテキストに結合します。次に、OracleMemoryEndUserSecurityContextを使用して、すべてのストアの初期化および操作をスコープ指定します。

def list_visible_memories(
    config: RuntimeConfig,
    pool: Any,
    user_context: Any,
) -> list[Any]:
    """List rows visible to the effective OCI IAM end user."""
    with OracleMemoryEndUserSecurityContext(user_context):
        store = create_runtime_store(config, pool)
        return store.list("memory", limit=100)


def add_memory(
    config: RuntimeConfig,
    pool: Any,
    user_context: Any,
    content: str,
    target_username: str,
) -> None:
    """Attempt to insert a row for the username supplied by the browser."""
    with OracleMemoryEndUserSecurityContext(user_context):
        store = create_runtime_store(config, pool)
        store.add(
            contents=[content],
            record_type="memory",
            user_ids=[target_username],
        )

スキーマの作成、検証、アップグレードおよび再作成はスキーマ所有者設定パスに属するため、ランタイム・ストアはSchemaPolicy.NO_CHECKを使用します。エンド・ユーザー・コンテキストがアクティブである間、SDKは別のスキーマ・ポリシーを拒否し、コンテキストがアクティブでない場合、この保護されたランタイム・ストアに対する後の操作を拒否します。セキュリティ管理機能も同様に、エンド・ユーザー・コンテキストを保持する接続を拒否します。

エージェント・メモリー・データベース操作ごとに、コンテキスト・マネージャは次を実行します。

プールのデータベース・アカウントには、フォールバック表権限がありません。python-oracledbペイロードAPIについては、「エンドユーザー・セキュリティ・コンテキスト・ペイロードの作成」を参照してください。ディープ・データ・セキュリティAPIおよびセキュリティ・リファレンスでは、コンテキスト・マネージャの完全な契約について説明します。

データベースを決定

ルートは、送信されたユーザー名を変更せずに転送します。データベース・エラーをキャッチしてサニタイズしますが、username == signed_in_user認可ブランチは含まれません。

@web.route("/", methods=["GET", "POST"])
def index() -> Response | tuple[str, int]:
    """Show visible memories and let the user attempt one insert."""
    config, pool, _ = _extensions()
    _, session = _session()
    if session is None or session.end_user_token is None:
        return render_template("index.html", session=None, memories=[])

    message = None
    status = 200
    try:
        user_context = _security_context(config, session)
        if request.method == "POST":
            if not hmac.compare_digest(
                request.form.get("csrf_token", ""),
                session.csrf_token,
            ):
                return render_template("error.html", message="The form expired."), 400
            content = request.form.get("content", "").strip()
            target_username = request.form.get("username", "").strip()
            if not content or not target_username:
                message = "Content and username are required."
                status = 400
            elif len(content) > 4000 or len(target_username) > 255:
                message = "The submitted memory is too large."
                status = 400
            else:
                try:
                    add_memory(
                        config,
                        pool,
                        user_context,
                        content,
                        target_username,
                    )
                    message = "Memory added."
                except oracledb.DatabaseError:
                    #Keep listing permitted rows after the deliberately denied write.
                    message = "Oracle AI Database denied this operation for the effective end user."
                    status = 403

        memories = list_visible_memories(config, pool, user_context)
    except oracledb.DatabaseError:
        #Never expose raw database errors, token contents, or submitted values.
        message = "Oracle AI Database denied this operation for the effective end user."
        memories = []
        status = 403
    except OAuthError:
        message = "The login session expired. Sign in again."
        memories = []
        status = 401

    return (
        render_template(
            "index.html",
            session=session,
            memories=memories,
            message=message,
        ),
        status,
    )

Jinjaは表示されたメモリー・コンテンツをエスケープします。RAWデータベース例外、OAuthレスポンス、トークンおよび送信された値はレンダリングされません。

アプリケーションを実行および検証します

Flask開発サーバーを起動します。

uv run python run.py

http://127.0.0.1:8000を開きます。

承認境界を確認します。

  1. Aliceとしてサイン・インします。
  2. 事前入力されたユーザー名aliceでAlice's first memoryを追加します。
  3. メモリーが「Visible memories」の下に表示されていることを確認します。
  4. Alice tries to write for Bobを追加しますが、ユーザー名をbobに変更します。
  5. Oracle AI Databaseが操作を拒否していることを確認します。
  6. サインアウトし、Bobとしてサインインし、Aliceのメモリーが表示されないことを確認します。
  7. Bobとしてメモリーを追加し、Aliceとして再度サインインして、Bobのメモリーが表示されないことを確認します。

これは、2つの独立したコントロールを示しています。

本番運用では、組織が保持する必要があるDeep Sec管理およびエンド・ユーザーのセキュリティ・コンテキスト・アクションに対してOracle Unified Auditingを構成します。また、ドキュメント化された失効時間契約についても説明します。SDKポリシーの失効は、管理コールが戻る前にコミットされますが、OCI IAMグループからユーザーを削除しても、すでに発行されているアクセス・トークンはリライトされません。監査のガイダンス、トークン有効期限の動作、および対応するOracle Deep SecおよびOCI IAMドキュメントへのリンクについては、ディープ・データ・セキュリティを参照してください。

ログインは成功したが、データベースがすべての操作を拒否する場合は、エンド・ユーザー・トークンを調べて、groupにORACLEAGENTMEMORY_USERSが含まれていることを確認します。OracleのDeep Data Securityのアクセスおよび権限のトラブルシューティングでは、管理者がアクティブ・データ・ロールを検査する方法についても説明します。

生産に必要なもの

警告:このガイドを完了しても、サンプルは本番環境に対応していません。

設計を適応させる前に、少なくとも次のものを交換または追加してください。

コア不変を保持します。つまり、ランタイム・プール・アカウントには直接表DML権限がなく、すべてのエージェント・メモリー・リクエストが検証済のOracleMemoryEndUserSecurityContext内で実行されます。