@@ -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 만 보임
|
||||
|
||||
@@ -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 설치 불필요.
|
||||
|
||||
@@ -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` | 판정 |
|
||||
|---|---|---|---|
|
||||
|
||||
@@ -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 정책 연결 확인:
|
||||
|
||||
|
||||
@@ -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 단계로 계속 이동할지 결정이 필요하다.
|
||||
|
||||
@@ -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 결과 유지 확인.
|
||||
|
||||
|
||||
@@ -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. 시그니처
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
|
||||
@@ -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 요청을 거부한다.
|
||||
|
||||
@@ -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`
|
||||
|
||||
## 목적
|
||||
|
||||
|
||||
@@ -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 계정을 사용한다.
|
||||
|
||||
|
||||
@@ -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. 시그니처
|
||||
|
||||
|
||||
@@ -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. 시그니처
|
||||
|
||||
|
||||
@@ -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. 결정과 목적
|
||||
|
||||
|
||||
@@ -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`는 감사로그 탭에서 다음 두 쿼리를 사용한다.
|
||||
|
||||
| 함수 | 조회 대상 | 역할 |
|
||||
|---|---|---|
|
||||
|
||||
@@ -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 원문을 출력하지 않는다.
|
||||
|
||||
|
||||
@@ -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`을 기본으로 하고 필요하면
|
||||
|
||||
@@ -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. 비면제 검증 사용자에서 토큰별 조회 결과를 확인하고 검증 토큰과 사용자를 제거한다.
|
||||
|
||||
@@ -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. 코드 구조
|
||||
|
||||
@@ -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를 만든다.
|
||||
|
||||
|
||||
112
docs/design/742-application-oriented-repository-layout/README.md
Normal file
112
docs/design/742-application-oriented-repository-layout/README.md
Normal 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 스키마와 운영 데이터는 이 구조 변경에서 수정하지 않는다.
|
||||
@@ -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 그대로 두는 게 정답.**
|
||||
|
||||
28
docs/notes/hmm-brand-refresh.md
Normal file
28
docs/notes/hmm-brand-refresh.md
Normal 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.
|
||||
@@ -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은 그대로 제공된다.
|
||||
|
||||
@@ -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 근거 검색 확인 결과
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
## 최종 속도 측정
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
## 적용 결과
|
||||
|
||||
`sql/adb/72_hmm_leave_team_vpd.sql`을 적용해 다음 구성을 활성화했다.
|
||||
`database/adb/72_hmm_leave_team_vpd.sql`을 적용해 다음 구성을 활성화했다.
|
||||
|
||||
| 구성 | 결과 |
|
||||
|---|---|
|
||||
|
||||
@@ -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
|
||||
서버 인증 풀로 교체했다.
|
||||
|
||||
@@ -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"
|
||||
```
|
||||
|
||||
|
||||
@@ -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`는 부여하지 않는다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user