# Cookbook: OCI AD Bridge로 DDS MCP 사용자 인증 전환 [개요로 돌아가기](README.md) · [아키텍처](architecture.md) · [트러블슈팅](troubleshooting.md) ## 적용 순서 Keycloak을 삭제하지 않는다. 아래 단계를 순서대로 끝내고 Alice/Bob DDS 결과를 확인한 뒤에만 AIPF의 기본 MCP source를 OCI 경로로 바꾼다. | 단계 | 작업 | 성공 판정 | 실패 시 | |---:|---|---|---| | 0 | AD·네트워크·관리 경로 점검 | AD/LDAPS/OCI HTTPS 연결 가능 | [Windows/LDAPS](troubleshooting.md#windows-ad-bridge) | | 1 | OCI AD Bridge 생성·Windows client 설치 | Bridge `Connected` | [Windows/AD Bridge](troubleshooting.md#windows-ad-bridge) | | 2 | AD OU/그룹 동기화 | OCI Domain에 Alice/Bob 표시 | [동기화](troubleshooting.md#동기화와-delegated-authentication) | | 3 | delegated authentication 시험·활성화 | AD 비밀번호 로그인 성공 | [동기화](troubleshooting.md#동기화와-delegated-authentication) | | 4 | AIPF OAuth source 등록 | OCI 로그인 → callback 완료 | [OAuth/AIPF](troubleshooting.md#oci-oauth와-aipf) | | 5 | MCP issuer/audience·DB binding 교체 | OCI JWT 검증·DDS mapping 성공 | [MCP/DDS](troubleshooting.md#mcp와-dds) | | 6 | Alice/Bob 비교 및 Keycloak 정리 판단 | Alice 1건, Bob 거부 | [권한](troubleshooting.md#mcp와-dds) | ## 0. 사전 점검 - AD Domain: `dds.test` - OCI Identity Domain: `identityAPAC` - Bridge 설치 위치: 운영은 domain-joined Windows member server 권장. 이 PoC는 격리된 AD VM에서 설치 가능 여부를 검증한다. - 네트워크: Bridge host → OCI Domain HTTPS 443, Bridge host → AD LDAPS 636 - AD Bridge service account: 동기화 대상 OU 읽기, `cn=Deleted Objects` 읽기, delegated authentication에 필요한 password/lockout attribute 최소 권한 - 동기화 대상은 기본 `CN=Users` container가 아니라 Bridge가 선택 가능한 OU에 둔다. 이 PoC는 `OU=Users,OU=DDS-PoC,DC=dds,DC=test` 및 `OU=Groups,OU=DDS-PoC,DC=dds,DC=test`를 사용한다. - OCI User 생성에 필요한 AD 사용자 속성은 최소 `sAMAccountName`, Given Name, Surname, `mail`이다. `mail`은 OCI가 허용하는 RFC 5322 형식의 주소여야 하며, `.test` 같은 내부 TLD는 거부될 수 있다. 현재 PoC Windows VM은 WinRM HTTPS(5986) 원격 실행이 확인됐다. OCI Run Command는 여전히 `ACCEPTED`에 머물 수 있으므로 installer 실행 수단으로 사용하지 않고 WinRM을 사용한다. ## 1. OCI AD Bridge 생성과 설치 1. OCI Console에서 **Identity & Security → Domains → identityAPAC → Directory integrations → Add → Microsoft Active Directory Bridge**를 연다. 2. 표시되는 **Bridge client ID/secret**과 Domain URL을 secret store에 보관한다. 3. OCI Console에서 내려받은 Bridge installer를 domain-joined Windows로 안전하게 전달한다. 현재 확보한 검증 대상 artifact는 `ad-id-bridge-23.2.92-2301160723.exe`다. 4. installer에서 OCI Domain URL/client credential 및 AD Bridge service account를 입력한다. 5. **LDAPS**를 선택하고 연결 시험을 통과한다. 6. Directory integrations에서 사용자·그룹 OU를 최소 범위로 선택하고 initial sync를 실행한다. Bridge client secret은 AIPF OAuth client secret 및 DB service client secret과 다르다. 각 secret을 서로 대체해 입력하지 않는다. ### 1.1 Installer artifact 관리 | 항목 | 이 PoC 값 | 적용 원칙 | |---|---|---| | 파일명 | `ad-id-bridge-23.2.92-2301160723.exe` | OCI Directory integrations 화면에서 내려받은 Bridge별 installer를 사용한다. | | 버전 | `23.2.92` | Console이 제공하는 최신 호환 installer인지 설치 직전에 확인한다. | | SHA-256 | `9388dbec5a76dfd19e6d3d5079e8cdccd00f4227e9aed36483961a8d68cdf19d` | 전달 전·후 checksum이 일치해야 한다. | | 원본 위치 | 로컬 `~/Downloads/` (Git 미포함) | 설치 파일·Bridge client secret·AD 비밀번호를 저장소에 commit하지 않는다. | | PoC 대상 위치 | `C:\DDS\installers\ad-id-bridge-23.2.92-2301160723.exe` | Windows에서 같은 SHA-256을 확인한 뒤 실행한다. | 입력값의 출처는 다음과 같다. | installer 입력값 | 출처 | 성공 판정 | |---|---|---| | Identity Domain URL, Bridge client ID/secret | OCI Console의 해당 **Directory integration** 설치 화면 | Installer의 OCI 연결 시험 성공 | | AD Bridge account | `dds.test` AD에서 최소 권한으로 만든 전용 service account | LDAPS 연결 시험 및 initial sync 성공 | | AD server/SSL | `dds.test` LDAPS TCP 636 | 인증서 신뢰 오류 없이 연결 성공 | 실패하면 [Windows/AD Bridge 문제 해결](troubleshooting.md#windows-ad-bridge)을 먼저 확인한다. installer와 client secret은 Bridge 생성 화면에서 다시 내려받거나 rotation하며, 채팅·문서·명령 이력에 secret 값을 남기지 않는다. ### 1.2 설치 실행 방식 이 버전은 WiX Bootstrapper 기반 installer다. `/quiet`으로 실행하면 **response file이 없다는 이유로 종료**하므로, response file 형식이 검증되기 전에는 silent 설치를 사용하지 않는다. 1. Windows VM에 RDP로 접속한다. 2. `C:\DDS\installers\ad-id-bridge-23.2.92-2301160723.exe`를 **Run as administrator**로 실행한다. 3. OCI Console의 Bridge 화면에서 확인한 Domain URL, Bridge client ID/secret을 입력하고 OCI 연결 시험을 성공시킨다. 4. AD Bridge 전용 service account와 비밀번호를 입력하고 **Use SSL (LDAPS)**를 유지한 채 AD 연결 시험을 성공시킨다. 5. 설치 완료 후 Directory integrations의 Bridge 상태가 `Partially configured` 또는 `Connected`로 바뀌는지 확인한다. 성공 후에만 [2. delegated authentication 활성화](#2-delegated-authentication-활성화)로 진행한다. silent response file을 확보한 경우에도 secret을 response file에 평문 보관하지 않으며, 사용 직후 삭제·rotation 절차를 적용한다. ### 1.3 LDAPS 인증서와 동기화 범위 구성 Bridge installer의 `LDAP server is unavailable`은 TCP 636이 열려 있더라도 AD DS가 유효한 LDAPS 인증서를 제공하지 않을 때 발생할 수 있다. PoC에서는 AD DS FQDN인 `hmm-ad-dss-test.dds.test`를 CN/SAN으로 하는 private server certificate를 Local Machine `My`에 설치하고, Bridge host의 Trusted Root에도 신뢰시켰다. AD DS가 새 인증서를 선택하도록 재부팅한 후 FQDN 기준 TLS handshake를 확인한다. ```powershell $fqdn = 'hmm-ad-dss-test.dds.test' $cert = New-SelfSignedCertificate -DnsName $fqdn, 'hmm-ad-dss-test' ` -CertStoreLocation 'Cert:\LocalMachine\My' -Type SSLServerAuthentication Export-Certificate -Cert $cert -FilePath 'C:\DDS\certs\dds-ad-ldaps-root.cer' Import-Certificate -FilePath 'C:\DDS\certs\dds-ad-ldaps-root.cer' ` -CertStoreLocation 'Cert:\LocalMachine\Root' ``` 운영에서는 self-signed 인증서 대신 사내 CA가 발급한 인증서를 사용한다. `ad.cloud-handson.com` 같은 OIDC 공개 로그인 주소는 LDAPS server name이 아니다. Bridge의 AD 연결은 내부 AD FQDN과 TCP 636을 사용한다. Bridge의 OU 선택 화면은 **OU만** 표시하고 기본 `CN=Users` container는 표시하지 않는다. 테스트 계정이 기본 container에 있으면 다음과 같이 전용 OU와 그룹을 만든 뒤 이동한다. ```text DC=dds,DC=test └─ OU=DDS-PoC ├─ OU=Users ← dds-alice, dds-bob └─ OU=Groups ← DDS-DDS-Users ``` `Edit configuration`에서 Users pane에는 `Users`, Groups pane에는 `Groups`만 선택한다. 상위 `dds.test` 또는 `DDS-PoC`를 Include hierarchy와 함께 선택하면 모든 하위 OU가 자동 선택되므로 선택하지 않는다. Supported operations의 AD 역방향 변경 항목은 모두 해제한다. import frequency를 설정하고, delegated authentication을 사용할 계획이면 **Enable local authentication**을 선택하고 **Enable federated authentication**은 해제한다. `Save` 뒤의 **Save Configuration Changes? → OK**까지 눌러야 상태가 `Configured`가 된다. ### 1.4 Import와 사용자 속성 검증 Bridge Action 메뉴의 **Import** 또는 configuration 저장으로 full sync를 실행한다. 성공 판정은 OCI Console의 Last import status에서 `Users imported from Active directory = 2`, `Groups imported from Active directory = 1`, failed 값이 모두 `0`인 것이다. | AD 사용자 속성 | PoC 예시 | OCI 매핑 목적 | |---|---|---| | `sAMAccountName` | `dds-alice` | OCI User Name | | Given Name / Surname | `Alice` / `DDS` | OCI 필수 `name` | | `mail` | `dds-alice@cloud-handson.com` | OCI Primary Email | 속성을 보완한 뒤에도 이전 실패 사용자가 재시도되지 않으면 Users/Groups OU 선택을 모두 해제해 Save/OK하고, 다시 필요한 OU만 선택해 Save/OK한다. 이 절차는 full sync를 강제한다. 성공 여부는 OCI Domain Users/Groups와 [동기화 문제 해결](troubleshooting.md#동기화와-delegated-authentication)을 함께 확인한다. ## 2. delegated authentication 활성화 1. OCI Domain에서 동기화된 `dds-alice`, `dds-bob`을 확인한다. 2. **Security → Delegated authentication → Test Delegated Authentication**에서 각 AD 계정/AD 비밀번호를 시험한다. 3. 두 계정이 성공한 뒤에만 `Activate Delegated Authentication`을 켠다. 이후 OCI 로그인 화면에 입력한 비밀번호는 Bridge를 거쳐 AD DS에서 검증된다. OCI Domain은 비밀번호 원천이 아니라 OIDC issuer다. ## 3. AIPF OCI OAuth client `AIPF_DDS_AD_TEST`는 AIPF 전용 confidential client다. | 설정 | 값 | |---|---| | Grant | `authorization_code`, `refresh_token` | | Redirect URI | `https://aipf.cloud-handson.com/agentFactory/v1/tools/mcp/callback` 및 `https://aipf.cloud-handson.com/v1/tools/mcp/callback` | | Scope | `openid profile email offline_access` | | Authorization URL | discovery의 `authorization_endpoint` | | Token / Refresh URL | discovery의 `token_endpoint` | discovery URL은 `https:///.well-known/openid-configuration`이다. endpoint를 추측해 입력하지 않는다. local test 환경의 client credential은 git-ignore된 `.runtime/aipf-dds-oci-ad-client.env`에만 보관한다. ## 4. AIPF source와 MCP 전환 1. AIPF에서 기존 Keycloak source를 삭제하지 않고 새 source를 만든다. 2. Server URL은 `https://hmm-backoffice.cloud-handson.com/mcp/dds/sse`를 유지한다. 3. Authentication mode를 `OAuth`로 선택하고 OCI client ID/secret과 discovery endpoint를 입력한다. 4. OCI login에서 Alice로 로그인한 뒤 받은 access token의 `iss`, `aud`, `sub`를 안전하게 확인한다. 5. MCP의 issuer/audience와 `CB_EXTERNAL_IDENTITY_BINDING`을 OCI claim 기준으로 함께 바꾼다. 6. Alice/Bob 권한 비교가 끝난 후에만 기존 source를 해제한다. ## 5. 검증과 rollback | 검증 | 성공 | |---|---| | Alice `휴가` 검색 | `휴가 정책 - Alice 전용 테스트` 1건 | | Bob 같은 검색 | 권한 없는 보호 객체가 default deny | | 잘못된/만료/미매핑 OCI JWT | DB query 이전에 거부 | 실패 시 MCP issuer/audience와 AIPF source를 Keycloak 값으로 되돌린다. DB service client, `DDS_U_1`/`DDS_U_2`, DATA GRANT는 OCI 사용자 OAuth 전환과 별개이므로 rollback 대상이 아니다.