Files
vpd-permission-poc/docs/assets/agent-ords-security-vpd-where-flow.svg

74 lines
4.4 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1280" height="760" viewBox="0 0 1280 760" role="img" aria-labelledby="title desc">
<title id="title">VPD EXISTS 권한 조건 적용 흐름</title>
<desc id="desc">ORDS 조회 SQL에 VPD가 p_object 기준 EXISTS 권한 조건을 추가해 VIEW/TABLE 접근과 행 접근을 판단하는 흐름.</desc>
<rect width="1280" height="760" fill="#f8fafc"/>
<defs>
<marker id="arrow" markerWidth="9" markerHeight="9" refX="7.5" refY="4.5" orient="auto">
<path d="M 0 0 L 9 4.5 L 0 9 z" fill="#475569"/>
</marker>
<style>
.h1 { font-family: Arial, Helvetica, sans-serif; font-size: 36px; font-weight: 700; fill: #0f172a; }
.sub { font-family: Arial, Helvetica, sans-serif; font-size: 20px; fill: #475569; }
.panel { fill: #ffffff; stroke: #cbd5e1; stroke-width: 2; }
.blue { fill: #eff6ff; stroke: #2563eb; stroke-width: 2; }
.purple { fill: #f5f3ff; stroke: #7c3aed; stroke-width: 2; }
.green { fill: #ecfdf5; stroke: #059669; stroke-width: 2; }
.warn { fill: #fff7ed; stroke: #ea580c; stroke-width: 2; }
.title { font-family: Arial, Helvetica, sans-serif; font-size: 23px; font-weight: 700; fill: #0f172a; }
.text { font-family: Arial, Helvetica, sans-serif; font-size: 18px; fill: #334155; }
.mono { font-family: Menlo, Consolas, monospace; font-size: 17px; fill: #0f172a; }
.mono-small { font-family: Menlo, Consolas, monospace; font-size: 15px; fill: #0f172a; }
.arrow { stroke: #475569; stroke-width: 2.2; marker-end: url(#arrow); fill: none; }
</style>
</defs>
<text x="48" y="58" class="h1">VPD: EXISTS로 권한 테이블 확인</text>
<text x="48" y="94" class="sub">p_object는 현재 조회 대상, SYS_CONTEXT는 요청자 식별값, EXISTS는 실제 권한 판단</text>
<rect x="48" y="138" width="360" height="276" rx="10" class="blue"/>
<text x="76" y="184" class="title">1. ORDS가 실행한 SQL</text>
<text x="76" y="228" class="text">권한 조건 없음</text>
<text x="76" y="278" class="mono">SELECT doc_id, title</text>
<text x="76" y="306" class="mono">FROM app.v_search_documents</text>
<text x="76" y="334" class="mono">WHERE contains_text = :q;</text>
<line x1="408" y1="276" x2="468" y2="276" class="arrow"/>
<rect x="480" y="138" width="360" height="276" rx="10" class="purple"/>
<text x="508" y="184" class="title">2. VPD 정책 함수</text>
<text x="508" y="226" class="text">조회 대상과 요청자 확인</text>
<text x="508" y="264" class="mono">p_object = 현재 VIEW/TABLE</text>
<text x="508" y="292" class="mono">USER_ID = SYS_CONTEXT(...)</text>
<text x="508" y="344" class="mono-small">RETURN EXISTS (...)</text>
<text x="508" y="370" class="mono-small">target_name = p_object</text>
<line x1="840" y1="276" x2="900" y2="276" class="arrow"/>
<rect x="912" y="138" width="360" height="276" rx="10" class="green"/>
<text x="940" y="184" class="title">3. DB가 합쳐서 적용</text>
<text x="940" y="226" class="text">조회 SQL 뒤에 권한 조건 추가</text>
<text x="940" y="276" class="mono-small">WHERE contains_text = :q</text>
<text x="940" y="304" class="mono-small">AND EXISTS (</text>
<text x="940" y="332" class="mono-small"> permission.target = p_object</text>
<text x="940" y="360" class="mono-small"> row rule matched)</text>
<rect x="74" y="486" width="360" height="118" rx="10" class="panel"/>
<text x="106" y="530" class="title">VIEW/TABLE 접근 판단</text>
<text x="106" y="568" class="text">target_name = p_object</text>
<text x="106" y="594" class="text">없으면 결과 0건</text>
<rect x="460" y="486" width="360" height="118" rx="10" class="panel"/>
<text x="492" y="530" class="title">행 접근 판단</text>
<text x="492" y="568" class="text">permission_rule이 행 컬럼과 일치</text>
<text x="492" y="594" class="text">조건에 맞는 행만 반환</text>
<rect x="846" y="486" width="360" height="118" rx="10" class="warn"/>
<text x="878" y="530" class="title">권한 매핑 없음</text>
<text x="878" y="568" class="text">EXISTS가 false</text>
<text x="878" y="594" class="text">해당 행은 제외</text>
<rect x="190" y="650" width="900" height="58" rx="10" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="236" y="686" class="title">요점: p_object는 조회 대상, SYS_CONTEXT는 요청자, EXISTS가 권한 판단</text>
</svg>