From 35782b8a50008d51b9dbe645058fcbb78385f9bd Mon Sep 17 00:00:00 2001 From: devmrko Date: Tue, 4 Aug 2026 15:49:36 +0900 Subject: [PATCH] refs #744: document AIPF OAuth MCP test flow --- .../README.md | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/design/744-windows-ad-dds-end-user-mapping/README.md b/docs/design/744-windows-ad-dds-end-user-mapping/README.md index a9a39b5..7f18edf 100644 --- a/docs/design/744-windows-ad-dds-end-user-mapping/README.md +++ b/docs/design/744-windows-ad-dds-end-user-mapping/README.md @@ -66,6 +66,73 @@ ORA_END_USER_CONTEXT + DDS DATA GRANT / 권한 함수 이 단계는 END USER와 DATA ROLE만 게시한다. 각 DATA ROLE에는 data grant를 만들지 않았으므로 데이터 도구 호출은 여전히 **default deny**다. +## 4.2 AIPF MCP 등록 값 + +AIPF의 **Edit MCP server** 화면에서 다음 값으로 등록한다. AIPF는 confidential OAuth client를 요구하므로, 일반 테스트용 public client `dds-mcp`가 아니라 AIPF 전용 client `aipf-dds-mcp`를 사용한다. + +| AIPF 항목 | 입력값 | +|---|---| +| Server name | `alice-dds` (Bob 검증 때는 `bob-dds`처럼 별도 등록) | +| Server URL | `https://hmm-backoffice.cloud-handson.com/mcp/dds/sse` | +| Authentication mode | `OAuth` | +| Redirect callback URL | AIPF 표시값 `https://aipf.cloud-handson.com/agentFactory/v1/tools/mcp/callback` — 입력하지 않는 읽기 전용 값 | +| OAuth client ID | `aipf-dds-mcp` | +| OAuth client secret | 운영자 보관 secret. 저장소·문서·대화에 기록하지 않는다. 현재 작업 환경에서는 `.runtime/aipf-dds-mcp-client.env`의 `OAUTH_CLIENT_SECRET` 값을 사용한다. | +| Authorization URL | `https://ad.cloud-handson.com/realms/dds-test/protocol/openid-connect/auth` | +| Token URL | `https://ad.cloud-handson.com/realms/dds-test/protocol/openid-connect/token` | +| Refresh URL | `https://ad.cloud-handson.com/realms/dds-test/protocol/openid-connect/token` | +| Scopes | `openid profile email` | + +### AIPF callback 호환 보정 + +현재 AIPF는 화면에 표시하는 callback과 달리 OAuth authorization request에는 `/agentFactory`가 빠진 `https://aipf.cloud-handson.com/v1/tools/mcp/callback`을 보낸다. AIPF Nginx는 이 경로를 같은 origin의 실제 callback으로 302 전환하도록 구성했다. + +```text +/v1/tools/mcp/callback + -> /agentFactory/v1/tools/mcp/callback +``` + +이 전환은 OAuth `code`와 `state`를 보존하고 브라우저가 `/agentFactory` 범위의 AIPF 세션 쿠키를 다시 전송하게 한다. AIPF의 OAuth callback 생성 로직이 수정되면 이 Nginx 보정은 제거할 수 있다. + +## 4.3 테스트 시나리오 + +### A. Alice 인증과 MCP 연결 + +1. AIPF에서 위 값으로 `alice-dds`를 저장하고 연결한다. +2. Keycloak 로그인 화면에서 AD 사용자 `dds-alice`로 로그인한다. 도메인 표기가 필요하면 `DDS\\dds-alice`를 사용한다. +3. AIPF가 callback으로 돌아오면 `alice-dds` MCP 연결이 완료된다. +4. AIPF Agent 대화에서 다음 요청을 실행한다. + + ```text + dds_vector_search 도구를 사용해서 "휴가"를 검색해줘. + embeddingMode는 DEMO, limit은 10으로 해줘. + ``` + +5. MCP는 Keycloak access token의 검증된 `iss + sub`를 Alice의 application user와 `DDS_U_1`에 매핑한 뒤 `dds_vector_search`를 호출한다. + +### B. Bob 권한 비교 + +1. AIPF OAuth 연결을 끊거나 새 MCP 등록 `bob-dds`를 만든다. +2. 같은 OAuth 설정으로 연결한 뒤 AD 사용자 `dds-bob`으로 로그인한다. +3. Alice와 동일한 검색 요청을 실행한다. +4. DDS data grant 구성 후 기대 결과는 다음과 같다. + +| 사용자 | JWT subject 매핑 | 기대 결과 | +|---|---|---| +| `dds-alice` | application user `1` → `DDS_U_1` | 허용된 지식 행만 반환 | +| `dds-bob` | application user `2` → `DDS_U_2` | 빈 결과 또는 DDS 권한 거부 | + +### C. 판정 기준과 현 상태 + +| 확인 항목 | 판정 방법 | 현재 상태 | +|---|---|---| +| OAuth 로그인 | AIPF가 Keycloak 로그인 후 MCP 등록 화면으로 복귀 | 확인 완료 | +| JWT 검증/매핑 | `tools/list` 또는 `dds_vector_search`가 Bearer 토큰 검증을 통과 | 확인 완료 | +| Alice/Bob 데이터 차이 | 같은 `dds_vector_search` 호출에서 반환 행이 다름 | 대기 — OCI IAM DB service credential 및 DDS DATA GRANT 필요 | +| 미매핑 토큰 거부 | 매핑 없는 `iss + sub`의 MCP 호출이 `AUTHORIZATION_DENIED` | 구현 완료, 회귀 검증 대기 | + +`dds_vector_search`는 현재 유일한 DDS MCP 도구이며 입력값은 `query`(필수), `limit`(1~100), `embeddingMode`(`DEMO` 또는 `AI`)다. 데이터 권한 차이 검증은 서비스 identity의 OCI IAM 설정과 Alice 허용/Bob 거부 DDS grant를 반영한 뒤에 완료한다. + ## 5. Entra ID로 전환할 때 Entra tenant가 확보되면 AD DS/bridge 테스트에서 확인한 `issuer + immutable subject -> CB_APP_USER -> DDS END USER` 계약은 유지한다. 바뀌는 부분은 token issuer와 JWKS 검증 설정뿐이다. Entra의 claim 이름(`oid`, `sub`, `preferred_username` 등)은 실제 발급 토큰을 확인한 뒤 결정하며, `sub` 단독이 아니라 tenant/issuer 경계를 반드시 포함한다.