시스템 권한과 객체 권한
시스템 권한과 객체 권한의 부여와 재부여(WITH ADMIN OPTION, WITH GRANT OPTION), 회수할 때 연쇄 회수가 일어나는지의 차이, 부여 현황 조회
#핵심 요약
시스템 권한(CREATE SESSION, CREATE TABLE 등)은 WITH ADMIN OPTION으로, 객체 권한(SELECT ON emp 등)은 WITH GRANT OPTION으로 받으면 다른 사용자에게 다시 줄 수 있음
회수 동작이 다름
객체 권한은 A가 B에게서 회수하면 B가 C에게 준 권한도 함께 회수되지만, 시스템 권한은 C에게 남음
부여 현황은 DBA_SYS_PRIVS(시스템 권한), DBA_TAB_PRIVS(객체 권한)로 봄
#개념과 동작 원리
| 구분 | 재부여 옵션 | A가 B에게서 회수할 때 B가 C에게 준 권한 |
|---|---|---|
| 시스템 권한 | WITH ADMIN OPTION |
남아 있음 |
| 객체 권한 | WITH GRANT OPTION |
함께 회수됨 |
공식 문서 확인 내용(Oracle Database SQL Language Reference 19c E96310-37, REVOKE, 2026-10-27):
사용자에게서 객체 권한을 회수하면, 그 사용자가 다른 사용자나 롤에 그 권한을 줬을 경우 그쪽에서도 회수됨
그 사용자의 스키마에 이 권한을 쓰는 프로시저, 함수, 패키지가 있으면 더 이상 실행할 수 없고, 이 객체에 대한 뷰는 무효화됨
사용자에게서 시스템 권한을 회수하면 그 사용자의 권한 영역에서 즉시 빠짐
같은 문서의 시스템 권한 설명에는 다른 사용자에게서도 회수된다는 내용이 없음
실습의 "C에게 남는다"는 이 차이와 맞음
시스템 권한을 회수하려면 그 권한을 ADMIN OPTION으로 받았거나 GRANT ANY PRIVILEGE 권한이 있어야 함
#필수 명령어 또는 SQL
#시스템 권한 목록 조회
SELECT name
FROM system_privilege_map
WHERE name LIKE '%ANY%';결과 해석:
실습에서는 FROM 줄 끝에 세미콜론이 있어 WHERE 절이 실행되지 않는 형태였음
위 블록은 ANY가 들어간 권한만 보려는 의도에 맞게 세미콜론 위치를 고쳤음
#시스템 권한 부여 (재부여 가능)
GRANT create session, create table TO app_mgr WITH ADMIN OPTION;결과 해석: 개별 실행 출력은 기재 없음
#객체 권한 부여 (재부여 가능)
GRANT select ON emp TO app_mgr2;
GRANT select ON emp TO app_mgr2 WITH GRANT OPTION;결과 해석: 개별 실행 출력은 기재 없음
#공용 동의어
CREATE PUBLIC SYNONYM emp FOR hr.employees;결과 해석:
실습의 객체 권한 실습에 함께 있던 명령임
모든 사용자가 emp라는 이름으로 hr.employees를 가리키게 함
동의어가 권한을 주지는 않는다는 점은 기재 없음
동의어는 시퀀스와 동의어에서 다룸
#부여 현황 조회
SELECT privilege, admin_option
FROM dba_sys_privs
WHERE grantee IN ('APP_MGR', 'APP_MGR2', 'APP_MGR3');
SELECT owner, table_name, privilege, grantable
FROM dba_tab_privs
WHERE grantee IN ('APP_MGR', 'APP_MGR2', 'APP_MGR3');결과 해석:
ADMIN_OPTION, GRANTABLE이 YES면 재부여할 수 있는 권한임
#새 사용자에게 기본 권한 주기 (연습)
시스템 권한은 CREATE TABLE, CREATE VIEW, DROP TABLE처럼 어떤 종류의 작업을 할 수 있는 권한이고, 객체 권한은 특정 테이블의 데이터를 조회하거나 입력, 수정, 삭제하는 권한임
SELECT * FROM session_privs; -- 내가 가진 시스템 권한
CREATE USER <USERNAME> IDENTIFIED BY <PASSWORD>;
GRANT CREATE SESSION TO <USERNAME>; -- 접속 권한
GRANT CREATE TABLE TO <USERNAME>; -- 테이블 생성 시스템 권한
GRANT SELECT ON <OWNER>.emp TO <USERNAME>; -- 객체 권한(ALL도 가능)
GRANT CONNECT, RESOURCE TO <USERNAME>; -- 기본 Role
REVOKE DBA FROM <USERNAME>; -- 준 Role 회수결과 해석:
연습 문제: 새 사용자를 만들어 접속과 CREATE TABLE 권한을 주고, 다른 사용자의 emp, dept에 SELECT, INSERT, UPDATE, DELETE 권한을 준 뒤, 새 사용자에서 emp라는 이름의 동의어로 원래 테이블을 조회함
실습 기록에서 CONNECT, RESOURCE를 받은 사용자의 SESSION_PRIVS에는 CREATE SESSION, CREATE TABLE, CREATE PROCEDURE, CREATE TRIGGER, CREATE SEQUENCE 등 10개가 보였음
#PDB를 옮기거나 복제한 뒤 권한 비교
| PDB를 만드는 방법 | 계정과 권한이 따라오는가 |
|---|---|
FROM PDB$SEED(시드 복제) |
아무것도 안 옴 빈 PDB라 계정과 권한을 직접 만들어야 함 |
FROM <다른 PDB>(PDB 클론) |
계정, 객체, 권한이 통째로 따라옴 |
| 언플러그와 플러그 | 통째로 따라옴 |
| Data Pump로 스키마만 이관 | 일부만 옴 |
스키마만 옮긴 경우처럼 권한이 빠졌을 수 있으면, 소스 쪽을 가리키는 DB 링크를 만들고 양쪽 DBA_SYS_PRIVS를 MINUS로 비교함
SELECT * FROM session_privs; -- 현재 세션이 가진 권한
-- 소스에는 있는데 대상에는 없는 권한
SELECT grantee, privilege, admin_option FROM dba_sys_privs@<DB_LINK>
WHERE grantee IN ('<USER1>', '<USER2>')
MINUS
SELECT grantee, privilege, admin_option FROM dba_sys_privs
WHERE grantee IN ('<USER1>', '<USER2>');
-- 대상에는 있는데 소스에는 없는 권한
SELECT grantee, privilege, admin_option FROM dba_sys_privs
WHERE grantee IN ('<USER1>', '<USER2>')
MINUS
SELECT grantee, privilege, admin_option FROM dba_sys_privs@<DB_LINK>
WHERE grantee IN ('<USER1>', '<USER2>');결과 해석: 첫 조회에 나온 행은 대상에서 다시 부여해야 할 권한, 두 번째 조회에 나온 행은 대상에만 있는 권한임
DB 링크 만드는 법은 데이터베이스 링크에 있음
#구문과 옵션 설명
| 구문 | 의미 | 바꿀 입력값 |
|---|---|---|
GRANT <시스템 권한> TO <사용자> WITH ADMIN OPTION |
시스템 권한 부여와 재부여 허용 | 권한, 사용자 |
GRANT <객체 권한> ON <객체> TO <사용자> WITH GRANT OPTION |
객체 권한 부여와 재부여 허용 | 권한, 객체, 사용자 |
REVOKE ... FROM <사용자> |
회수 연쇄 회수 여부는 위 표 |
#사용 조건과 주의사항
WITH ADMIN OPTION과 ANY 권한은 범위가 넓음
운영 환경에서는 필요한 최소 권한만 줌