[Developer] #573 normalize vector access whitelist
This commit is contained in:
64
docs/design/573-vector-all-role-normalization/README.md
Normal file
64
docs/design/573-vector-all-role-normalization/README.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# 설계서: 전체 벡터 접근 역할의 ALL predicate 정규화 (#573)
|
||||
|
||||
> **상태**: Implemented · QA passed
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-06-30
|
||||
> **추적성** — Redmine: #573 · 선행 기능: #558, #570, #572
|
||||
> · 구현 파일: `32_dds_vector_tag_setup.sql`, `38_agent_ords_vector_all_permission_normalization.sql`, `29_agent_ords_vector_search_ords.sql`, `OrdsProbeService`
|
||||
> · 테스트: `OrdsProbeServiceTest`, `GuidedFlowTemplateTest`, `mvn test`, 운영 vector probe
|
||||
|
||||
## 1. 목적
|
||||
|
||||
기본 벡터 접근은 역할 기반 whitelist다. 기본 역할(10·20·30)에 `CB_VECTOR_SEARCH_DOCUMENTS / SELECT / ALLOW / ALL`을 저장하고, 그 역할을 가진 사용자는 전체 벡터 청크를 조회한다. 역할 권한이 없는 사용자는 VPD의 fail-closed predicate `1 = 0`으로 차단한다.
|
||||
|
||||
`TAG`, 부서, 소유자 같은 행 조건은 관리자가 **ALL rule이 없는 제한 역할**에 실제로 등록했을 때만 추가한다. 기본 예제 역할에 임의의 TAG rule을 넣지 않는다.
|
||||
|
||||
| 역할 | permission rule | VPD predicate | effective SQL 권한 조건 |
|
||||
|---|---|---|---|
|
||||
| `HR_DEPT_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
|
||||
| `FIN_SELF_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
|
||||
| `ALL_DOC_ROLE` | `ALL` | `1 = 1` | 조건 생략 |
|
||||
| 관리자가 TAG rule을 준 역할 | `TAG: ...` | TAG OR | `AND (REGEXP_LIKE(...))` |
|
||||
| 권한 없음 | allow rule 없음 | `1 = 0` | `AND (1 = 0)` |
|
||||
|
||||
## 2. 범위
|
||||
|
||||
- 초기화 SQL에서 기본 역할 10·20·30의 개별 TAG rule을 제거하고 `ALL` rule을 보장.
|
||||
- 이미 설치된 DB를 위한 idempotent migration SQL 제공 및 운영 적용.
|
||||
- vector ORDS/백오피스 effective SQL trace에서 predicate가 `1 = 1`이면 `AND` 절을 출력하지 않음.
|
||||
- 특정 TAG role의 `REGEXP_LIKE` filter와 fail-closed `1 = 0`은 유지.
|
||||
|
||||
## 3. 인수조건
|
||||
|
||||
- [x] 기본 whitelist 역할 사용자(`agent_hr`, `agent_fin_self`, `agent_all`)의 VPD predicate가 정확히 `1 = 1`이다.
|
||||
- [x] 기본 whitelist 역할의 vector effective SQL에 `REGEXP_LIKE`와 `AND (1 = 1)`이 없다.
|
||||
- [x] 관리자가 TAG rule을 실제로 부여한 역할만 해당 TAG predicate를 포함한다.
|
||||
- [x] 기본 역할 10·20·30의 기존 vector TAG rule은 migration 후 제거되고 ALL rule은 각 한 개만 존재한다.
|
||||
- [x] 권한 없는 사용자 결과는 기존 fail-closed semantics를 유지한다.
|
||||
- [x] SQL trace에 Bearer 원문·임베딩 숫자가 포함되지 않는다.
|
||||
|
||||
## 4. 구현 흐름
|
||||
|
||||
```text
|
||||
whitelist role
|
||||
→ CB_PERMISSION (CB_VECTOR_SEARCH_DOCUMENTS / SELECT / ALLOW)
|
||||
→ CB_PERMISSION_RULE (ALL)
|
||||
→ CB_AGENT_DOC_VPD_FILTER = 1 = 1
|
||||
→ vector effective SQL: base VECTOR_DISTANCE query only
|
||||
```
|
||||
|
||||
기존 기본 역할의 TAG rule은 현재 fixture의 태그만 허용할 뿐 이후 추가되는 청크를 불필요하게 막는다. 기본 whitelist는 `ALL` rule로 유지하고, 제한이 필요한 역할에만 명시적 행 rule을 부여한다.
|
||||
|
||||
## 5. 검증
|
||||
|
||||
- `vectorEffectiveSql(..., "1 = 1")`가 `AND (1 = 1)`을 만들지 않는 단위 테스트.
|
||||
- setup/migration source가 role 30의 ALL rule과 TAG rule 정리를 포함하는 템플릿/소스 테스트.
|
||||
- `mvn test`.
|
||||
- 운영 smoke: `tempUserId=101`, `102`, `103`으로 vector `/probe`를 실행해 모두 `VPD predicate = 1 = 1`, `REGEXP_LIKE` 없는 effective SQL, `SCORE` Top-K를 확인한다. 권한 없는 별도 사용자는 `1 = 0`인지 확인한다.
|
||||
|
||||
## 6. 구현·QA 결과
|
||||
|
||||
- `38_agent_ords_vector_all_permission_normalization.sql`을 운영 DB에 적용해 기본 role 10·20·30의 legacy TAG rule을 제거하고 `ALL` rule을 보장했다.
|
||||
- ORDS vector handler(29)를 재등록하고 백오피스를 배포했다.
|
||||
- `mvn test`: 59 tests, 0 failures.
|
||||
- 운영 `/probe` smoke(2026-06-30): `agent_hr(101)`, `agent_fin_self(102)`, `agent_all(103)` 모두 `1 = 1 (ALL: 추가 행 필터 없음)` 및 `WHERE d.embedding IS NOT NULL ORDER BY score`를 반환했다. 세 결과에 `REGEXP_LIKE`와 `AND (1 = 1)`은 없었다.
|
||||
- 권한 없는 역할의 VPD 함수 경로는 변경하지 않아 기존 `1 = 0` fail-closed 동작을 유지한다.
|
||||
Reference in New Issue
Block a user