# HMM MCP endpoint와 토큰 설정 ## 인증 수단 구분 HMM 포털 로그인과 MCP 호출은 서로 다른 인증 수단을 사용한다. | 인증 수단 | 사용 위치 | 전달 방식 | MCP 호출 사용 여부 | |---|---|---|---| | `__Host-HMM_PORTAL_SESSION` | `hmm.cloud-handson.com` 포털 로그인 | 브라우저 `Secure; HttpOnly` 쿠키 | 사용 금지 | | `HMM_MCP_BEARER_TOKEN` | 별도 호환 MCP 서버 접근 | HTTP `Authorization: Bearer` | 포털의 공용 gateway에 사용 | | HMM 직원별 VPD 토큰 | 백오피스 MCP 사용자 인증·DB context | HTTP `Authorization: Bearer` | Agent Factory 사용자별 연동에 사용 | 포털 쿠키를 복사해 MCP Bearer Token으로 사용하면 안 된다. 브라우저 JavaScript에서도 포털 쿠키를 읽을 수 없도록 `HttpOnly`로 설정한다. ## MCP endpoint 구분 두 주소는 같은 토큰을 받지 않는다. | 항목 | 값 | |---|---| | 사용자별 VPD MCP | `https://hmm-backoffice.cloud-handson.com/mcp` | | 사용자별 인증 | 백오피스에서 발급한 `vpd_live_*` 토큰 원문 | | 공용 호환 MCP | `https://hmm-mcp.cloud-handson.com/mcp` | | 공용 인증 | 운영 `HMM_MCP_BEARER_TOKEN` | | Transport | Streamable HTTP POST | 허용 도구는 다음 세 개다. | 도구 | 주요 인자 | 용도 | |---|---|---| | `search_hr_data` | `query` | 조직, 직원, 휴가 잔여·신청, 근태 조회 | | `resolve_hr_term` | `term` | 휴가·근태 표현을 표준 용어와 코드로 변환 | | `search_hr_policy` | `query` | HR 규정 PDF 지식 검색 | ## 포털의 현재 공용 토큰 조합 `config/vpd_token_presets.json`의 현재 조합은 다음과 같다. | 데모 사용자 | 역할 | `mcp_token_env` | |---|---|---| | E1001 Kim Minseo | HR Team Manager | `HMM_MCP_BEARER_TOKEN` | | E1002 Lee Jiwon | HR Operations Specialist | `HMM_MCP_BEARER_TOKEN` | | E1003 Park Dohyun | People Analytics Analyst | `HMM_MCP_BEARER_TOKEN` | | E1005 Han Seojun | Recruiting Specialist | `HMM_MCP_BEARER_TOKEN` | | E1007 Kang Minho | HR Coordinator | `HMM_MCP_BEARER_TOKEN` | 현재는 모든 preset이 같은 서버 관리 토큰을 쓴다. preset을 바꾸면 질문에 포함되는 데모 사용자 문맥은 바뀌지만, Bearer Token 자체는 바뀌지 않는다. 따라서 이 조합만으로는 사용자별 VPD 보안 경계를 만들지 못한다. ## 포털 설정 `config/mcp_servers.json`에는 토큰 원문 대신 환경변수 이름만 기록한다. ```json { "id": "hmm_hr_mcp", "endpoint_url": "https://hmm-mcp.cloud-handson.com/mcp", "auth_token_env": "HMM_MCP_BEARER_TOKEN", "tool_allowlist": [ "search_hr_data", "resolve_hr_term", "search_hr_policy" ] } ``` 운영 서버 `/opt/hmm-poc4/.env`에 실제 값이 있어야 한다. ```dotenv HMM_MCP_BEARER_TOKEN= POC3_MCP_TIMEOUT_SECONDS=45 ``` 토큰 원문은 JSON, Git, 대화 기록, 화면 상세에 저장하지 않는다. 환경 파일은 운영 계정만 읽을 수 있게 제한한다. ## 사용자 VPD MCP 직접 호출 예시 ```bash export HMM_USER_BEARER_TOKEN='<백오피스 발급 화면에서 한 번 표시된 원문>' curl --fail-with-body \ -H "Authorization: Bearer ${HMM_USER_BEARER_TOKEN}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ --data '{ "jsonrpc": "2.0", "id": "tools-list-1", "method": "tools/list", "params": {} }' \ https://hmm-backoffice.cloud-handson.com/mcp unset HMM_USER_BEARER_TOKEN ``` MCP 서버가 `initialize`와 session ID를 요구하면 다음 순서를 사용한다. 1. `initialize` 2. 응답의 `Mcp-Session-Id` 보관 3. `notifications/initialized` 4. 같은 session header와 Bearer Token으로 `tools/list` 5. 같은 session header와 Bearer Token으로 `tools/call` ## Oracle AI Database Private Agent Factory 설정 | 입력 항목 | 값 | |---|---| | Server name | `hmm-backoffice-mcp` | | Server URL | `https://hmm-backoffice.cloud-handson.com/mcp` | | Authentication mode | Bearer Token | | Token | 백오피스에서 해당 직원에게 발급한 토큰 원문. `Bearer ` 문자열은 붙이지 않음 | | Allowed tools | 위 세 도구만 선택 | | Timeout | 45초부터 시작 | 이 endpoint는 OAuth authorization endpoint가 아니다. OAuth client ID, client secret, authorization URL, token URL은 입력하지 않는다. ## 사용자별 VPD 적용 구조 MCP의 표준 `Authorization` header는 하나이므로 “공통 gateway token + 직원 VPD token” 두 개를 같은 header에 조합하지 않는다. 다음 구조가 권장된다. 1. 백오피스에서 E1001, E1002 등 직원별 opaque token을 각각 발급한다. 2. MCP 서버는 그 직원 token 자체를 Bearer Token으로 검증한다. 3. `ADMIN` 연결은 Select AI `SHOWSQL` 생성까지만 수행한다. 4. `EXEMPT ACCESS POLICY`가 없는 `CB_ORDS` 연결에서 `CB_ORDS_HANDLER_PKG.SET_VPD_CONTEXT('Bearer ' || :token)`을 호출한다. 5. 같은 `CB_ORDS` DB 세션에서 생성된 읽기 전용 SQL로 `HMM_LEAVE_BALANCES`, `HMM_LEAVE_REQUESTS`를 조회한다. 6. 실행 전 런타임 사용자가 `ADMIN`이 아니고 `EXEMPT ACCESS POLICY`가 없으며, `HMM_ACCESS_CTX.EMPLOYEE_CODE`가 토큰 인증 결과와 일치하는지 확인한다. 7. 하나라도 다르면 조회하지 않고 fail-closed 한다. 8. `finally`에서 `CB_ORDS_HANDLER_PKG.CLEAR_VPD_CONTEXT`와 rollback을 수행한다. 9. 서버 관리용 공통 토큰과 직원별 토큰을 동시에 요구해야 한다면 OAuth/API Gateway에서 application identity와 user subject를 하나의 검증 가능한 access token으로 합친다. 이 흐름은 2026-07-31 백오피스 MCP `search_hr_data`에 적용됐다. 모든 MCP method가 토큰 해시·만료·회수·재직 상태를 확인한다. `search_hr_data`는 `HMM_HR_DATA_GPT54_PROFILE`로 SQL만 생성하고, 실제 SQL은 위 `CB_ORDS` 세션에서 실행한다. 무토큰·무효·회수 토큰은 HTTP 401이다. 운영 환경에는 다음 값이 필요하다. ```dotenv BACKOFFICE_SELECT_AI_PROFILE=HMM_HR_DATA_GPT54_PROFILE BACKOFFICE_SELECT_AI_RUNTIME_DB_URL= BACKOFFICE_SELECT_AI_RUNTIME_DB_USERNAME=CB_ORDS BACKOFFICE_SELECT_AI_RUNTIME_DB_PASSWORD=<운영 secret> ``` DB 구성 스크립트는 `database/adb/73_hmm_mcp_vpd_runtime.sql`이다. 이 스크립트는 승인된 HMM HR 객체에 대한 개별 `SELECT`와 handler package 실행 권한만 부여하며 `EXEMPT ACCESS POLICY`는 부여하지 않는다. 포털의 `HMM_MCP_BEARER_TOKEN` 공용 preset은 별도 호환 gateway를 사용하는 기존 UI 라우팅이다. Agent Factory의 사용자별 권한 검증에는 반드시 백오피스 MCP 주소와 직원 토큰을 사용한다.