refs #741 #742: reorganize repository by application

This commit is contained in:
devmrko
2026-08-03 10:20:36 +09:00
parent 2e44ed0b97
commit e9d50e6a32
445 changed files with 1523 additions and 1885 deletions

View File

@@ -8,7 +8,7 @@
> 단위 매트릭스** 입니다 (README 참고). 본 상세 가이드는 그 위에 얹을 수 있는 **행
> 단위 region 필터링** 변형(`KR_ANALYSTS → APAC`, `GLOBAL_ADMINS → '*'`) 을 예시로
> 사용합니다 — VPD 메커니즘 자체는 동일하므로 개념 이해에는 차이가 없습니다.
> region 필터를 실제로 켜려면 `sql/adb/03_seed.sql` 하단의 주석을 해제하세요.
> region 필터를 실제로 켜려면 `database/adb/03_seed.sql` 하단의 주석을 해제하세요.
---
@@ -543,7 +543,7 @@ SQL> SELECT COUNT(*) FROM admin.v_customers_pg; -- 0
SQL> SELECT COUNT(*) FROM admin.v_customers_my; -- 0
# region 필터 변형을 켰을 때 — vpduser_both 에게 APAC 만 허용한 경우
# (sql/adb/03_seed.sql 하단 UPDATE 주석 해제 후)
# (database/adb/03_seed.sql 하단 UPDATE 주석 해제 후)
sqlplus "vpduser_both/\"${VPDUSER_BOTH_PASSWORD}\"@$ADB_TNS"
SQL> SELECT region, COUNT(*) FROM admin.v_customers_pg GROUP BY region;
-- 결과: APAC 만 보임

View File

@@ -4,7 +4,7 @@
---
## Postgres (`sql/source/postgres_setup.sql`)
## Postgres (`database/source/postgres_setup.sql`)
```
DB : 사용자가 .env 에서 지정 (PG_DB, 기본값 vpdpoc)
@@ -22,12 +22,12 @@ seed rows : 12 (APAC 4 / EMEA 4 / AMER 4)
```bash
PGPASSWORD=$PG_PASSWORD psql \
-h $PG_HOST -p $PG_PORT -U $PG_USER -d $PG_DB \
-f sql/source/postgres_setup.sql
-f database/source/postgres_setup.sql
```
---
## MySQL (`sql/source/mysql_setup.sql`)
## MySQL (`database/source/mysql_setup.sql`)
```
DB : MY_DB (기본 ecommerce_poc)
@@ -47,12 +47,12 @@ PK 범위를 PG (1~12) 와 다르게 가져간 이유:
```bash
mysql -h $MY_HOST -P $MY_PORT -u $MY_USER -p"$MY_PASSWORD" $MY_DB \
< sql/source/mysql_setup.sql
< database/source/mysql_setup.sql
```
---
## ADB → 원격 DB Link (`sql/adb/01_dblinks.sql`)
## ADB → 원격 DB Link (`database/adb/01_dblinks.sql`)
`DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK` 가 ADB 안에서 직접 heterogeneous 연결을
처리합니다. 별도 Database Gateway 설치 불필요.

View File

@@ -2,7 +2,7 @@
> 본 문서는 **선택사항** 입니다. 메인 데모(`run.sh all`) 는 전통적 **VPD** 경로로
> 그대로 동작합니다. 이 문서는 동일한 4-user 매트릭스를 Oracle AI Database
> **26ai 신기능 Deep Data Security (DDS)** 로 재구현한 `sql/adb/13_dds_variant.sql`
> **26ai 신기능 Deep Data Security (DDS)** 로 재구현한 `database/adb/13_dds_variant.sql`
> 의 사용법과, VPD ↔ DDS 1:1 매핑을 다룹니다.
>
> 본 변형은 **2026-05-26 실제 ADB (23.26.2.2.0) 에서 E2E 검증** 됨 (8장 결과).
@@ -84,7 +84,7 @@ Oracle 이 **2026-04-09** 에 VPD/RAS 의 공식 후계자로 발표한 native a
```bash
source .env # DDSUSER_*_PASSWORD 로드
sqlplus "$ADB_USER/$ADB_PASSWORD@$ADB_TNS" @sql/adb/13_dds_variant.sql
sqlplus "$ADB_USER/$ADB_PASSWORD@$ADB_TNS" @database/adb/13_dds_variant.sql
```
스크립트가 만드는 객체:
@@ -218,7 +218,7 @@ DROP VIEW v_dds_customers_my;
## 8. E2E 검증 결과 (2026-05-26, ADB 23.26.2.2.0)
`sql/adb/13_dds_variant.sql` 실행 후 4명의 ddsuser 로 `v_dds_customers_*` 조회:
`database/adb/13_dds_variant.sql` 실행 후 4명의 ddsuser 로 `v_dds_customers_*` 조회:
| 사용자 | `v_dds_customers_pg` | `v_dds_customers_my` | 판정 |
|---|---|---|---|

View File

@@ -1165,15 +1165,15 @@ ORDER BY rg.grantee, dg.object_name, dg.grant_name;
| 파일 | 역할 |
|---|---|
| `scripts/run_agent_ords_security_adb_local.sh` | 전체 실행 |
| `sql/adb/16_agent_ords_security_local_cleanup.sql` | `CB_*` 예제 객체 정리 |
| `sql/adb/17_agent_ords_security_local_vpd_setup.sql` | VPD용 로컬 테이블, 권한 테이블, context, redaction, 정책 생성 |
| `sql/adb/18_agent_ords_security_local_vpd_test.sql` | `CB_ORDS`로 Bearer Key 기반 VPD 테스트 |
| `sql/adb/19_agent_ords_security_local_dds_setup.sql` | DDS용 로컬 테이블, END USER, DATA ROLE, DATA GRANT 생성 |
| `sql/adb/20_agent_ords_security_local_dds_test.sql` | DDS end user별 조회 테스트 |
| `sql/adb/21_agent_ords_security_ords_enable_schema.sql` | `CB_ORDS` schema를 ORDS에 enable |
| `sql/adb/22_agent_ords_security_ords_handler_setup.sql` | ORDS Module/Handler와 Handler Package 생성 |
| `sql/adb/23_agent_ords_security_ords_handler_test.sql` | Handler Package 직접 실행으로 VPD/DDS Bearer 경로 검증 |
| `sql/adb/24_agent_ords_security_inventory.sql` | VPD/DDS 정책과 권한을 중앙 조회 |
| `database/adb/16_agent_ords_security_local_cleanup.sql` | `CB_*` 예제 객체 정리 |
| `database/adb/17_agent_ords_security_local_vpd_setup.sql` | VPD용 로컬 테이블, 권한 테이블, context, redaction, 정책 생성 |
| `database/adb/18_agent_ords_security_local_vpd_test.sql` | `CB_ORDS`로 Bearer Key 기반 VPD 테스트 |
| `database/adb/19_agent_ords_security_local_dds_setup.sql` | DDS용 로컬 테이블, END USER, DATA ROLE, DATA GRANT 생성 |
| `database/adb/20_agent_ords_security_local_dds_test.sql` | DDS end user별 조회 테스트 |
| `database/adb/21_agent_ords_security_ords_enable_schema.sql` | `CB_ORDS` schema를 ORDS에 enable |
| `database/adb/22_agent_ords_security_ords_handler_setup.sql` | ORDS Module/Handler와 Handler Package 생성 |
| `database/adb/23_agent_ords_security_ords_handler_test.sql` | Handler Package 직접 실행으로 VPD/DDS Bearer 경로 검증 |
| `database/adb/24_agent_ords_security_inventory.sql` | VPD/DDS 정책과 권한을 중앙 조회 |
### 7.1 VPD + Redaction 실행 검증
@@ -1634,7 +1634,7 @@ ORA-20101: Authorization header must be Bearer <key>
### 7.4 중앙 권한 인벤토리
VPD와 DDS 모두 적용 결과를 Dictionary View로 확인할 수 있다. 이 예제에서는 `sql/adb/24_agent_ords_security_inventory.sql`을 실행해 정책 연결과 DDS Grant Matrix를 확인한다.
VPD와 DDS 모두 적용 결과를 Dictionary View로 확인할 수 있다. 이 예제에서는 `database/adb/24_agent_ords_security_inventory.sql`을 실행해 정책 연결과 DDS Grant Matrix를 확인한다.
VPD 정책 연결 확인:

View File

@@ -3,7 +3,7 @@
> **상태**: Draft
> **작성**: [AI] Architect · **최종수정**: 2026-06-23
> **추적성** — Redmine: #424 · 관련 ADR: 없음
> · 구현 파일: `pom.xml`, `src/main/**`, `src/test/**` · 테스트: `mvn test`
> · 구현 파일: `vpd-backoffice/pom.xml`, `vpd-backoffice/src/main/**`, `vpd-backoffice/src/test/**` · 테스트: `mvn test`
## 1. 목적 (Why)
@@ -58,8 +58,8 @@
### 모듈/파일 구조
```text
pom.xml
src/main/java/com/cloudhandson/vpdbackoffice/
vpd-backoffice/pom.xml
vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/
VpdBackofficeApplication.java
config/
DataSourceConfig.java
@@ -88,13 +88,13 @@ src/main/java/com/cloudhandson/vpdbackoffice/
TokenController.java
ProbeController.java
DashboardController.java
src/main/resources/
vpd-backoffice/src/main/resources/
application.yml
mapper/*.xml
templates/**/*.html
static/css/app.css
static/js/app.js
src/test/java/com/cloudhandson/vpdbackoffice/
vpd-backoffice/src/test/java/com/cloudhandson/vpdbackoffice/
```
### 데이터 흐름
@@ -251,7 +251,7 @@ MCP-style reasoning
## 12. 미해결 질문 (Open Questions)
- ORDS 검증 API는 기존 `sql/adb/22_agent_ords_security_ords_handler_setup.sql`의 Handler를 그대로 사용할지, 백오피스 전용 Handler를 추가할지 결정이 필요하다.
- ORDS 검증 API는 기존 `database/adb/22_agent_ords_security_ords_handler_setup.sql`의 Handler를 그대로 사용할지, 백오피스 전용 Handler를 추가할지 결정이 필요하다.
- 백오피스 관리자 로그인은 초기에는 local user로 둘지, 사내 인증과 연결할지 후속 결정이 필요하다.
- 컬럼 정책을 Redaction DDL까지 자동 생성할지, 관리 테이블 저장 후 DBA 적용으로 둘지 결정이 필요하다.
- 실제 구현 issue를 별도 Redmine 하위 이슈로 나눌지, #424를 Developer 단계로 계속 이동할지 결정이 필요하다.

View File

@@ -3,7 +3,7 @@
> **상태**: Approved
> **작성**: [AI] Architect · **최종수정**: 2026-06-25
> **추적성** — Redmine: #456 · 관련 ADR: 없음
> · 구현 파일: `sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`, `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`, `mvn test`
> · 구현 파일: `database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`, `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`, `mvn test`
## 1. 목적 (Why)
@@ -78,8 +78,8 @@ I/O와 순수 로직 경계:
## 10. 테스트 계획
- SQLcl: `@sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
- SQLcl: `@sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
- SQLcl: `@database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
- SQLcl: `@database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
- Maven: `mvn test`
- ORDS smoke: 기존 HR=3, SELF=1, ALL=6 결과 유지 확인.

View File

@@ -1,7 +1,7 @@
# 함수 설계서: `cb_agent_doc_vpd_filter` (#456)
> **부모 설계서**: ./README.md · **상태**: Approved
> **작성**: [AI] Architect · **구현**: `sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql:cb_agent_doc_vpd_filter` · **테스트**: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
> **작성**: [AI] Architect · **구현**: `database/adb/26_agent_ords_security_dynamic_vpd_filter.sql:cb_agent_doc_vpd_filter` · **테스트**: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
## 1. 시그니처

View File

@@ -3,7 +3,7 @@
> **상태**: Approved
> **작성**: [AI] Architect · **최종수정**: 2026-06-25
> **추적성** — Redmine: #462 · 관련 ADR: 없음
> · 구현 파일: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: SQLcl `27`, `./run.sh backoffice-vpd-ords-test`, `mvn test`
> · 구현 파일: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: SQLcl `27`, `./run.sh backoffice-vpd-ords-test`, `mvn test`
## 1. 목적 (Why)
@@ -67,8 +67,8 @@ malicious cb_permission_rule rows
## 10. 테스트 계획
- `@sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
- `@sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
- `@database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
- `@database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
- `./run.sh backoffice-vpd-ords-test`
- `mvn test`

View File

@@ -3,7 +3,7 @@
> **상태**: Approved
> **작성**: [AI] Architect · **최종수정**: 2026-06-28
> **추적성** — Redmine: #547 · 관련 ADR: 없음
> · 구현 파일: `src/main/resources/application.yml`, `SecurityConfig.java`, `scripts/deploy-backoffice-vm.sh`, `scripts/configure-backoffice-https-vm.sh`, `deploy/caddy/Caddyfile.template`
> · 구현 파일: `vpd-backoffice/src/main/resources/application.yml`, `SecurityConfig.java`, `scripts/deploy-backoffice-vm.sh`, `scripts/configure-backoffice-https-vm.sh`, `deploy/vpd-backoffice/caddy/Caddyfile.template`
> · 테스트: `TransportSecurityTest.java`, `scripts/test-backoffice-https-config.sh`
## 1. 목적 (Why)
@@ -49,7 +49,7 @@ Internet client
Internet client ── HTTP :8082 ──X (loopback bind + firewalld/NSG deny)
```
- `deploy/caddy/Caddyfile.template`: TLS/redirect/HSTS/reverse proxy의 선언적 설정.
- `deploy/vpd-backoffice/caddy/Caddyfile.template`: TLS/redirect/HSTS/reverse proxy의 선언적 설정.
- `scripts/configure-backoffice-https-vm.sh`: 입력 검증, 원격 설정 검증·백업·적용·확인.
- `scripts/deploy-backoffice-vm.sh`: 앱 배포 시 운영 보안 환경값을 강제하고 루프백 헬스체크.
- Spring 설정: proxy가 전달한 HTTPS scheme을 인식하고 직접 HTTP 요청을 거부한다.

View File

@@ -2,7 +2,7 @@
> **상태**: VPD·DDS 병행 검증 완료, 토큰 기반 객체별 Data Grant 적용 완료
> **추적성**: Redmine #565, #566 · DDS 구현 커밋 `1e48864`, `a5e70bc`, `04cca64`, `8978be4`
> **기준 구현**: `sql/adb/32_dds_vector_tag_setup.sql`, `sql/adb/34_dds_token_data_grant_common_auth.sql`, `sql/adb/36_dds_sales_knowledge_scenario.sql`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsGrantPublisher.java`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsVectorKnowledgeService.java`
> **기준 구현**: `database/adb/32_dds_vector_tag_setup.sql`, `database/adb/34_dds_token_data_grant_common_auth.sql`, `database/adb/36_dds_sales_knowledge_scenario.sql`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsGrantPublisher.java`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsVectorKnowledgeService.java`
## 목적

View File

@@ -77,8 +77,8 @@ Authorization: Bearer <masked>
## 설치와 운영 절차
1. `ADMIN`으로 [42_agent_ords_fga_execution_audit.sql](../../../sql/adb/42_agent_ords_fga_execution_audit.sql)을 실행해 활성 보호 객체마다 FGA `SELECT` 정책을 만든다.
2. `CB_ORDS`로 [22_agent_ords_security_ords_handler_setup.sql](../../../sql/adb/22_agent_ords_security_ords_handler_setup.sql), [29_agent_ords_vector_search_ords.sql](../../../sql/adb/29_agent_ords_vector_search_ords.sql), [43_agent_ords_probe_id_handler_patch.sql](../../../sql/adb/43_agent_ords_probe_id_handler_patch.sql)을 순서대로 실행한다.
1. `ADMIN`으로 [42_agent_ords_fga_execution_audit.sql](../../../database/adb/42_agent_ords_fga_execution_audit.sql)을 실행해 활성 보호 객체마다 FGA `SELECT` 정책을 만든다.
2. `CB_ORDS`로 [22_agent_ords_security_ords_handler_setup.sql](../../../database/adb/22_agent_ords_security_ords_handler_setup.sql), [29_agent_ords_vector_search_ords.sql](../../../database/adb/29_agent_ords_vector_search_ords.sql), [43_agent_ords_probe_id_handler_patch.sql](../../../database/adb/43_agent_ords_probe_id_handler_patch.sql)을 순서대로 실행한다.
3. 새 권한 결과 확인을 실행한다. 이전 요청에는 `CLIENT_ID`가 없으므로 소급해 매칭하지 않는다.
4. 백오피스 실행 계정이 Autonomous의 `UNIFIED_AUDIT_TRAIL`을 조회할 수 있어야 한다. 전통 FGA 환경은 `DBA_FGA_AUDIT_TRAIL`을 fallback으로 사용한다. 일반 계정이면 감사 조회 권한을 가진 전용 observer 계정을 사용한다.

View File

@@ -1,7 +1,7 @@
# 함수 설계서: `addLocalSqlTrace` (#567)
> **부모 설계서**: ./README.md · **상태**: Approved
> **작성**: [AI] Architect · **구현**: `src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:addLocalSqlTrace` · **테스트**: `ProbeResultTest`, `mvn test`
> **작성**: [AI] Architect · **구현**: `vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:addLocalSqlTrace` · **테스트**: `ProbeResultTest`, `mvn test`
## 1. 시그니처

View File

@@ -1,7 +1,7 @@
# 함수 설계서: `findVpdPredicate` (#567)
> **부모 설계서**: ./README.md · **상태**: Approved
> **작성**: [AI] Architect · **구현**: `src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:findVpdPredicate` · **테스트**: `mvn test`, 운영 smoke
> **작성**: [AI] Architect · **구현**: `vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:findVpdPredicate` · **테스트**: `mvn test`, 운영 smoke
## 1. 시그니처

View File

@@ -4,8 +4,8 @@
> **최종수정**: 2026-07-19
> **추적성** — Redmine: #617 · 관련 ADR: [ADR-0001](../../adr/0001-dds-mcp-service-identity.md), [ADR-0002](../../adr/0002-dds-runtime-permission-source.md)
> · 현재 구현: `DdsMcpBearerAuthenticator`, `DdsMcpEndUserResolver`, `DdsMcpContextExecutor`, `DdsMcpSseController`
> · 기존 PoC 게시: `sql/adb/44_dds_mcp_local_end_user_setup.sql`
> · 검증: `sql/adb/45_dds_mcp_local_end_user_test.sql`, SSE `tools/call`
> · 기존 PoC 게시: `database/adb/44_dds_mcp_local_end_user_setup.sql`
> · 검증: `database/adb/45_dds_mcp_local_end_user_test.sql`, SSE `tools/call`
## 1. 결정과 목적

View File

@@ -3,7 +3,9 @@
> **상태**: Implemented snapshot documented · follow-up contract pending
> **작성**: [AI] Architect · **최종수정**: 2026-07-14
> **추적성** — Redmine: #654 · 관련 ADR: 없음 · 구현 커밋: `5bdd242`, `33399f9`, `1f6d974`
> · 스냅샷: `poc4_active_source_20260714/` · 원본 archive: `poc4_active_source_20260714/poc4_active_source_20260714.tar.gz` · 현행 구현 파일: `apps/poc4/mcp_discovery_ui.py`, `src/mcp_tool_router.py`, `src/oci_genai_sdk.py`, `src/poc3/model_registry.py`, `config/mcp_servers.json` · 테스트: Python 3.11 `py_compile`, 기존 백오피스 `mvn -q test`
> · 현재 소스: `ai-web-agent-console/` · 현행 구현 파일: `ai-web-agent-console/app.py`, `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py`, `ai-web-agent-console/ai_web_agent_console/oci_genai_sdk.py`, `ai-web-agent-console/ai_web_agent_console/model_registry.py`, `ai-web-agent-console/config/mcp_servers.json` · 테스트: Python 3.11 `compileall`/`unittest`, `mvn -f vpd-backoffice/pom.xml test`
>
> 이 문서의 PoC4 명칭과 원격 archive 경로는 2026-07-14 당시의 이력이다. 현재 저장소 구조는 #742 설계서를 기준으로 한다.
## 1. 목적 (Why)
@@ -17,17 +19,17 @@ PoC4 MCP AI Console이 KB VPD MCP를 사용자별 Bearer 토큰으로 안전하
| 영역 | 현행 구현 |
|---|---|
| 저장소 위치 | `poc4_active_source_20260714/` 단일 폴더에 격리 |
| 실행 진입점 | 직접 실행은 `streamlit run apps/poc4/mcp_discovery_ui.py --server.address 0.0.0.0 --server.port 8622` |
| 저장소 위치 | `ai-web-agent-console/` 단일 폴더에 격리 |
| 실행 진입점 | 직접 실행은 `streamlit run ai-web-agent-console/app.py --server.address 0.0.0.0 --server.port 8622` |
| Python 런타임 | Python 3.11 이상. 배포 서버 검증 런타임은 `/home/opc/poc_4/.python-runtime/cpython-3.11.15+20260610/bin/python3.11` |
| Streamlit 화면 | `apps/poc4/mcp_discovery_ui.py` 단일 대형 UI. KB 테마, 포털 로그인, 대화 이력, MCP discovery/call, evidence 수집, 답변 합성을 포함 |
| MCP registry | `config/mcp_servers.json`. `kb_mcp``kb_vector_mcp` 두 서버를 선언 |
| Streamlit 화면 | `ai-web-agent-console/app.py` 단일 대형 UI. KB 테마, 포털 로그인, 대화 이력, MCP discovery/call, evidence 수집, 답변 합성을 포함 |
| MCP registry | `ai-web-agent-console/config/mcp_servers.json` |
| KB 정형 MCP | `https://kb.cloud-handson.com/mcp`, 기본 tool `ords.query.kb_select_ai_vpd` |
| KB 벡터 MCP | `http://127.0.0.1:9978/mcp`, allowlist `hybrid_rerank_search` |
| 토큰 preset | `config/vpd_token_presets.json`. 실제 토큰 원문은 포함하지 않고 placeholder만 둠 |
| 토큰 preset | `ai-web-agent-console/config/vpd_token_presets.json`. 실제 토큰 원문은 포함하지 않고 placeholder만 둠 |
| 대화 저장소 | 기본 `data/poc4_mcp_chat.sqlite3`, 환경변수 `POC4_CHAT_DB_PATH`로 변경 가능 |
| DB evidence 연결 | 기본 env file `/home/opc/kbmcp/.env`, wallet fallback `/home/opc/wallet/kbaipoc` |
| OCI GenAI | `OCI_AUTH_TYPE=config_file`, `~/.oci/config`, `DEFAULT` profile 기반. model profile은 `config/poc3_model_profiles.json`에서 로드 |
| OCI GenAI | `OCI_AUTH_TYPE=config_file`, `~/.oci/config`, `DEFAULT` profile 기반. model profile은 `ai-web-agent-console/config/model_profiles.json`에서 로드 |
| 보안 원칙 | wallet, DB password, wallet password, 실제 VPD token, 대화 DB는 저장소에 포함하지 않음 |
현행 데이터 흐름은 다음과 같다.
@@ -60,25 +62,24 @@ SQLite 대화 이력 저장
| 파일 | 책임 |
|---|---|
| `apps/poc4/mcp_discovery_ui.py` | Streamlit 화면, 포털 로그인, MCP discovery/call, agent loop, evidence 수집, 답변 합성, 대화 이력 저장 |
| `apps/poc4/ui_theme.py` | UI theme 보조 코드 |
| `src/mcp_tool_router.py` | 발견된 MCP tool descriptor를 기반으로 LLM router가 server/tool을 선택하고 tool arguments를 구성 |
| `src/oci_genai_sdk.py` | OCI Generative AI 호출 경계. MCP/VPD token을 알지 않는 최소 completion client |
| `src/poc3/model_registry.py` | 모델 profile registry 로드, region/endpoint 해석, 환경 override 처리 |
| `src/poc3/questions.py` | 데모 질문 목록 |
| `config/mcp_servers.json` | MCP 서버 registry. 현재는 `endpoint_url`이 있으면 이를 우선 사용 |
| `config/poc3_model_profiles.json` | `gpt55_oci`, `gpt54_mini_oci`, `grok43`, `llama4_maverick`, `llama33_70b` profile |
| `config/vpd_token_presets.json` | 데모 사용자 token preset 구조. 실제 토큰은 배포 환경에서 교체 |
| `scripts/poc4/start_8622_langgraph_tc_ui_nohup.sh` | 원본 PoC4 런처 wrapper. 현재 스냅샷의 직접 entrypoint와는 다르게 `/home/opc/poc_4/scripts/poc4/run_8622_langgraph_tc_ui.sh``apps/poc4/langgraph_tc_ui.py`를 참조 |
| `ai-web-agent-console/app.py` | Streamlit 화면, 포털 로그인, MCP discovery/call, agent loop, evidence 수집, 답변 합성, 대화 이력 저장 |
| `ai-web-agent-console/ai_web_agent_console/presentation.py` | 공통 UI theme와 화면 표현 보조 코드 |
| `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py` | 발견된 MCP tool descriptor를 기반으로 LLM router가 server/tool을 선택하고 tool arguments를 구성 |
| `ai-web-agent-console/ai_web_agent_console/oci_genai_sdk.py` | OCI Generative AI 호출 경계. MCP/VPD token을 알지 않는 최소 completion client |
| `ai-web-agent-console/ai_web_agent_console/model_registry.py` | 모델 profile registry 로드, region/endpoint 해석, 환경 override 처리 |
| `ai-web-agent-console/ai_web_agent_console/questions.py` | 데모 질문 목록 |
| `ai-web-agent-console/config/mcp_servers.json` | MCP 서버 registry |
| `ai-web-agent-console/config/model_profiles.json` | OCI GenAI model profile registry |
| `ai-web-agent-console/config/vpd_token_presets.json` | 데모 사용자 token preset 구조. 실제 토큰은 배포 환경에서 교체 |
런처 주의사항: 스냅샷에는 `mcp_discovery_ui.py` 직접 실행에 필요한 소스가 들어 있지만, 포함된 `start_8622...` script는 원본 서버의 공용 runtime wrapper에 의존한다. 이 저장소에서 독립 실행하려면 `SOURCE_README.md`의 직접 `streamlit run` 명령을 사용하거나, 별도 wrapper를 작성해야 한다.
현재 저장소에서는 `cd ai-web-agent-console && streamlit run app.py`를 독립 실행 진입점으로 사용한다.
## 1.3 현행 보안/비밀정보 경계
- `VpdTokenPreset.token`은 dataclass에서 `repr=False`이며, UI는 token을 정규화한 뒤 Authorization header에만 넣는다.
- `_NoRedirectHandler`는 redirect 시 Authorization header가 다른 endpoint로 전달되는 것을 막는다.
- `src/mcp_tool_router.py`의 router는 질문과 tool descriptor만 받으며 bearer token 또는 provider credential을 받지 않는다.
- `src/oci_genai_sdk.py``.env`에서 `OCI_AUTH_TYPE`, `OCI_CONFIG_FILE`, `OCI_GENAI_COMPARTMENT_ID`, `OCI_PROFILE`만 읽는다.
- `ai_web_agent_console.mcp_tool_router`의 router는 질문과 tool descriptor만 받으며 bearer token 또는 provider credential을 받지 않는다.
- `ai_web_agent_console.oci_genai_sdk``.env`에서 `OCI_AUTH_TYPE`, `OCI_CONFIG_FILE`, `OCI_GENAI_COMPARTMENT_ID`, `OCI_PROFILE`만 읽는다.
- Oracle audit/business evidence 조회는 `/home/opc/kbmcp/.env`에서 `ORACLE_DB_USER`, `ORACLE_DB_PASSWORD`, `ORACLE_DSN`, `ORACLE_WALLET_PASSWORD`, `ORACLE_WALLET_DIR`를 읽는다.
- wallet 기본 fallback은 `/home/opc/wallet/kbaipoc`이다.
- 저장소에는 실제 `.env`, wallet, SQLite 대화 DB, 실제 VPD bearer token 원문을 포함하지 않는다.
@@ -97,7 +98,7 @@ SQLite 대화 이력 저장
## 2. 범위 (Scope)
- **포함**:
- `apps/poc4/mcp_discovery_ui.py`의 KB MCP endpoint, 인증 헤더, JSON-RPC, 오류 처리 정비
- `ai-web-agent-console/app.py`의 KB MCP endpoint, 인증 헤더, JSON-RPC, 오류 처리 정비
- `config/mcp_servers.json` 및 sample의 KB MCP 선언 정비
- KB MCP의 단일 도구 `ords.query.kb_select_ai_vpd` 호출 계약 문서화
- VPD Backoffice `/mcp`과의 HTTP 상태·프로토콜 버전 호환성 점검 및 필요한 최소 보완
@@ -300,8 +301,8 @@ Authorization: Bearer <current-user-vpd-token>
배포 서버의 PoC4 활성 화면 소스를 현재 저장소에 별도 폴더로 반입했다.
- 원격 실제 위치: `/home/opc/poc_4/poc4_active_source_20260714.tar.gz`
- 사용자 제시 경로 `/home/opc/poc_4/poc4_active_source_20260714/poc4_active_source_20260714.tar.gz`에는 파일이 없었고, 실제 archive는 `/home/opc/poc_4/` 바로 아래에 있었다.
- 저장소 위치: `poc4_active_source_20260714/`
- 사용자 제시 경로 `/home/opc/poc_4/ai-web-agent-console/poc4_active_source_20260714.tar.gz`에는 파일이 없었고, 실제 archive는 `/home/opc/poc_4/` 바로 아래에 있었다.
- 저장소 위치: `ai-web-agent-console/`
- 포함 파일: Streamlit UI, MCP router, OCI GenAI client, 모델 profile, token preset sample, 기동/status script, requirements
- 보안 확인: 실제 `.env`, 실제 VPD token 원문, 대화 SQLite DB는 포함하지 않았다. `vpd_token_presets.json`에는 placeholder만 있다.
- DB 참조 경로: VPD 개발본 배포 서버에서는 `/home/opc/kbmcp/.env`의 접속 정보를 사용하고, wallet directory는 `/home/opc/wallet/kbaipoc`를 사용한다. 두 경로의 파일 내용은 저장소에 포함하지 않는다.
@@ -380,7 +381,7 @@ ENABLED_COUNT = 4
SELECT_POLICY_COUNT = 4
```
현재 DB의 정책명 계열은 모두 `KB_FGA_*`다. 저장소의 범용 적용 스크립트 `sql/adb/42_agent_ords_fga_execution_audit.sql``CB_VPD_EXEC_AUDIT_<object_id>` 형태의 정책을 만들도록 작성되어 있으나, 현행 ADB에는 이 계열이 아니라 `KB_FGA_*` 정책이 적용되어 있다. 따라서 운영 확인 시에는 “스크립트 파일명/예상명”보다 `DBA_AUDIT_POLICIES`의 실제 정책명을 기준으로 봐야 한다.
현재 DB의 정책명 계열은 모두 `KB_FGA_*`다. 저장소의 범용 적용 스크립트 `database/adb/42_agent_ords_fga_execution_audit.sql``CB_VPD_EXEC_AUDIT_<object_id>` 형태의 정책을 만들도록 작성되어 있으나, 현행 ADB에는 이 계열이 아니라 `KB_FGA_*` 정책이 적용되어 있다. 따라서 운영 확인 시에는 “스크립트 파일명/예상명”보다 `DBA_AUDIT_POLICIES`의 실제 정책명을 기준으로 봐야 한다.
### 15.4 감사 이벤트 저장 위치
@@ -437,7 +438,7 @@ DBA_FGA_AUDIT_TRAIL event_count_7d = 0
### 15.6 소스 구현과 화면 연결
PoC4 스냅샷의 `apps/poc4/mcp_discovery_ui.py`는 감사로그 탭에서 다음 두 쿼리를 사용한다.
PoC4 스냅샷의 `ai-web-agent-console/app.py`는 감사로그 탭에서 다음 두 쿼리를 사용한다.
| 함수 | 조회 대상 | 역할 |
|---|---|---|

View File

@@ -2,7 +2,9 @@
## 프로젝트 개요
`poc4_active_source_20260714`는 레거시 스냅샷 경로이며, 정식 서비스명은 HMM AI 업무 에이전트다. HMM MCP를 통해 HR 데이터, 표준 용어, 규정 문서를 조회하고 대화 이력과 보안 관리 화면을 제공한다.
정식 서비스명은 HMM AI 업무 에이전트이며 현재 소스 경계는 `ai-web-agent-console/`다.
과거 `poc4_active_source_20260714` 스냅샷 경로는 #742에서 제거했다. HMM MCP를 통해 HR 데이터,
표준 용어, 규정 문서를 조회하고 대화 이력과 보안 관리 화면을 제공한다.
## 목표
@@ -10,7 +12,7 @@
## 현재 문제
- `apps/poc4/mcp_discovery_ui.py`가 화면, 설정, 인증, SQLite 대화 이력, MCP JSON-RPC, Agent 실행을 함께 관리한다.
- `ai-web-agent-console/app.py`가 화면, 설정, 인증, SQLite 대화 이력, MCP JSON-RPC, Agent 실행을 함께 관리한다.
- MCP 설정과 인증 토큰 규칙을 수정할 때 화면 코드까지 함께 읽어야 한다.
- MCP 프로토콜 처리의 단위 검증 지점이 없다.
@@ -18,14 +20,15 @@
| 모듈 | 책임 | Streamlit 의존 |
| --- | --- | --- |
| `src/poc4/runtime_config.py` | `.env`, MCP 서버 JSON, VPD preset 로드와 검증 | 없음 |
| `src/poc4/mcp_client.py` | endpoint 검증, JSON-RPC, 세션 fallback, tool discovery/call | 없음 |
| `src/poc4/chat_store.py` | SQLite 대화 이력 CRUD | 없음 |
| `apps/poc4/mcp_discovery_ui.py` | 사용자 입력, 상태, 화면 렌더링, 업무 Agent orchestration | 음 |
| `ai-web-agent-console/ai_web_agent_console/profile.py` | 제품 프로필과 환경 override 로드 | 없음 |
| `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py` | MCP 도구 discovery 결과의 route와 arguments 구성 | 없음 |
| `ai-web-agent-console/ai_web_agent_console/auth_gateway.py` | 로그인·쿠키·세션 경계 | 없음 |
| `ai-web-agent-console/ai_web_agent_console/audit.py` | 감사·증적 조회 경계 | 음 |
| `ai-web-agent-console/app.py` | 사용자 입력, 상태, 화면 렌더링, 업무 Agent orchestration | 있음 |
### 재사용 UI Shell과 제품 프로필
공통 화면 shell은 `src/agent_console/`에서 제공하고, 특정 고객·PoC의 표현은
공통 화면 shell은 `ai-web-agent-console/ai_web_agent_console/`에서 제공하고, 특정 고객·PoC의 표현은
`config/app_profile.json`에 둔다. 다른 프로젝트는 앱 코드를 복사·수정하지 않고 profile JSON을
교체할 수 있다. 실제 배포에서는 `AGENT_CONSOLE_NAME`, `AGENT_CONSOLE_HEADER_DESCRIPTION`,
`AGENT_CONSOLE_PRIMARY_COLOR``AGENT_CONSOLE_*` 환경변수가 JSON 기본값보다 우선한다.
@@ -48,7 +51,7 @@
2. 변경은 Redmine 이슈에 설계·검증 결과와 Git commit SHA를 함께 기록한다.
3. Git commit message에는 Redmine 번호를 `refs #<번호>:` 형식으로 포함한다.
4. 환경별 값과 비밀값은 profile JSON에 넣지 않고 `.env` 또는 secret store에만 둔다.
5. UI CSS는 `src/agent_console/presentation.py` 한 곳에서 관리한다. 제품별 색상과 문구는 Python/CSS를 수정하지 않고 `app_profile.json`으로 조정한다.
5. UI CSS는 `ai-web-agent-console/ai_web_agent_console/presentation.py` 한 곳에서 관리한다. 제품별 색상과 문구는 Python/CSS를 수정하지 않고 `app_profile.json`으로 조정한다.
도메인 로직의 공개 오류는 `PublicMcpError`로 통일한다. UI는 이 오류를 사람이 이해할 수 있는 메시지로 표시하되 토큰과 HTTP 원문을 출력하지 않는다.

View File

@@ -60,7 +60,7 @@ HMM_KNOWLEDGE_DOCUMENTS ──< HMM_KNOWLEDGE_CHUNKS ──< HMM_KNOWLEDGE_TAGS
- `/structured-data``/schema-metadata`의 데이터 원본명, Oracle owner, 안내 문구, 최대 조회 건수,
허용 테이블 목록은 Java·HTML에 하드코딩하지 않는다.
- 기본 HMM 정의는 `src/main/resources/config/structured-data-catalog.json`에 둔다. 배포 환경에서는
- 기본 HMM 정의는 `vpd-backoffice/src/main/resources/config/structured-data-catalog.json`에 둔다. 배포 환경에서는
`BACKOFFICE_STRUCTURED_DATA_CATALOG_LOCATION=file:/.../structured-data-catalog.json`으로 외부
JSON을 지정할 수 있어 다른 회사 PoC에서 애플리케이션 코드를 수정하지 않고 재사용할 수 있다.
- 각 테이블 정의는 `key`, `tableName`, `businessName`, `description`을 기본으로 하고 필요하면

View File

@@ -73,7 +73,7 @@ E1001에는 `HMM_HR_MANAGER`, E1002~E1007에는 `HMM_HR_VIEWER`를 부여한다.
## 배포 순서
1. 애플리케이션 테스트와 SQL 구문 검사를 수행한다.
2. 멱등 SQL `sql/adb/72_hmm_leave_team_vpd.sql``ADMIN`으로 실행한다.
2. 멱등 SQL `database/adb/72_hmm_leave_team_vpd.sql``ADMIN`으로 실행한다.
3. VPD 정책·컴파일 상태·백오피스 화면을 확인한다.
4. 백오피스와 같은 SHA-256 저장 규칙으로 E1001과 E1002 임시 검증 토큰을 만든다.
5. 비면제 검증 사용자에서 토큰별 조회 결과를 확인하고 검증 토큰과 사용자를 제거한다.

View File

@@ -182,7 +182,7 @@ HMM 운영 MCP는 현재 세 개의 Agent Tool을 사용하므로 Select AI 접
BACKOFFICE_SECURITY_SQL_SCRIPTS
```
번들된 `sql/adb` 경로 안의 파일만 허용하며 요청값을 resource path로 사용하지 않는다.
번들된 `database/adb` 경로 안의 파일만 허용하며 요청값을 resource path로 사용하지 않는다.
HMM 운영에서는 `72_hmm_leave_team_vpd.sql` 등 HMM 관련 SQL만 노출한다.
## 5. 코드 구조

View File

@@ -110,8 +110,8 @@ CHECK 제약으로 보장한다. 월별 조회와 위험 선사 조회에 각각
## 7. 적재 순서
1. RDS TLS와 현재 계정의 CREATE 권한을 확인한다.
2. `sql/source/postgres_hmm_carrier_performance.sql`을 실행한다.
3. `sql/source/postgres_hmm_carrier_performance_verify.sql`을 실행한다.
2. `database/source/postgres_hmm_carrier_performance.sql`을 실행한다.
3. `database/source/postgres_hmm_carrier_performance_verify.sql`을 실행한다.
4. 재실행 후에도 동일한 선사 8개와 실적 144행인지 확인한다.
5. 후속 작업에서 ADB credential과 PostgreSQL database link를 만든다.

View File

@@ -0,0 +1,112 @@
# #742 애플리케이션 단위 저장소 구조 개편
## 문제
현재 저장소 루트의 `pom.xml`, `src/main`, `src/test`는 실제로 하나의 Spring Boot
백오피스지만 제품 폴더 없이 저장소 전체 애플리케이션처럼 보인다. Streamlit 앱은
`poc4_active_source_20260714`라는 날짜 스냅샷 폴더에 있고 내부에서도 `poc3`, `poc4`,
`agent_console`, 단독 Python 모듈이 서로 참조한다.
이 구조에서는 다음 내용을 파일 경로만 보고 알 수 없다.
- 어떤 파일이 실제 배포 애플리케이션인지
- Spring Boot와 Streamlit의 빌드·테스트 경계가 어디인지
- `poc3`, `poc4`가 제품명인지 과거 실험 번호인지
- DB 스크립트와 특정 애플리케이션의 관계가 무엇인지
## 목표 구조
```text
vpd-permission-poc/
├── vpd-backoffice/ Spring Boot VPD·권한 관리 백오피스
│ ├── pom.xml
│ ├── src/main/
│ └── src/test/
├── ai-web-agent-console/ Streamlit AI 업무 에이전트
│ ├── app.py
│ ├── ai_web_agent_console/ 단일 Python 패키지
│ ├── config/
│ ├── tests/
│ └── requirements.txt
├── dds-backoffice/ 별도 DDS 백오피스
├── database/
│ ├── adb/
│ └── source/
├── deploy/ 제품별 배포 설정
├── docs/ 설계·운영·검증 문서
├── scripts/ 저장소 공통 자동화
└── README.md
```
## 이동 매핑
| 기존 | 변경 | 처리 |
|---|---|---|
| `pom.xml` | `vpd-backoffice/pom.xml` | Maven 프로젝트 경계 명시 |
| `src/main` | `vpd-backoffice/src/main` | Spring 애플리케이션 소스 |
| `src/test` | `vpd-backoffice/src/test` | Spring 단위·통합 테스트 |
| `sql/adb` | `database/adb` | Oracle/ADB 스크립트 |
| `sql/source` | `database/source` | 외부 원천 DB 스크립트 |
| `poc4_active_source_20260714` | `ai-web-agent-console` | 날짜·PoC 번호 제거 |
| `apps/poc4/mcp_discovery_ui.py` | `ai-web-agent-console/app.py` | 명확한 Streamlit 진입점 |
| `src/agent_console/*` | `ai-web-agent-console/ai_web_agent_console/*` | 단일 제품 패키지 |
| `src/poc3/model_registry.py` | `ai-web-agent-console/ai_web_agent_console/model_registry.py` | 실험 번호 제거 |
| `src/poc3/questions.py` | `ai-web-agent-console/ai_web_agent_console/questions.py` | 실험 번호 제거 |
| `src/poc4/scenarios.py` | `ai-web-agent-console/ai_web_agent_console/scenarios.py` | 실험 번호 제거 |
| `src/poc4/query_contracts.py` | `ai-web-agent-console/ai_web_agent_console/query_contracts.py` | 실험 번호 제거 |
| `src/mcp_*.py`, `src/oci_genai_sdk.py` | `ai-web-agent-console/ai_web_agent_console/` | 앱 전용 공용 모듈 통합 |
| `config/poc3_model_profiles.json` | `ai-web-agent-console/config/model_profiles.json` | 실험 번호 제거 |
## 경로 규칙
1. 저장소 루트에는 애플리케이션 프레임워크의 `src``pom.xml`을 두지 않는다.
2. 각 애플리케이션은 자신의 소스, 의존성 선언, 테스트 진입점을 가진다.
3. DB 스크립트는 `database`를 Git 원본으로 사용하고 Spring JAR는 해당 경로를
리소스로 포함한다.
4. 배포 설정은 `deploy/<application>`에서 새 소스 경로를 참조한다.
5. 과거 경로를 유지하는 심볼릭 링크나 복제본은 만들지 않는다. 잘못된 경로가 다시
사용되면 테스트가 실패하도록 한다.
6. 운영 중인 환경변수와 SQLite 테이블명은 데이터 호환을 위해 이번 변경에서 유지한다.
폴더·패키지·실행 경로에서만 PoC 명칭을 제거한다.
## Maven 변경
`vpd-backoffice/pom.xml`의 SQL 리소스 경로는 `../database/adb`를 사용한다. 루트 자동화는
`mvn -f vpd-backoffice/pom.xml`을 사용하며 앱 디렉토리 안에서는 기존처럼 `mvn test`
동작해야 한다.
Java 테스트에서 파일을 직접 여는 경로는 앱 디렉토리를 기준으로 유지한다. 따라서
`vpd-backoffice`에서 실행한 테스트와 루트에서 `-f`로 실행한 테스트를 모두 확인한다.
## Python 변경
`ai-web-agent-console/app.py`는 자신의 부모 폴더를 애플리케이션 루트로 사용한다.
모든 import는 `ai_web_agent_console.<module>` 형식으로 통일한다. 테스트도 같은 공개
패키지 경로만 사용한다.
`model_profiles.json` 안의 `default_for_poc3` 속성은 `default_for_console`로 바꾸고
로더·검증 코드도 함께 변경한다. 배포된 비밀정보 파일과 대화 DB는 Git 이동 대상이
아니다.
## 배포 변경
- Spring 배포 빌드는 `vpd-backoffice/pom.xml``vpd-backoffice/target`을 사용한다.
- Streamlit 실행은 `streamlit run app.py`를 사용한다.
- 인증 게이트웨이는 `python -m ai_web_agent_console.auth_gateway`를 사용한다.
- 기존 운영 디렉토리 `/opt/hmm-poc4`는 무중단 전환을 위해 물리 경로로 유지할 수 있지만,
서비스의 Git 소스 경로와 Python 모듈명은 새 구조를 사용한다.
## 검증
1. `git status --short`에서 기존 #741 변경이 새 경로에 남아 있는지 확인한다.
2. `mvn -f vpd-backoffice/pom.xml test`를 실행한다.
3. Python 전체 소스에 `compileall`을 실행한다.
4. `unittest discover -s ai-web-agent-console/tests`를 실행한다.
5. `rg`로 운영 코드의 `src.poc3`, `src.poc4`, `src.agent_console`,
`poc4_active_source_20260714`, `apps/poc4` 참조가 0건인지 확인한다.
6. 배포 스크립트의 dry-run 또는 정적 경로 검증을 수행한다.
## 롤백
모든 이동은 한 Git 커밋으로 추적한다. 문제가 생기면 해당 커밋을 revert하여 이전 경로와
import를 함께 복구한다. DB 스키마와 운영 데이터는 이 구조 변경에서 수정하지 않는다.

View File

@@ -98,7 +98,7 @@ STEP 8 (선택) ALTER TABLE ... SET USE DATA GRANTS ONLY ENABLED -- MAC 모드
STEP 9 감사 (dba_data_grants 등) + 역순 정리
```
전체 스크립트는 세션 본문 참조. 이 POC 의 `sql/adb/13_dds_variant.sql` + `15_dds_cleanup.sql` 가 동일 패턴.
전체 스크립트는 세션 본문 참조. 이 POC 의 `database/adb/13_dds_variant.sql` + `15_dds_cleanup.sql` 가 동일 패턴.
---
@@ -325,8 +325,8 @@ CREATE DATA GRANT admin.dg_scoped
### 이 POC 에서 보면
- `sql/adb/06_policy.sql` + `permission` 테이블 = "앱/운영자가 행으로 권한 관리" → **VPD 답안**
- `sql/adb/13_dds_variant.sql` = "DBA 가 DDL 로 4 종 역할 정의" → **DDS 답안**
- `database/adb/06_policy.sql` + `permission` 테이블 = "앱/운영자가 행으로 권한 관리" → **VPD 답안**
- `database/adb/13_dds_variant.sql` = "DBA 가 DDL 로 4 종 역할 정의" → **DDS 답안**
- 같은 결과를 두 다른 모델로 표현한 비교 데모
**권한 매핑 테이블 중심으로 가겠다면 VPD 그대로 두는 게 정답.**

View File

@@ -0,0 +1,28 @@
# HMM 화면 전환
대상 기업을 HMM으로 전환하면서 PoC4의 로그인·헤더 화면을 해운·물류 업무 에이전트로 재구성한다.
- 공식 페이지의 `Connect Values Navigate Growth` 메시지와 해운·물류·디지털 솔루션 맥락을 반영한다.
- 외부 KB 로고·전용 글꼴 의존성을 제거하고, 애플리케이션 내부 SVG 워드마크와 해양 청색 계열로 표시한다.
- 기존 MCP, VPD, 데이터베이스 스키마 및 도구 계약은 변경하지 않는다.
- 로그인 유지 기능은 서버 비밀키로 서명한 7일 만료 토큰을 사용하며, 로그아웃 시 즉시 폐기한다.
- 공통 화면 CSS와 로그인/헤더 renderer는
`ai-web-agent-console/ai_web_agent_console/presentation.py`에서 관리한다.
HMM의 제품명·문구·색상은 `config/app_profile.json`에만 둔다.
# HMM MCP runtime wiring
The PoC4 MCP registry defaults to `hmm_hr_mcp` (`https://hmm-mcp.cloud-handson.com/mcp`).
Its gateway credential is supplied only at runtime as `HMM_MCP_BEARER_TOKEN` in the
deployed `.env`; it is intentionally not committed and is not the selected VPD user's token.
## HMM demo user presets
`config/vpd_token_presets.json` is retained as a legacy deployment filename, but its content is
an HMM HR demo-user list. The Streamlit sidebar uses it to select a manager or team-member
persona and resolves pronouns such as “내” and “우리 팀” in the test question. Each preset uses
`mcp_token_env: HMM_MCP_BEARER_TOKEN`; the bearer value stays in `/opt/hmm-poc4/.env` and is
never rendered, downloaded, or committed. The selector is a test context, not a claim of
row-level authorization enforcement.
The security-operation link in the Streamlit console points to
`https://hmm-backoffice.cloud-handson.com/`, the HMM access-management backoffice.

View File

@@ -12,10 +12,10 @@
기존 Handler가 trace 필드를 반환하지 않으면 백오피스가 같은 DB 연결에서 `set_user_by_bearer``CB_AGENT_DOC_VPD_FILTER``clear_user` 순서로 기본 VPD predicate를 조회한다. 이 보조 조회가 실패해도 권한 결과 자체는 실패 처리하지 않는다.
기존 설치에 trace 권한을 추가하려면 ADMIN으로 `sql/adb/33_agent_ords_sql_trace_grant.sql`을 실행한 뒤 CB_ORDS로 `22_agent_ords_security_ords_handler_setup.sql`을 재실행하거나 `/ords-handlers`에서 trace가 포함된 Handler source를 저장한다.
기존 설치에 trace 권한을 추가하려면 ADMIN으로 `database/adb/33_agent_ords_sql_trace_grant.sql`을 실행한 뒤 CB_ORDS로 `22_agent_ords_security_ords_handler_setup.sql`을 재실행하거나 `/ords-handlers`에서 trace가 포함된 Handler source를 저장한다.
기본으로 표시되는 SQL은 해당 토큰 컨텍스트에서 VPD 정책 함수가 반환한 행 predicate를 기본 Handler SELECT에 결합한 확인용 SQL이다. Bearer 원문은 trace나 응답에 포함하지 않는다.
실행 DB가 `V$SQL``DBMS_XPLAN` 조회를 허용하면 `/probe`는 최근 2분 내 같은 보호 객체의 SQL_ID, DB가 기록한 원문 SQL, cursor 누적 통계, Predicate Information도 함께 표시한다. `V$SQL` 원문은 VPD 주입 전 SQL이고, 실제 적용 조건은 `DBMS_XPLAN`의 Predicate Information에서 확인한다. 같은 객체에 동시 요청이 많은 경우에는 최근 cursor 매칭이므로 요청 ID 기반 상관 추적이 필요하다.
Autonomous DB에서 일반 `ADMIN` 계정은 `SYS.V_$SQL` 권한을 ORDS 계정에 위임하지 못할 수 있다. 이 경우에는 SYS/DBA가 [34_agent_ords_execution_evidence_grant.sql](../../sql/adb/34_agent_ords_execution_evidence_grant.sql)을 실행해 진단 권한을 준비해야 한다. 권한을 얻지 못해도 접근 검증 결과와 기존 권한 조건 재현 SQL은 그대로 제공된다.
Autonomous DB에서 일반 `ADMIN` 계정은 `SYS.V_$SQL` 권한을 ORDS 계정에 위임하지 못할 수 있다. 이 경우에는 SYS/DBA가 [34_agent_ords_execution_evidence_grant.sql](../../database/adb/34_agent_ords_execution_evidence_grant.sql)을 실행해 진단 권한을 준비해야 한다. 권한을 얻지 못해도 접근 검증 결과와 기존 권한 조건 재현 SQL은 그대로 제공된다.

View File

@@ -54,7 +54,7 @@ EXTERNAL_CLAUSE_NAME=개인용애니카다이렉트자동차보험
변경 스크립트:
- `sql/adb/65_kb_select_ai_vpd_query_api.sql`
- `database/adb/65_kb_select_ai_vpd_query_api.sql`
## RAG 근거 검색 확인 결과

View File

@@ -202,7 +202,7 @@ c_profile_name CONSTANT VARCHAR2(128) := 'KB_AIDP_SELECTAI_GPT54_MINI_COMMENTS_P
대상 스크립트:
```text
sql/adb/65_kb_select_ai_vpd_query_api.sql
database/adb/65_kb_select_ai_vpd_query_api.sql
```
### ORDS 응답 표시
@@ -216,7 +216,7 @@ profile=KB_AIDP_SELECTAI_GPT54_MINI_COMMENTS_PROFILE_V1
대상 스크립트:
```text
sql/adb/66_kb_select_ai_vpd_query_ords.sql
database/adb/66_kb_select_ai_vpd_query_ords.sql
```
### MCP 응답 표시
@@ -226,8 +226,8 @@ MCP tool 응답 payload의 profile 표시와 화면 설명을 새 프로파일
대상 소스:
```text
src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java
src/main/resources/templates/mcp-sse.html
vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/service/McpSseService.java
vpd-backoffice/src/main/resources/templates/mcp-sse.html
```
## 최종 속도 측정

View File

@@ -8,7 +8,7 @@
## 적용 결과
`sql/adb/72_hmm_leave_team_vpd.sql`을 적용해 다음 구성을 활성화했다.
`database/adb/72_hmm_leave_team_vpd.sql`을 적용해 다음 구성을 활성화했다.
| 구성 | 결과 |
|---|---|

View File

@@ -32,7 +32,7 @@
## 이번에 제거한 결함
1. 감사로그가 KB PoC의 `POC_2` FGA 메타데이터를 조회하던 경로를 제거했다.
2. 감사 원천을 `ADMIN.HMM_ACCESS_AUDIT`으로 교체하고 렌더러를 `src/agent_console/audit.py`
2. 감사 원천을 `ADMIN.HMM_ACCESS_AUDIT`으로 교체하고 렌더러를 `ai-web-agent-console/ai_web_agent_console/audit.py`
분리했다.
3. Python Thin driver가 암호화 `ewallet.pem`의 암호를 대화형으로 기다리던 연결을 ADB TLS 1521
서버 인증 풀로 교체했다.

View File

@@ -25,9 +25,9 @@ SQLCL_BIN=/path/to/sql SQLCL_JAVA_HOME=/path/to/jdk "$SQLCL_BIN" "USER/PASSWORD@
SQLcl 안에서 실행:
```sql
@sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql
@database/adb/26_agent_ords_security_dynamic_vpd_filter.sql
SHOW ERRORS FUNCTION cb_agent_doc_vpd_filter
@sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql
@database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql
```
기대 결과:
@@ -64,7 +64,7 @@ SQLCL_JAVA_HOME=/path/to/jdk \
가장 단순한 롤백은 직전 Git revision의 `26_agent_ords_security_dynamic_vpd_filter.sql`을 다시 적용하는 것이다.
```bash
git show HEAD~1:sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql > /tmp/previous-vpd-filter.sql
git show HEAD~1:database/adb/26_agent_ords_security_dynamic_vpd_filter.sql > /tmp/previous-vpd-filter.sql
SQLCL_BIN=/path/to/sql SQLCL_JAVA_HOME=/path/to/jdk "$SQLCL_BIN" "USER/PASSWORD@TNS"
```

View File

@@ -151,7 +151,7 @@ BACKOFFICE_SELECT_AI_RUNTIME_DB_USERNAME=CB_ORDS
BACKOFFICE_SELECT_AI_RUNTIME_DB_PASSWORD=<운영 secret>
```
DB 구성 스크립트는 `sql/adb/73_hmm_mcp_vpd_runtime.sql`이다. 이 스크립트는 승인된 HMM
DB 구성 스크립트는 `database/adb/73_hmm_mcp_vpd_runtime.sql`이다. 이 스크립트는 승인된 HMM
HR 객체에 대한 개별 `SELECT`와 handler package 실행 권한만 부여하며
`EXEMPT ACCESS POLICY`는 부여하지 않는다.