
이 글은 Oracle의 테이블 객체 권한(Table Object Privileges)을 실무 관점에서 깊이 있게 정리합니다. 권한의 의미와 부작용, 안전한 부여/회수 패턴, 그리고 DBA_TAB_PRIVS·ALL_TAB_PRIVS·USER_TAB_PRIVS 계열 뷰를 활용한 점검 쿼리까지 한 번에 확인할 수 있습니다. Oracle 공식 문서를 교차 확인하여 최신 동작을 반영했습니다.
1) 왜 지금 TABLE_PRIVILEGES를 점검해야 할까?
- 보안·감사 요구 강화: 최소권한 원칙을 위반한 광범위 GRANT는 곧바로 리스크로 이어집니다.
- 운영 안정성: 불필요한
WITH GRANT OPTION은 권한 전염(chain grant)을 유발하여 회수(REVOKE)를 복잡하게 만듭니다. - 버전 변화: 12c부터 도입된
READ권한은SELECT와 행 잠금 동작이 달라 미묘한 트러블을 줄여줍니다.
2) Oracle 테이블 객체 권한의 전체 그림
Oracle의 객체 권한은 테이블·뷰 등 스키마 오브젝트 단위로 부여되는 권한입니다. 테이블에 적용되는 대표 권한은 다음과 같습니다.
| 권한 | 설명 (핵심 동작) | 비고/주의 |
|---|---|---|
SELECT |
데이터 조회 허용 (SELECT ... FOR UPDATE로 행 잠금 가능) |
광범위 부여 시 데이터 유출 위험 |
READ |
읽기 전용 조회, SELECT ... FOR UPDATE처럼 행 잠금을 허용하지 않음 |
12c+에서 보안 친화적 대안으로 권장 |
INSERT |
행 추가 허용 | 대량 적재 작업 시 주의 |
UPDATE |
행 변경 허용 (열 단위 제한 가능) | 민감 컬럼은 컬럼 단위 GRANT 권장 |
DELETE |
행 삭제 허용 | 외래키/감사 정책과 충돌 가능 |
REFERENCES |
외래키 참조 허용 (컬럼 단위 가능) | 스키마 설계 시 필수 권한 |
ALTER |
테이블 구조 변경 허용 | 운영 환경에서는 극히 제한 |
INDEX |
다른 사용자 테이블에 인덱스 생성 허용 | 성능·스토리지 영향 고려 |
권한 부여는 GRANT 문으로 수행하며, 사용자·롤·PUBLIC을 지정할 수 있습니다. (운영에서는 PUBLIC 대상 부여 지양)
3) 점검에 쓰는 핵심 사전 뷰(Grants Inventory)
DBA_TAB_PRIVS: 데이터베이스 전체 객체 권한 그랜트 현황ALL_TAB_PRIVS: 현재 세션 관점에서 접근 가능한 객체 권한USER_TAB_PRIVS/USER_TAB_PRIVS_MADE: 내게 부여/내가 부여한 권한 추적
각 뷰의 정의는 다음 공식 문서를 참고하세요.
| 뷰 | 설명 | 주요 컬럼(예) | 활용 포인트 |
|---|---|---|---|
DBA_TAB_PRIVS |
DB 전체 객체 권한 | GRANTEE, OWNER, TABLE_NAME, PRIVILEGE, GRANTABLE | 광범위 권한 스캔, 보안 감리 |
ALL_TAB_PRIVS |
세션이 볼 수 있는 권한 | 위와 유사 | 문제 재현/개발자 셀프 점검 |
USER_TAB_PRIVS |
내게 관련된 권한(소유/부여/수혜) | 위와 유사 | 개인 스키마 방어 점검 |
USER_TAB_PRIVS_MADE |
내가 부여한 권한 목록 | GRANTEE, TABLE_NAME, PRIVILEGE, GRANTABLE | 권한 회수 플랜 작성 |
4) 안전한 GRANT 패턴 (실무 레시피)
4.1 최소권한 + 롤 기반 부여
-- 1) 역할(ROLE) 정의
CREATE ROLE r_sales_ro;
-- 2) 필요한 읽기 권한만 롤에 부여 (READ 권한 사용 예)
GRANT READ ON sales.order TO r_sales_ro;
-- 3) 사용자에게 롤 부여
GRANT r_sales_ro TO app_user1;
포인트: 객체별 직접 부여 대신 롤을 매개로 하면 회수와 감사를 단순화할 수 있습니다. READ는 SELECT 대비 행 잠금 제한으로 안전성이 높습니다.
4.2 컬럼 단위 UPDATE/REFERENCES로 민감 컬럼 격리
-- 주소/연락처 컬럼만 수정 허용
GRANT UPDATE (address, phone) ON hr.employees TO helpdesk;
-- 급여 컬럼은 별도 롤/담당자에게만
-- GRANT UPDATE (salary) ON hr.employees TO payroll_role;
4.3 외래키 설계를 위한 REFERENCES
-- 다른 스키마의 키 컬럼을 참조하려면 REFERENCES 필요
GRANT REFERENCES (customer_id) ON crm.customers TO sales_schema;
4.4 WITH GRANT OPTION은 예외적으로만
-- helpdesk가 제3자에게 동일 권한을 재부여할 수 있게 함 (권장 X)
GRANT READ ON hr.tickets TO helpdesk WITH GRANT OPTION;
권한 전파 사슬이 길어지면 회수 난도가 급증합니다. 기본적으로 지양하세요.
5) REVOKE 전략: 전염 차단과 깨끗한 회수
-- 직접 부여한 권한 회수
REVOKE READ, SELECT ON hr.tickets FROM helpdesk;
-- 롤 해제
REVOKE r_sales_ro FROM app_user1;
팁: 직접 부여한 권한인지, 롤을 통해 들어온 권한인지 먼저 식별하세요. GRANTABLE='YES'가 다단계 전파의 흔적일 수 있습니다.
6) “지금” 우리 DB는 안전한가? — 즉시 실행 점검 쿼리
6.1 위험 신호: PUBLIC/광역 권한
-- PUBLIC 대상 SELECT/READ/INSERT/UPDATE/DELETE 탐지
SELECT owner, table_name, privilege
FROM dba_tab_privs
WHERE grantee = 'PUBLIC'
AND privilege IN ('SELECT','READ','INSERT','UPDATE','DELETE')
ORDER BY owner, table_name;
6.2 권한 전염 가능성 추적
-- WITH GRANT OPTION 흔적
SELECT grantee, owner, table_name, privilege
FROM dba_tab_privs
WHERE grantable = 'YES'
ORDER BY owner, table_name;
6.3 내가(우리 팀이) 부여한 권한 목록
SELECT grantee, table_name, privilege, grantable
FROM user_tab_privs_made
ORDER BY grantee, table_name;
6.4 개발자 셀프 점검(내가 가진 권한만 보기)
SELECT owner, table_name, privilege
FROM user_tab_privs
ORDER BY owner, table_name, privilege;
위 뷰들의 의미와 컬럼 사양은 공식 레퍼런스를 참고하세요.
7) 흔한 오해와 장애 시나리오
- SELECT ANY TABLE만 있으면 된다? 이는 시스템 권한으로, 거의 모든 스키마 테이블을 읽게 합니다. 최소권한 원칙에 어긋나며, 객체 권한 설계와 목적이 다릅니다. 매우 제한적으로 사용하세요.
- SELECT와 READ는 같다? READ는 행 잠금이 불가하여 동시성 영향과 보안 측면에서 더 보수적입니다. 레거시 코드에
FOR UPDATE가 있다면 READ만으로는 실패할 수 있습니다. - 권한은 직접 사용자에게만? 실무에서는 “롤 → 사용자” 경유가 표준입니다. 회수·감사·권한 모델 표준화를 동시에 만족합니다.
8) 운영 체크리스트 (바로 적용)
- ① 인벤토리 작성:
DBA_TAB_PRIVS전수 스캔 → PUBLIC/GRANTABLE 우선 정리 - ② 롤 리팩터링: 동일 역할군을 묶어 역할로 표준화, 개인 직접 GRANT 제거
- ③ 민감 컬럼 분리: UPDATE/REFERENCES는 컬럼 단위로 최소화
- ④ READ 우선: 단순 조회는 READ로 시작, 필요 시에만 SELECT 부여
- ⑤ 권한 전염 차단:
WITH GRANT OPTION금지, 기존 흔적은 REVOKE 플랜 수립 - ⑥ 정기 감리 자동화: 위 점검 쿼리를 스케줄링하여 드리프트 감시
9) 꼭 알아둘 문법 스니펫
-- GRANT: 사용자/롤/공용 대상
GRANT READ, SELECT ON hr.employees TO r_hr_reader, dev_user;
-- 컬럼 단위 UPDATE
GRANT UPDATE (email, phone) ON hr.employees TO helpdesk;
-- REFERENCES (외래키 참조)
GRANT REFERENCES (customer_id) ON crm.customers TO sales_schema;
-- REVOKE
REVOKE SELECT, READ ON hr.employees FROM dev_user;
-- 권장하지 않음: WITH GRANT OPTION
GRANT SELECT ON hr.employees TO temp_op WITH GRANT OPTION;
GRANT/REVOKE 구문과 제약사항은 SQL 언어 참조를 확인하세요.
10) 자주 묻는 질문(FAQ)
Q1. 뷰(View)에도 동일한 권한을 쓰나요?
A. 네. SELECT/READ/INSERT/UPDATE/DELETE 등이 유사하게 적용되지만, 실제 DML 가능 여부는 뷰의 갱신 가능성에 좌우됩니다. (권한 개념은 동일)
Q2. 오브젝트-타입(OBJECT TABLE)에도 같은가요?
A. 객체 테이블은 관계형 테이블과 동일하게 READ/SELECT/INSERT/UPDATE/DELETE 권한 모델을 따릅니다.
출처(Official & Authoritative)
- Oracle Database Security Guide — Object Privileges(23c): 테이블 권한의 분류와 READ/SELECT 차이.
- Oracle SQL Language Reference —
GRANT문 (23c): 권한 부여 구문과PUBLIC주의. - Oracle Reference —
DBA_TAB_PRIVS/ALL_TAB_PRIVS/USER_TAB_PRIVS/USER_TAB_PRIVS_MADE(19c~21c): 권한 인벤토리 뷰 정의. - Oracle Docs — Access Privileges on Object Tables(21c): 객체 테이블 권한 모델.
'Database > Oracle' 카테고리의 다른 글
| [ORACLE] ALL_OUTLINES 완전 가이드 : 개념 활용 예제 SPM 전환 전략 (0) | 2025.10.10 |
|---|---|
| [ORACLE] ALL_HISTOGRAMS 완전 정복 : 옵티마이저를 움직이는 히스토그램 이해와 실전 튜닝 (0) | 2025.10.10 |
| [ORACLE] SESSION_ROLES 완벽 가이드: 현재 세션에 활성화된 역할을 정확히 읽고, 점검하고, 통제하는 방법 (0) | 2025.10.09 |
| [ORACLE] SESSION_PRIVS 뷰 완벽 해설 : 현재 세션이 가진 권한 확인 방법 (0) | 2025.10.09 |
| [ORACLE] ROLE_TAB_PRIVS 뷰 완벽 해설 – 사용자별 테이블 권한 확인 가이드 (0) | 2025.10.09 |