# 함수 명세: `canAccess` (#617) > **상태**: Approved design · 구현 Pending · **분류**: 보안 핵심 ## 책임 local DDS END USER Context와 기존 `CB_*` 권한 테이블을 사용해 Object·동작·컬럼 그룹·행 속성에 대한 접근을 판단한다. 권한 변경을 사용자별 DDS DDL 재게시 없이 다음 보호 SQL부터 반영한다. ## 호출 형태 ```sql ADMIN.DDS_MCP_AUTHZ_PKG.can_access( ORA_END_USER_CONTEXT.username, 'ADMIN.CUSTOMER', 'SELECT', 'CONTACT', tenant_id, customer_type ) ``` 반환값은 `1`(허용) 또는 `0`(거부)이다. 실제 함수 인자와 행 속성은 Object별 Grant가 사용하는 컬럼에 맞춰 제한한다. ## 입력 신뢰 경계 | 입력 | 출처 | 신뢰 규칙 | |---|---|---| | END USER 이름 | `ORA_END_USER_CONTEXT.username` | Bearer 검증·Context attach 뒤 DB가 제공한 값만 사용 | | Object·동작·컬럼 그룹 | DATA GRANT DDL의 문자열 상수 | whitelist 검증 후 provisioning된 값만 사용 | | 테넌트·분류 등 행 속성 | 보호 Object의 현재 행 컬럼 | 함수 안에서 추가 SQL로 재조회하지 않음 | | 사용자 ID·권한 값 | `CB_DDS_END_USER_MAP`, `CB_*` | 클라이언트/MCP 인자에서 받지 않음 | ## 알고리즘 1. END USER 이름으로 `CB_DDS_END_USER_MAP`과 활성 `CB_APP_USER`를 찾는다. 2. 사용자 직접 역할과 활성 그룹의 역할을 합친다. 3. 대상 Object/동작/컬럼 그룹에 일치하는 `CB_PERMISSION`을 찾고 ALLOW와 DENY를 평가한다. 4. 권한 규칙과 전달된 행 속성으로 테넌트·부서·본인·상태·태그 범위를 평가한다. 5. 명시적 DENY, 매핑 없음, 비활성 사용자, 권한 없음, 검증 실패, 예외는 `0`을 반환한다. ## DDS DATA GRANT 배치 규칙 - Object/CRUD/컬럼 그룹마다 장기 Grant를 하나 이상 만든다. - `SELECT (column...)`과 `UPDATE (column...)`의 목록은 정적이며, 민감 컬럼마다 또는 승인 단위 컬럼 그룹마다 분리한다. - Grant들은 additive이다. 공통 Role에 `AS SELECT` 또는 넓은 컬럼 목록을 만들지 않는다. - predicate가 같은 보호 Object를 서브쿼리로 읽지 않게 하고, 권한 테이블만 읽는다. ## 실패와 성능 - 패키지는 `AUTHID DEFINER`로 작성하며 권한 테이블 조회 권한은 직접 부여한다. - 함수 오류는 로그에 안전한 식별자만 남기고 `0`을 반환한다. 오류를 MCP 응답에서 권한 존재 여부로 구분해 노출하지 않는다. - `DETERMINISTIC`·임의 result cache는 사용하지 않는다. 권한 테이블 변경이 즉시 반영되어야 한다. - 권한 테이블에는 END USER/user, role, Object, action, column group, active 상태를 시작 열로 하는 인덱스를 둔다. 대량 행 조회 대상은 `EXISTS`/조인 실행 계획을 별도 측정한다.