Files
vpd-permission-poc/docs/design/619-stakeholder-token-permission-example/README.md

7.7 KiB

설계서: 이해당사자 토큰과 역할 기반 KB 원장 권한 예제 (#619)

상태: Implemented · QA passed · deployed 작성: [AI] Architect · 최종수정: 2026-07-07 추적성 — Redmine: #619 · 관련 설계: #618 정형 데이터 원장 조회, #492 토큰 검증 흐름

1. 목적

POC_2.KB_STAKEHOLDERS를 업무 사용자 원장으로 삼아 모든 이해당사자에게 Bearer Token을 발급한다. 토큰의 실제 주체, 역할, 채널은 해당 원장에서만 해석하고, 접근 허용 여부는 백오피스의 접근 규칙(역할 → 보호 객체 → 행 규칙/표시 예외)으로 관리한다.

2. 핵심 결정

  • CB_AGENT_BEARER_KEY.STAKEHOLDER_USER_IDKB_STAKEHOLDERS.USER_ID를 가리킨다. 기존 숫자형 USER_ID는 기존 기능 호환용 application-user bridge로 유지한다.
  • 이해당사자마다 CB_APP_USER.STAKEHOLDER_USER_ID bridge를 하나 만들고, KB_STAKEHOLDERS.ROLE지점장이면 KB_BRANCH_MANAGER_ROLE, 설계사이면 KB_DESIGNER_ROLE을 부여한다. 다른 역할은 토큰은 발급되지만 별도 권한을 추가하기 전까지 fail-closed다.
  • VPD package는 토큰에서 STAKEHOLDER_USER_ID, STAKEHOLDER_ROLE, 정규화된 STAKEHOLDER_CHANNEL을 application context에 설정한다. 설계사채널 → 설계사, GA채널 → GA를 정규화한다.
  • 토큰의 업무 역할은 KB_STAKEHOLDERS에서 한 번 해석해 context에 넣고, 그 역할에 매핑된 CB_PERMISSION이 어떤 조건 코드를 사용할지 결정한다. filter predicate에 업무 역할명은 직접 저장하지 않는다.
  • 행 규칙은 두 가지다. allowlist condition code는 secure context 값으로 치환하고, STATIC_SQL은 현재 보호 객체 컬럼만 사용하는 검증된 정적 WHERE 조건식을 그대로 추가한다.

3. 예제 권한

역할 보호 객체 행 규칙 결과
KB_DESIGNER_ROLE KB_CONTRACTS FC_ID / OWN_CONTRACT 본인 담당 계약
KB_BRANCH_MANAGER_ROLE KB_CONTRACTS FC_CHANNEL / CHANNEL_CONTRACT 같은 채널 계약
KB_DESIGNER_ROLE 고객·담보·청구·외부보유 CUST_ID / OWN_CUSTOMER 본인 담당 고객 기준
KB_BRANCH_MANAGER_ROLE 고객·담보·청구·외부보유 CUST_ID / CHANNEL_CUSTOMER 같은 채널 고객 기준
KB_STAKEHOLDER_IDENTITY_ROLE KB_STAKEHOLDERS USER_ID / TOKEN_SUBJECT 토큰 주체 자신의 매핑 행

OWN_CONTRACT, CHANNEL_CONTRACT, OWN_CUSTOMER, CHANNEL_CUSTOMER, TOKEN_SUBJECT는 접근 규칙 화면에서 선택하는 filter 조건 코드다. Bearer Token을 해석할 때 KB_STAKEHOLDERS를 한 번만 조회해 STAKEHOLDER_USER_ID, STAKEHOLDER_ROLE, STAKEHOLDER_CHANNEL secure context를 만들고, VPD filter가 condition code를 대상 object의 WHERE 조각으로 확장한다.

각 접근 규칙 안에서는 치환된 condition code와 STATIC_SQLAND로 합친다. 예를 들어 본인 담당 고객 / CUST_IDCONTRACT_STATUS = '정상' 정적 조건을 더하면, 담당 고객이면서 상태가 정상인 행만 허용된다. 서로 다른 ALLOW 권한(역할/권한 세트)은 OR, DENY 권한은 최종 허용 결과에서 제외한다. STATIC_SQL은 세미콜론·주석·서브쿼리·다른 테이블 참조를 차단하고 현재 보호 객체의 컬럼과 allowlist SQL 연산자만 허용한다.

-- 고객·청구·외부보유의 CUST_ID 예시: permission condition code 확장 결과
EXISTS (
  SELECT 1
  FROM POC_2.KB_CONTRACTS c
  WHERE c.CUST_ID = <현재행>.CUST_ID
    AND c.FC_ID = SYS_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_USER_ID')
)
OR EXISTS (
  SELECT 1
  FROM POC_2.KB_CONTRACTS c
  WHERE c.CUST_ID = <현재행>.CUST_ID
    AND c.FC_CHANNEL = SYS_CONTEXT('CB_AGENT_CTX', 'STAKEHOLDER_CHANNEL')
)

어느 분기를 사용할지는 token context에 매핑된 effective role의 permission이 결정한다. 토큰 원문은 predicate에 노출하지 않으며, CB_AGENT_BEARER_KEY → KB_STAKEHOLDERS에서 한 번 검증·해석한 subject context만 사용한다.

4. CLS / NULL 처리

아래 컬럼은 CB_PERMISSION_COLUMN원문 표시 허용에 포함되지 않으면 VPD의 SEC_RELEVANT_COL_OPT=ALL_ROWS로 NULL 처리한다. 즉, 행 접근과 원문 표시 예외를 같은 접근 규칙 화면에서 분리 관리한다.

테이블 기본 NULL 처리 컬럼
KB_CUSTOMERS CUST_NM, RRN_MASKED
KB_CLAIMS CLAIM_AMT, PAID_AMT
KB_EXTERNAL_HOLDINGS EXT_INSURER, EXT_PRODUCT_GRP, EXT_PRODUCT_TYPE

초기 예제는 표시 예외를 비워 두므로 지점장·설계사 모두 해당 원문을 보지 못한다. 운영자는 역할별 권한에서 필요한 컬럼만 명시적으로 추가할 수 있다.

5. 흐름

KB_STAKEHOLDERS
   ├─ token issue → CB_AGENT_BEARER_KEY.STAKEHOLDER_USER_ID
   └─ role sync  → CB_APP_USER bridge → CB_USER_ROLE
                                         ↓
Bearer Token → CB_AGENT_CTX_PKG → application context
                                         ↓
                         CB_PERMISSION / CB_PERMISSION_RULE
                                         ↓
                    CB_AGENT_DOC_VPD_FILTER + DBMS_RLS
                                         ↓
                     permitted rows / sensitive-column NULL

6. 인수 조건

  • 토큰 발급 화면은 모든 KB_STAKEHOLDERS 사용자를 선택지로 제공하고, 목록에 업무 역할·채널을 표시한다.
  • 접힌 메뉴를 열지 않아도 상단에서 권한 설정과 토큰 발급 화면으로 이동할 수 있다.
  • 권한 설정에 설계사·지점장 예제 역할과 7개 원장 권한이 표시된다.
  • 지점장 역할은 정규화된 동일 채널 계약/고객 범위 규칙으로 등록된다.
  • 설계사 역할은 FC_ID = stakeholder user_id와 담당 고객 범위 규칙으로 등록된다.
  • 지정 7개 민감 컬럼은 원문 표시 예외가 없으면 NULL 처리하는 VPD column policy가 등록된다.
  • 토큰 없음·역할 없음·지원하지 않는 rule mapping은 VPD filter에서 1 = 0으로 fail-closed 된다.
  • 조건 코드와 정적 SQL 조건은 같은 접근 규칙 안에서 AND로 결합되며, 정적 SQL은 단일 안전 조건식만 저장할 수 있다.

7. 검증 계획

  1. Maven 단위/템플릿 테스트로 token subject 선택 및 새 rule type validation을 확인한다.
  2. SQLcl에서 지점장/설계사 token context를 설정하고 VPD predicate 및 row count를 비교한다.
  3. SQLcl에서 민감 컬럼이 NULL 처리되는지 확인한다.
  4. HTTPS 로그인 뒤 /permissions, /tokens의 상단 바로가기를 확인한다.

2026-07-07 배포 검증 결과

  • Maven 테스트 78건 통과.
  • HTTPS 인증 요청으로 /permissions, /tokens가 각각 200을 반환했다. 기존 /permissions의 잘못된 Thymeleaf fallback 표현식도 함께 수정했다.
  • CB_APP_USER bridge 13명, 지점장 역할 2명, 설계사 역할 5명이 동기화됐다.
  • POC_2에 행 VPD 7개와 민감 컬럼 NULL VPD policy 7개, 관련 CLS 함수 7개가 모두 VALID 상태로 확인됐다.

8. 리스크와 제한

  • CB_APP_USER는 업무 원장이 아니라 permission engine용 bridge다. 업무 identity의 원천은 반드시 KB_STAKEHOLDERS다.
  • 정적 SQL은 백오피스 검증과 VPD 함수의 이중 검증을 통과한 단일 조건식만 사용한다. 임의 SQL, 주석, 바인드, 서브쿼리, 다른 테이블 참조는 허용하지 않는다.
  • 지점장의 “집계만” 요구는 원시 행 조회를 완전히 차단하는 별도 집계 View/ORDS endpoint가 필요하다. 이번 예제는 채널 행 범위와 민감 컬럼 NULL 처리까지 구현하며, 집계 전용 endpoint는 후속 범위다.