refs #744: document AIPF OAuth MCP test flow

This commit is contained in:
devmrko
2026-08-04 15:49:36 +09:00
parent 7dd47d39b9
commit 35782b8a50

View File

@@ -66,6 +66,73 @@ ORA_END_USER_CONTEXT + DDS DATA GRANT / 권한 함수
이 단계는 END USER와 DATA ROLE만 게시한다. 각 DATA ROLE에는 data grant를 만들지 않았으므로 데이터 도구 호출은 여전히 **default deny**다. 이 단계는 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로 전환할 때 ## 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 경계를 반드시 포함한다. 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 경계를 반드시 포함한다.