diff --git a/docs/design/699-hmm-mcp-demo-users/README.md b/docs/design/699-hmm-mcp-demo-users/README.md index 5ad35de..3670007 100644 --- a/docs/design/699-hmm-mcp-demo-users/README.md +++ b/docs/design/699-hmm-mcp-demo-users/README.md @@ -1,6 +1,6 @@ # HMM MCP 데모 사용자 preset (#699) -> 상태: Verified / Deployed (2026-07-22) +> 상태: Verified / Deployed (2026-07-23) > 추적: Redmine #699 / Git 브랜치: `hmm-backoffice` > 대상: `hmm.cloud-handson.com` / `/opt/hmm-poc4` @@ -64,3 +64,41 @@ vpd_token_presets.json (사용자 ID·역할·팀·테스트 문맥·mcp_token_e 입사 2년차부터 차기 발생연차 50% 선사용 제한을 답변했다. - dark color-scheme 계산값: expander 배경 `rgb(246, 248, 250)`, 보조 버튼 배경 `rgb(255, 255, 255)`, 답변 목록·expander·버튼 글자 `rgb(23, 43, 58)` + +## 전 화면 브라우저 검증 기준 (2026-07-23) + +다음 화면과 패널을 각각 실제 Chromium에서 열어 렌더링, 오류 alert, 핵심 조작, 색상 대비를 확인한다. + +1. 로그인: 입력 필드, 로그인 유지, 실패 안내, 정상 로그인, 로그아웃 +2. 아키텍처: 운영 구조와 질의 처리 흐름 +3. 시나리오: 샘플 선택, 질문 입력, 저장된 답변, MCP 상세 +4. 감사로그: HMM 접근 이벤트 유형·상태·기간 필터, 지표와 이벤트 표 +5. 보안관리: 업무 프로세스와 `hmm-backoffice` 운영 포털 링크 +6. 사이드바: 데모 사용자 5명, 대화 검색·세션, 대화 관리, MCP 고급 설정 + +페이지 오류, HTTP 4xx/5xx, 흰 배경의 흰 글자, 검은 배경의 검은 글자, 가로 overflow가 없어야 한다. + +### HMM 감사로그 데이터 원천 + +- 포털 감사로그 탭은 KB PoC의 `POC_2` FGA 카탈로그를 조회하지 않는다. +- DB 접속값은 `POC4_AUDIT_DB_USER`, `POC4_AUDIT_DB_PASSWORD`, `POC4_AUDIT_DSN`으로 + 분리하고 Git에 값을 저장하지 않는다. ADB가 TLS 서버 인증을 허용하므로 운영 환경은 1521 TLS + 접속 기술자를 사용해 Wallet PEM 암호 입력 대기를 제거한다. +- 상호 TLS가 필요한 다른 환경에서는 `POC4_AUDIT_WALLET_DIR`와 + `POC4_AUDIT_WALLET_PASSWORD`를 함께 지정한다. Wallet 암호 없이 단순 TNS alias만 지정하는 + 불완전한 설정은 시작 시 안전한 오류로 처리한다. +- 이벤트 원천은 `ADMIN.HMM_ACCESS_AUDIT`이다. 이벤트 유형, 성공/실패, 대상 key/object, 처리 행 수, + 오류 코드와 메시지를 최근 순으로 표시한다. +- 비활성 Streamlit tab의 글자·배경색도 공통 presentation CSS에서 명시해 OS dark color-scheme과 + 무관하게 WCAG AA 수준의 대비를 유지한다. + +### 2026-07-23 전수검사 결과 + +- 실제 Chromium에서 로그인·아키텍처·시나리오·감사로그·보안관리 5개 화면을 각각 열었다. +- 필수 문구 누락 0, 낮은 색상 대비 0, 가로 overflow 0이다. +- 브라우저 page error 0, console error 0, HTTP 오류 0이다. +- 데모 사용자 5명 선택·복원, 대화 검색·JSON 다운로드, MCP discovery cache 갱신을 확인했다. +- 감사로그 필터 2개, 새로고침, 상세 토글이 렌더링되고 `ADMIN.HMM_ACCESS_AUDIT` 0건 상태를 + 정상적인 empty state로 표시한다. +- 보안관리의 `https://hmm-backoffice.cloud-handson.com/` 링크는 HTTP 200이다. +- 상세 증적은 `docs/reports/2026-07-23-hmm-portal-full-browser-audit.md`에 기록한다. diff --git a/docs/reports/2026-07-23-hmm-portal-full-browser-audit.md b/docs/reports/2026-07-23-hmm-portal-full-browser-audit.md new file mode 100644 index 0000000..b499390 --- /dev/null +++ b/docs/reports/2026-07-23-hmm-portal-full-browser-audit.md @@ -0,0 +1,49 @@ +# HMM 포털 전 화면 브라우저 전수검사 + +- 실행일: 2026-07-23 (Asia/Seoul) +- 대상: `https://hmm.cloud-handson.com/` +- 브라우저: Chromium, 1440×1100, OS dark color-scheme 모의 +- 추적: Redmine #699 / branch `hmm-backoffice` + +## 결과 + +| 화면 | 핵심 검증 | 결과 | +|---|---|---| +| 로그인 | 입력 2개, 로그인 유지, 실패 피드백, 서명 로그인, 로그아웃 | PASS | +| 아키텍처 | 운영 아키텍처, 처리 흐름, AI/MCP, 데이터 보안 | PASS | +| 시나리오 | 질문 입력, 샘플, 전송, 결과 empty state | PASS | +| 감사로그 | HMM 이벤트·상태 필터, 기간·건수, 새로고침, 상세 토글 | PASS | +| 보안관리 | 업무 프로세스, 백오피스 링크 및 HTTP 200 | PASS | +| 사이드바 | 데모 사용자 5명, 전환·복원, 검색, 다운로드, MCP cache | PASS | + +## 정량 결과 + +- 검사 화면: 5 +- 필수 문구 누락: 0 +- 낮은 색상 대비: 0 +- 가로 overflow: 0 +- 브라우저 page error: 0 +- console error: 0 +- HTTP 4xx/5xx: 0 + +시나리오의 “아직 저장된 대화가 없습니다.”와 감사로그의 “선택한 조건에 해당하는 HMM 접근 관리 +이벤트가 없습니다.”는 오류가 아니라 현재 데이터 0건을 설명하는 정상 empty state다. + +## 이번에 제거한 결함 + +1. 감사로그가 KB PoC의 `POC_2` FGA 메타데이터를 조회하던 경로를 제거했다. +2. 감사 원천을 `ADMIN.HMM_ACCESS_AUDIT`으로 교체하고 렌더러를 `src/agent_console/audit.py`로 + 분리했다. +3. Python Thin driver가 암호화 `ewallet.pem`의 암호를 대화형으로 기다리던 연결을 ADB TLS 1521 + 서버 인증 풀로 교체했다. +4. Streamlit 최신 DOM의 `data-testid="stTab"`을 공통 CSS에서 직접 처리해 dark color-scheme에서 + 비활성 탭이 흰색으로 렌더링되던 문제를 제거했다. + +## 운영 배포 + +- 애플리케이션: `/opt/hmm-poc4` +- 서비스: `poc4-streamlit.service` (active) +- 감사 DB 환경 파일: `/etc/hmm-poc4-audit.env` (root-only) +- systemd drop-in: `/etc/systemd/system/poc4-streamlit.service.d/20-audit.conf` + +DB 사용자·암호·접속 기술자 원문은 이 보고서와 Git에 기록하지 않는다. diff --git a/poc4_active_source_20260714/apps/poc4/mcp_discovery_ui.py b/poc4_active_source_20260714/apps/poc4/mcp_discovery_ui.py index a6a014e..1ccb827 100644 --- a/poc4_active_source_20260714/apps/poc4/mcp_discovery_ui.py +++ b/poc4_active_source_20260714/apps/poc4/mcp_discovery_ui.py @@ -62,6 +62,7 @@ from src.agent_console.presentation import ( render_console_header, render_login_brand, ) +from src.agent_console.audit import render_hmm_audit_tab from src.agent_console.profile import AppProfile, AppProfileError, load_app_profile from src.poc4.scenarios import ScenarioConfigError, load_demo_scenarios @@ -93,10 +94,16 @@ PORTAL_AUTH_USER_KEY = "poc4_portal_auth_user" PORTAL_LOGIN_FAILURE_KEY = "poc4_portal_login_failed" PORTAL_REMEMBER_TOKEN_PARAM = "poc4_remember" PORTAL_REMEMBER_MAX_AGE_SECONDS = 7 * 24 * 60 * 60 -AUDIT_SCHEMA = "POC_2" AUDIT_DB_ENV_FILE = Path( - os.environ.get("POC4_AUDIT_DB_ENV_FILE", "/home/opc/kbmcp/.env") + os.environ.get("POC4_AUDIT_DB_ENV_FILE", str(ENV_FILE)) ).expanduser() +DEFAULT_AUDIT_DB_DSN = ( + "(description=(retry_count=3)(retry_delay=1)" + "(address=(protocol=tcps)(port=1521)(host=adb.ap-seoul-1.oraclecloud.com))" + "(connect_data=(service_name=" + "yh0olybn5pqce4n_hmmaipoc_high.adb.oraclecloud.com))" + "(security=(ssl_server_dn_match=yes)))" +) _OPAQUE_BEARER = re.compile(r"^[\x21-\x7e]{1,4096}$") KB_THEME_CSS = """