Deep Data Security로 최종 사용자 메모리 격리 적용
이 가이드에서는 OCI IAM 및 Oracle Deep Data Security를 통해 Oracle AI Agent Memory 애플리케이션에 대한 최종 사용자 격리를 적용하는 방법을 보여줍니다.
경고: 학습 환경만 해당됩니다. 이 예제를 운용 환경에 배치하지 마십시오.
응용 프로그램은 Flask의 개발 서버, 인메모리 세션 저장소, 환경 파일 암호 및 단순화된 토큰 수명 주기 처리를 사용합니다. 데이터베이스 설정 스크립트는 데이터베이스 차원의 ID 제공자 설정 및 권한을 수정합니다. 일회용 사용자와 격리된 비운용 Oracle Autonomous AI Database만 사용하십시오.
이 가이드는 고의적으로 작은 웹 애플리케이션을 구축합니다.
- 사용자는 OCI IAM OAuth 2.0 권한 부여 코드 플로우로 사인인합니다.
- 이 페이지에는 로그인한 사용자에게 표시되는 메모만 나열됩니다.
- 폼은 메모리를 추가하고 대상
username를 노출합니다. Alice는 Alice의 메모리를 저장할 수 있지만, Oracle AI Database는 Alice의 Bob용 메모리를 저장하려는 시도를 거부합니다.
이 경로는 앨리스와 밥 자체를 비교하지 않습니다. 최종 사용자 토큰을 Oracle AI Database에 전달합니다. Oracle Deep Data Security는 에이전트 메모리 자체 행 정책을 적용합니다.
이 설명서에서는 하나의 배치를 보여줍니다. 지원되는 모든 정책, 주체, 관리 기능, 런타임 컨텍스트 API, 감사 및 취소 타이밍을 포함한 전체 보안 기능은 딥 데이터 보안 API 및 보안 참조를 참조하십시오.
이 설명서에서는 다음 작업을 수행합니다.
- OCI IAM ID 도메인에 데이터베이스 리소스 및 웹 애플리케이션 등록
- 데이터베이스 데이터 롤을 활성화하는 데 사용되는 OCI IAM
group토큰 클레임 추가 - 별도의 보안 관리자, 스키마 소유자 및 애플리케이션 풀 데이터베이스 계정 구성
- 에이전트 메모리 저장소를 생성하고 OCI IAM 그룹에 자체 행 정책 부여
- 웹 응용 프로그램을 실행하고 데이터베이스에 적용된 유저 격리를 확인합니다.
신뢰 체인 이해
브라우저와 애플리케이션은 두 가지 OAuth 액세스 토큰을 사용합니다.
- 최종 사용자 토큰은 Alice 또는 Bob을 식별하며 사용자의 IAM 그룹을 포함합니다.
- 클라이언트 인증서를 통해 기밀 응용 프로그램에서 획득한 데이터베이스 액세스 토큰은 응용 프로그램이 데이터베이스 리소스에 액세스할 수 있음을 증명합니다.
Oracle AI Database는 일반 사용자 보안 컨텍스트를 연결하기 전에 두 토큰을 모두 검증합니다.
Oracle은 이 2-토큰 모델을 인증 플로우 및 필요 조건 이해 및 최종 사용자 보안 컨텍스트의 전체 수명 주기에 문서화합니다.
선행 조건
다음이 필요합니다.
- Oracle Deep Data Security를 지원하는 격리된 Oracle Autonomous AI Database 버전
- 애플리케이션, 사용자, 그룹 및 사용자정의 클레임을 관리할 수 있는 권한이 있는 동일한 테넌시의 OCI IAM ID 도메인
- 자율운영 AI 데이터베이스의 기존 데이터베이스 보안 관리자 계정(일반적으로
ADMIN) PATH의 SQL*Plus 및 자율운영 AI 데이터베이스 전자 지갑 또는 TLS 접속 구성- Python 3.10 - 3.14,
uv및 이 저장소.
Oracle Deep Data Security는 데이터베이스에 적용된 세분화된 권한 부여입니다. Oracle Deep Data Security란 무엇인가를 참조하십시오.
OCI IAM ID 도메인 구성
모든 OCI IAM 작업을 하나의 ID 도메인에서 수행합니다. 도메인 URL을 기록합니다(예: https://idcs-<id>.identity.oraclecloud.com:443).
신뢰할 수 있는 Oracle 워크스루는 애플리케이션 중심의 액세스를 위한 OCI IAM 구성입니다. 다음 예제의 값은 이 설명서와 함께 제공된 예제 환경 파일과 일치합니다.
데이터베이스 리소스 등록
ID 도메인 > 통합 애플리케이션에서 다음을 수행합니다.
OracleDB이라는 기밀 애플리케이션을 추가합니다.- 리소스 서버로 구성합니다.
- 주요 대상자:
OracleDB - 범위:
DB_ACCESS_SCOPE
- 주요 대상자:
- 클라이언트로 구성하고 클라이언트 인증서를 허용합니다.
- 활성화.
- 애플리케이션 ID, 클라이언트 ID 및 클라이언트 암호를 기록합니다.
전체 데이터베이스 범위는 범위 이름과 연결된 대상자입니다.
OracleDBDB_ACCESS_SCOPE
현재 콘솔 레이블 및 필드 설명은 OCI IAM에 데이터베이스 등록을 따르십시오.
웹 애플리케이션 등록
이름이 OracleAgentMemoryWeb인 두번째 기밀 애플리케이션을 추가합니다.
- 권한 부여를 권한 부여로 적용을 사용으로 설정합니다.
- 리소스 서버로 구성합니다.
- 주요 대상자:
OracleAgentMemoryWeb - 범위:
APP_ACCESS_SCOPE - 액세스 토큰 수명: 이 연습의 경우
3600초
- 주요 대상자:
- 다음 권한 부여를 사용하여 클라이언트로 구성합니다.
- 승인 코드
- 클라이언트 자격 증명
- 이 정확한 재지정 URL 추가:
http://127.0.0.1:8000/auth/callback - 클라이언트 리소스에서 다음 두 가지 모두에 대한 액세스 권한을 부여합니다.
OracleDBDB_ACCESS_SCOPEOracleAgentMemoryWebAPP_ACCESS_SCOPE
- 애플리케이션을 활성화하고 해당 클라이언트 ID 및 클라이언트 암호를 기록합니다.
응용 프로그램은 state 및 PKCE S256과 함께 권한 부여 코드를 사용합니다. OCI IAM은 OCI IAM에서 애플리케이션 등록에 필요한 클라이언트 구성을 문서화하고 PKCE 권한 부여 코드 예를 제공합니다.
그룹 클레임 추가
Oracle AI Database는 최종 사용자 토큰의 group 클레임에서 외부적으로 매핑된 데이터 역할을 활성화합니다. OCI IAM 커스터마이징 클레임은 콘솔이 아닌 ID 도메인 REST API를 통해 구성됩니다.
ID 도메인 관리자는 ID 도메인 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 및 응용 프로그램 그룹 생성
ORACLEAGENTMEMORY_USERS라는 그룹을 생성합니다.- 테스트 사용자
alice및bob를 생성합니다. - 두 사용자를
ORACLEAGENTMEMORY_USERS에 지정합니다. OracleAgentMemoryWeb에 그룹을 지정합니다.
데이터베이스는 나중에 이 그룹 이름을 데이터 롤에 매핑합니다. 그룹 이름은 대소문자를 구분하지 않고 비교되지만 설정 전체에서 동일한 철자를 사용합니다. OCI IAM에서 사용자 생성 및 그룹 지정을 참조하십시오.
환경을 준비합니다.
전체 웹 응용 프로그램 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 |
대상 자율운영 AI 데이터베이스에 대해 OCI IAM 외부 인증을 사용으로 설정하고 OCI_IAM_DOMAIN_DB_CRED$를 대체합니다. |
db_deepsec_user_setup.sh |
스키마 소유자 및 앱 풀 사용자를 생성하고 문서화된 권한 허용 목록을 부여합니다. |
db_list_all_data_roles.sh |
Deep Data Security 역할, IAM 매핑, 데이터 권한 부여, 술어, 보호된 객체, 최종 사용자 및 애플리케이션 ID에 대한 읽기 전용 검사를 수행합니다. |
.deepsec.env는 데이터베이스 설정에서만 사용됩니다. 여기에는 보안 관리자 및 스키마 소유자 암호가 포함됩니다. .deepsec.runtime.env는 Flask 프로세스에 의해 로드되며 권한 있는 두 암호를 모두 의도적으로 제외합니다. 설정 파일을 웹 응용 프로그램을 시작하는 셸로 내보내지 마십시오. 다른 경로를 사용하려면 설정에 OAM_DEEPSEC_ENV_FILE 또는 웹 프로세스에 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 |
웹 애플리케이션의 클라이언트 ID |
OAM_WEB_OCI_CLIENT_SECRET |
웹 애플리케이션의 클라이언트 암호 |
OAM_WEB_OCI_END_USER_SCOPE |
OracleAgentMemoryWebAPP_ACCESS_SCOPE |
OAM_WEB_OCI_DATABASE_ACCESS_SCOPE |
OracleDBDB_ACCESS_SCOPE |
OAM_DEEPSEC_CONFIG_DIR는 DSN이 tnsnames.ora를 검색할 수 없는 TNS 별칭인 경우에만 필요합니다. sqlnet.ora 및 DSN이 이미 모든 python-oracledb 요구 사항을 제공하는 경우 전자 지갑 위치 및 암호는 선택 사항입니다. 자율운영 AI 데이터베이스 접속 옵션은 전자 지갑으로 Python 애플리케이션 접속을 참조하십시오.
임베딩 제공자도 구성합니다. 응용 프로그램은 메모리만 나열하고 추가하지만 에이전트 메모리는 메모리 컨텐츠를 저장할 때 임베딩을 만듭니다. 템플리트는 OpenAI 호환 모델을 예로 사용합니다. 모델, API 기반, 키 및 차원을 제공자의 값으로 대체합니다.
세 개의 데이터베이스 계정 구성
경고: 이 섹션의 명령은 데이터베이스 전체의 외부 인증 설정 및 계정 권한을 변경합니다. 먼저 스크립트를 검사합니다. 공유 데이터베이스나 운용 중인 데이터베이스에 대해 이들을 실행하지 마십시오.
세 개의 구분 데이터베이스 유저 사용:
| 권한 | 예제 계정 | 허용된 작업 |
|---|---|---|
| 보안 관리자 | ADMIN |
OCI IAM 통합을 사용으로 설정하고, 데이터 롤 및 데이터 권한 부여를 생성, 부여, 취소, 나열 및 제거합니다. 웹 요청에 사용되지 않습니다. |
| 관리 스키마 소유자 | OAM_SCHEMA_OWNER |
에이전트 메모리 테이블, 인덱스, 프로시저 및 스케줄러 작업을 생성합니다. 스키마 수명 주기 작업에만 사용됩니다. |
| 애플리케이션 DB 사용자 | OAM_APP_DB_USER |
세션을 열고 일반 사용자 보안 컨텍스트를 연결합니다. 일반 SELECT, INSERT, UPDATE 또는 DELETE 권한을 받지 않습니다. |
이렇게 구분하면 유효한 일반 사용자 컨텍스트가 없는 요청이 닫히지 않습니다. Oracle의 데이터베이스 구성 설명서에서는 연결 풀 계정에 대해 CREATE SESSION 및 CREATE END USER SECURITY CONTEXT를 권장합니다. IAM 통합을 위해 데이터베이스 구성을 참조하십시오.
예제에서는 설정을 위해 자율운영 AI 데이터베이스 ADMIN 계정을 사용합니다. 사용자 정의 보안 관리자 계정은 두 데이터베이스 사용자를 생성 및 변경하고 나열된 시스템 권한을 부여할 수 있어야 합니다. 에이전트 메모리 테이블은 별도의 스키마에 속하므로 정책 관리에는 관리자의 고유 스키마에 CREATE DATA GRANT만 있는 것이 아니라 CREATE ANY DATA GRANT, DROP ANY DATA GRANT 및 ADMINISTER ANY DATA GRANT가 필요합니다. 또한 정책에서 사용되는 데이터 롤을 생성하고 삭제할 수 있는 권한이 있어야 합니다.
OCI IAM 토큰 검증 사용
검토 및 실행
bash database_scripts/db_ociiam_setup.sh
이 스크립트는 보안 관리자로 연결되며
- 데이터베이스 응용 프로그램의 ID 및 ID 도메인 URL로
DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION를 호출합니다. - 데이터베이스 애플리케이션의 클라이언트 ID 및 암호로 암호화된
OCI_IAM_DOMAIN_DB_CRED$인증서를 생성합니다. - 결과 ID 제공자 매개변수를 인쇄합니다.
하나의 외부 ID 제공자만 활성 상태일 수 있습니다. 예제 스크립트는 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
소유자는 자율운영 AI 데이터베이스 DATA 테이블스페이스에서 할당량을 받습니다. Pool 유저는 소유자 테이블에 대한 직접 권한을 받지 않습니다. 필요한 명령문에 초점을 맞추기 위해 스크립트는 기존 유저를 확인하거나 현재 권한을 검사하지 않습니다. 새 계정 이름을 사용합니다. 유저가 이미 있거나 다른 SQL 문이 실패하는 경우 스크립트가 정지됩니다.
저장소 및 자체 행 정책 생성
독립형 예제 환경을 설치합니다.
uv sync
그런 다음 설치 프로그램을 실행합니다.
uv run python scripts/setup_memory.py
이 명령은 OAM_WEB_MEMORY_STORE_ID에 대해서만 의도적으로 파괴적입니다. 다음을 수행합니다.
- 스키마 소유자로 연결하여 에이전트 메모리 스키마를 재생성합니다.
- 보안 관리자로 연결하여 자체 행 정책을 추가하고
ORACLEAGENTMEMORY_USERS에 부여합니다.
추가 및 권한 부여 관리 호출은 멱등입니다. 재실행하면 동일한 관리 정책 정의 및 지정이 대체되고 중단된 시도로 인해 남아 있는 부분 관리 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 Data Security 객체를 생성, 변경 또는 제거하지 않습니다.
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 그룹에 대해 하나의 매핑된 데이터 역할을 생성합니다. 해당 데이터에 모델에 대한 액세스 권한이 있는 일반 데이터베이스 롤을 부여합니다. 다음 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에 매핑된 기존 롤을 찾아 동일한 롤에 에이전트 메모리 테이블 데이터 권한 부여를 추가합니다. 두번째 롤은 생성하지 않습니다. 런타임 시 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에는 전체 웹 응용 프로그램 및 데이터베이스 스크립트가 포함되어 있습니다. 주요 응용 프로그램 부분은 의도적으로 작습니다.
OAuth 시작 및 완료
로그인 경로는 임의 state 및 PKCE 값을 만듭니다. 불투명 세션 ID만 HttpOnly, SameSite=Lax 쿠키에 배치되고 토큰은 프로세스 로컬 데모 세션 저장소에 유지됩니다.
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는 일반 사용자 컨텍스트가 활성 상태인 동안 다른 스키마 정책을 거부하고 활성 상태인 컨텍스트가 없을 때 이 보호된 런타임 저장소에 대한 이후 작업을 거부합니다. 또한 보안 관리 기능은 일반 유저 컨텍스트를 전달하는 연결을 거부합니다.
각 에이전트 메모리 데이터베이스 작업에 대해 컨텍스트 관리자는 다음을 수행합니다.
- 애플리케이션 풀에서 물리적 연결을 획득합니다.
- 의도한 최종 사용자 보안 컨텍스트를 첨부하고 확인합니다.
- 해당 ID로 SQL 실행
- 연결을 반환하기 전에 컨텍스트를 지우고 확인합니다.
풀의 데이터베이스 계정에 폴백 테이블 권한이 없습니다. 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는 표시된 메모리 콘텐츠를 이스케이프합니다. 원시 데이터베이스 예외, OAuth 응답, 토큰 및 제출된 값은 렌더링되지 않습니다.
응용 프로그램 실행 및 확인
Flask 개발 서버를 시작합니다.
uv run python run.py
http://127.0.0.1:8000를 엽니다.
권한 부여 경계 확인:
- Alice로 로그인합니다.
- 미리 채워진 사용자 이름
alice을 사용하여Alice's first memory를 추가합니다. - Visible memories 아래에 메모리가 표시되는지 확인합니다.
Alice tries to write for Bob를 추가하고 username을bob으로 변경합니다.- Oracle AI Database가 작업을 거부하는지 확인합니다.
- 로그아웃한 후 Bob으로 로그인하고 Alice의 메모리가 표시되지 않는지 확인합니다.
- 메모리를 Bob으로 추가하고 Alice로 다시 로그인한 다음 Bob의 메모리가 표시되지 않는지 확인합니다.
이렇게 하면 다음과 같은 두 개의 독립적인 제어가 나타납니다.
SELECT는user_id가 유효 ID와 일치하는 행만 반환합니다.INSERT는user_id가 다른 ID에 속하는 행을 생성할 수 없습니다.
운용 작업의 경우 조직에서 유지해야 하는 Deep Sec 관리 및 최종 사용자 보안 컨텍스트 작업에 대해 Oracle Unified Auditing을 구성합니다. 또한 문서화된 취소 시간 계약을 고려합니다. 관리 호출이 반환되기 전에 SDK 정책 취소가 커밋되고, OCI IAM 그룹에서 사용자를 제거해도 이미 실행된 액세스 토큰이 재작성되지 않습니다. 감사 지침, 토큰 만료 동작 및 해당 Oracle Deep Sec 및 OCI IAM 설명서에 대한 링크는 딥 데이터 보안을 참조하십시오.
로그인에 성공하지만 데이터베이스가 모든 작업을 거부하는 경우 일반 사용자 토큰을 검사하고 group에 ORACLEAGENTMEMORY_USERS이 포함되어 있는지 확인합니다. Oracle의 딥 데이터 보안 액세스 및 권한 문제 해결에서는 관리자가 활성 데이터 역할을 검사하는 방법에 대해서도 설명합니다.
여전히 필요한 운영 환경
경고: 이 가이드를 완료해도 예제가 생산 준비가 되지 않습니다.
설계를 적용하기 전에 다음을 교체하거나 추가하십시오.
- TLS 뒤에 운용 중인 WSGI 서버, 신뢰할 수 있는 프록시 구성 및 보안 쿠키
- 만료, 순환, 로그아웃 전달 및 동시성 제어를 지원하는 지속성 암호화된 서버측 세션 저장소
- dotenv 파일 대신에 관리되는 비밀 저장소;
- refresh-token 또는 재인증 동작, 토큰 취소 처리 및 클럭 인식 만료;
- 요율 제한, 요청 시간 초과, 토큰 또는 사용자 콘텐츠가 없는 감사 로깅 및 운영 모니터링
- 배포별 CSRF, 콘텐츠 보안 정책, 보안 헤더, 입력 제약 조건 및 오류 처리;
RECREATE를 사용하지 않는 마이그레이션 및 정책 변경 절차;- 관리, 스키마 마이그레이션 및 런타임을 위한 별도의 배포 ID와 네트워크 경계
- 실제 서버 및 풀 구성에 대한 높은 동시성, 취소, 컨텍스트 지우기 및 ID 전환 테스트
핵심 불변성 유지: 런타임 풀 계정에는 직접 테이블 DML 권한이 없으며 모든 에이전트 메모리 요청은 확인된 OracleMemoryEndUserSecurityContext 내에서 실행됩니다.