GRANT
GRANT
접근 권한(access privilege)을 정의하는 명령이에요. 두 가지 기본 변형이 있는데, 하나는 데이터베이스 객체에 대한 권한을 부여하는 것이고, 다른 하나는 역할(role)에 대한 멤버십을 부여하는 것이에요. 테이블·열·뷰 등 객체별로 특정 권한을 어떤 역할에 줄지, 또는 어떤 역할의 구성원이 되게 할지를 지정할 수 있죠.
출처: PostgreSQL 문서
본문
개요 (Synopsis)
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...]
| ALL TABLES IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { USAGE | SELECT | UPDATE }
[, ...] | ALL [ PRIVILEGES ] }
ON { SEQUENCE sequence_name [, ...]
| ALL SEQUENCES IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE database_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON DOMAIN domain_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN DATA WRAPPER fdw_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON FOREIGN SERVER server_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON { { FUNCTION | PROCEDURE | ROUTINE } routine_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...]
| ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] }
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE lang_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT loid [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { SET | ALTER SYSTEM } [, ... ] | ALL [ PRIVILEGES ] }
ON PARAMETER configuration_parameter [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT { USAGE | ALL [ PRIVILEGES ] }
ON TYPE type_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]
[ GRANTED BY role_specification ]
GRANT role_name [, ...] TO role_specification [, ...]
[ WITH { ADMIN | INHERIT | SET } { OPTION | TRUE | FALSE } ]
[ GRANTED BY role_specification ]
where role_specification can be:
[ GROUP ] role_name
| PUBLIC
| CURRENT_ROLE
| CURRENT_USER
| SESSION_USER
설명 (Description)
GRANT 명령에는 두 가지 기본 변형이 있어요. 하나는 데이터베이스 객체(테이블, 열, 뷰, 외부 테이블, 시퀀스, 데이터베이스, 외부 데이터 래퍼, 외부 서버, 함수, 프로시저, 절차 언어, 대형 객체, 구성 파라미터, 스키마, 테이블스페이스, 또는 타입)에 대한 권한을 부여하고, 다른 하나는 역할에 대한 멤버십을 부여해요. 이 변형들은 여러 면에서 비슷하지만, 서로 다를 만큼 구별되므로 따로 설명해요.
데이터베이스 객체에 대한 GRANT
이 GRANT 명령 변형은 데이터베이스 객체에 대한 특정 권한을 하나 이상의 역할에 부여해요. 이러한 권한은 이미 부여된 권한(있다면)에 추가돼요.
PUBLIC 키워드는 권한이 나중에 생성될 수 있는 역할을 포함해 모든 역할에 부여된다는 것을 나타내요. PUBLIC은 항상 모든 역할을 포함하는 암시적으로 정의된 그룹으로 생각할 수 있어요. 어떤 특정 역할은 직접 부여된 권한, 현재 구성원으로 있는 역할에 부여된 권한, PUBLIC에 부여된 권한의 합을 갖게 돼요.
WITH GRANT OPTION이 지정되면 권한을 받은 역할은 그 권한을 차례로 다른 사람에게 부여할 수 있어요. 부여 옵션이 없으면 받은 사람은 그렇게 할 수 없어요. 부여 옵션은 PUBLIC에 부여할 수 없어요.
GRANTED BY가 지정되면 지정된 부여자(grantor)는 현재 사용자여야 해요. 이 절은 현재 SQL 호환성을 위해 이 형태로 존재해요.
객체 소유자(보통 그것을 만든 사용자)에게 권한을 부여할 필요는 없어요. 소유자는 기본적으로 모든 권한을 갖기 때문이에요. (다만 소유자는 안전을 위해 자신의 일부 권한을 박탈하도록 선택할 수도 있어요.)
객체를 삭제하거나 그 정의를 어떤 식으로든 변경할 권리는 부여 가능한 권한(privilege)으로 취급되지 않아요. 이는 소유자에게 내재되어 있고, 부여하거나 박탈할 수 없어요. (다만 객체를 소유한 역할에 대한 멤버십을 부여하거나 박탈함으로써 비슷한 효과를 얻을 수 있어요. 아래 참고). 소유자는 객체에 대한 모든 부여 옵션도 암시적으로 가져요.
가능한 권한은 다음과 같아요.
SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER,CREATE,CONNECT,TEMPORARY,EXECUTE,USAGE,SET,ALTER SYSTEM,MAINTAIN— 5.8절에서 정의한 특정 유형의 권한이에요.
TEMP — TEMPORARY의 대체 철자예요.
ALL PRIVILEGES — 객체의 유형에 사용 가능한 모든 권한을 부여해요. PRIVILEGES 키워드는 PostgreSQL에서는 선택사항이지만, 엄격한 SQL에서는 필수예요.
FUNCTION 문법은 일반 함수, 집계 함수, 윈도우 함수에는 동작하지만 프로시저에는 동작하지 않아요. 프로시저에는 PROCEDURE를 사용하세요. 또는 정확한 유형에 관계없이 함수, 집계 함수, 윈도우 함수, 프로시저를 가리키려면 ROUTINE을 사용하세요.
하나 이상의 스키마 안에 있는 같은 유형의 모든 객체에 권한을 부여하는 옵션도 있어요. 이 기능은 현재 테이블, 시퀀스, 함수, 프로시저에만 지원돼요. ALL TABLES는 특정 객체 GRANT 명령처럼 뷰와 외부 테이블에도 영향을 미쳐요. ALL FUNCTIONS도 특정 객체 GRANT 명령처럼 집계·윈도우 함수에는 영향을 미치지만 프로시저에는 영향을 미치지 않아요. 프로시저를 포함하려면 ALL ROUTINES을 사용하세요.
역할에 대한 GRANT
이 GRANT 명령 변형은 하나 이상의 다른 역할에 어떤 역할의 멤버십을 부여하고, SET, INHERIT, ADMIN 멤버십 옵션을 수정해요. 자세한 내용은 21.3절을 참고하세요. 역할 멤버십이 중요한 이유는 잠재적으로 각 구성원이 역할에 부여된 권한에 접근할 수 있게 하고, 잠재적으로 역할 자체에 변경을 가할 수 있게 하기 때문이에요. 단, 실제로 부여되는 권한은 부여와 연관된 옵션에 따라 달라져요. 기존 멤버십의 옵션을 수정하려면 갱신된 옵션 값으로 멤버십을 지정하면 돼요.
아래 설명하는 각 옵션은 TRUE 또는 FALSE로 설정할 수 있어요. OPTION 키워드는 TRUE의 동의어로 받아들여지므로, WITH ADMIN OPTION은 WITH ADMIN TRUE의 동의어예요. 기존 멤버십을 변경할 때 옵션을 생략하면 현재 값이 유지돼요.
ADMIN 옵션은 구성원이 그 역할의 멤버십을 차례로 다른 사람에게 부여하고, 역할 멤버십을 박탈하는 것도 허용해요. 관리자 옵션이 없으면 일반 사용자는 그렇게 할 수 없어요. 역할은 자기 자신에 대해 WITH ADMIN OPTION을 보유한 것으로 간주되지 않아요. 데이터베이스 슈퍼유저는 누구에게나 어떤 역할의 멤버십을 부여하거나 박탈할 수 있어요. 이 옵션은 기본값이 FALSE예요.
INHERIT 옵션은 새 멤버십의 상속 상태를 제어해요. 상속에 대한 자세한 내용은 21.3절을 참고하세요. TRUE로 설정하면 새 구성원이 부여된 역할로부터 상속해요. FALSE로 설정하면 새 구성원은 상속하지 않아요. 새 역할 멤버십을 만들 때 지정하지 않으면, 이 값은 새 구성원의 상속 속성으로 기본 설정돼요.
SET 옵션을 TRUE로 설정하면 구성원이 SET ROLE 명령을 사용해 부여된 역할로 변경할 수 있어요. 어떤 역할이 다른 역할의 간접 구성원이라면, 각각 SET TRUE인 부여 체인이 있을 때만 SET ROLE로 그 역할로 변경할 수 있어요. 이 옵션은 기본값이 TRUE예요.
다른 역할이 소유한 객체를 만들거나 기존 객체의 소유권을 다른 역할에 주려면, 그 역할로 SET ROLE할 수 있는 능력이 있어야 해요. 그렇지 않으면 ALTER ... OWNER TO나 CREATE DATABASE ... OWNER 같은 명령이 실패해요. 하지만 역할의 권한을 상속받지만 그 역할로 SET ROLE할 수 없는 사용자는, 그 역할이 소유한 기존 객체를 조작해 역할에 대한 완전한 접근을 얻을 수 있을지도 몰라요(예: 기존 함수를 재정의해 트로이 목마 역할을 하게 할 수 있어요). 따라서 역할의 권한을 상속받아야 하지만 SET ROLE로 접근하면 안 된다면, 그 역할은 어떤 SQL 객체도 소유하지 않아야 해요.
GRANTED BY가 지정되면 그 부여가 지정된 역할에 의해 이루어진 것으로 기록돼요. 사용자는 그 역할의 권한을 보유한 경우에만 다른 역할에게 부여를 귀속시킬 수 있어요. 부여자로 기록된 역할은 부트스트랩 슈퍼유저가 아니라면 대상 역할에 ADMIN OPTION을 가져야 해요. 부여가 부트스트랩 슈퍼유저가 아닌 다른 부여자가 있는 것으로 기록되면, 그 부여는 부여자가 역할에 ADMIN OPTION을 계속 보유하는 것에 의존해요. 따라서 ADMIN OPTION이 박탈되면 의존하는 부여도 같이 박탈해야 해요.
권한의 경우와 달리, 역할 멤버십은 PUBLIC에 부여할 수 없어요. 또한 이 명령 형태는 role_specification에서 잡음 단어(noise word) GROUP을 허용하지 않는다는 점도 참고하세요.
참고 (Notes)
REVOKE 명령은 접근 권한을 박탈하는 데 사용돼요.
PostgreSQL 8.1부터 사용자와 그룹의 개념이 role이라는 단일 종류의 엔터티로 통합됐어요. 따라서 권한을 받는 사람이 사용자인지 그룹인지 식별하기 위해 GROUP 키워드를 사용할 필요가 더 이상 없어요. GROUP은 여전히 명령에서 허용되지만 잡음 단어예요.
사용자는 특정 열 또는 그 전체 테이블에 대한 해당 권한을 보유하면 열에 대해 SELECT, INSERT 등을 수행할 수 있어요. 테이블 수준에서 권한을 부여한 다음 한 열에 대해 박탈해도 원하는 대로 동작하지 않아요. 테이블 수준 부여는 열 수준 작업의 영향을 받지 않기 때문이에요.
객체의 비소유자가 객체에 권한을 GRANT하려고 하면, 사용자가 객체에 아무런 권한도 없을 때 명령은 완전히 실패해요. 어떤 권한이라도 있으면 명령은 진행되지만, 사용자가 부여 옵션을 가진 권한만 부여해요. GRANT ALL PRIVILEGES 형태는 부여 옵션을 보유하지 않으면 경고 메시지를 발행하고, 다른 형태는 명령에 구체적으로 이름이 지정된 권한 중 어떤 것에 대한 부여 옵션을 보유하지 않으면 경고를 발행해요. (원칙적으로 이 진술은 객체 소유자에게도 적용되지만, 소유자는 항상 모든 부여 옵션을 보유한 것으로 취급되므로 이런 경우는 발생할 수 없어요.)
데이터베이스 슈퍼유저는 객체 권한 설정과 관계없이 모든 객체에 접근할 수 있다는 점을 알아야 해요. 이것은 Unix 시스템에서 root의 권한과 비슷해요. root와 마찬가지로, 꼭 필요할 때 외에는 슈퍼유저로 작업하는 것은 좋지 않아요.
슈퍼유저가 GRANT나 REVOKE 명령을 발행하면, 그 명령은 해당 객체의 소유자가 발행한 것처럼 수행돼요. 특히 그런 명령으로 부여된 권한은 객체 소유자가 부여한 것처럼 나타나요. (역할 멤버십의 경우 멤버십은 부트스트랩 슈퍼유저가 부여한 것처럼 나타나요.)
GRANT와 REVOKE는 해당 객체의 소유자가 아니지만 객체를 소유한 역할의 구성원이거나, 객체에 WITH GRANT OPTION 권한을 보유한 역할의 구성원인 역할에 의해서도 수행될 수 있어요. 이 경우 권한은 실제로 객체를 소유하거나 WITH GRANT OPTION 권한을 보유한 역할이 부여한 것으로 기록돼요. 예를 들어 테이블 t1을 역할 g1이 소유하고 있고 역할 u1이 그 구성원이라면, u1은 t1에 대한 권한을 u2에게 부여할 수 있지만, 그 권한은 g1이 직접 부여한 것처럼 나타나요. 역할 g1의 다른 구성원은 나중에 그 권한을 박탈할 수 있어요.
GRANT를 실행하는 역할이 여러 역할 멤버십 경로를 통해 필요한 권한을 간접적으로 보유하고 있다면, 어떤 포함 역할이 부여를 한 것으로 기록될지는 지정되지 않아요. 그런 경우에는 SET ROLE을 사용해 GRANT를 수행하려는 특정 역할이 되는 것이 가장 좋은 방법이에요.
테이블에 권한을 부여해도 테이블이 사용하는 시퀀스( SERIAL 열에 연결된 시퀀스 포함)에 대한 권한까지 자동으로 확장되지는 않아요. 시퀀스에 대한 권한은 따로 설정해야 해요.
특정 권한 유형과 객체의 권한을 조사하는 방법에 대한 자세한 내용은 5.8절을 참고하세요.
예제 (Examples)
테이블 films에 대해 모든 사용자에게 insert 권한을 부여하려면:
GRANT INSERT ON films TO PUBLIC;
뷰 kinds에 대해 사용자 manuel에게 사용 가능한 모든 권한을 부여하려면:
GRANT ALL PRIVILEGES ON kinds TO manuel;
위 명령은 슈퍼유저나 kinds의 소유자가 실행하면 실제로 모든 권한을 부여하지만, 다른 사람이 실행하면 그 사람이 부여 옵션을 가진 권한만 부여한다는 점을 참고하세요.
역할 admins의 멤버십을 사용자 joe에게 부여하려면:
GRANT admins TO joe;
호환성 (Compatibility)
SQL 표준에 따르면 ALL PRIVILEGES의 PRIVILEGES 키워드는 필수예요. SQL 표준은 명령당 둘 이상의 객체에 대한 권한 설정을 지원하지 않아요.
PostgreSQL은 객체 소유자가 자신의 일반 권한을 박탈하는 것을 허용해요. 예를 들어 테이블 소유자는 자신의 INSERT, UPDATE, DELETE, TRUNCATE 권한을 박탈해 테이블을 자신에게 읽기 전용으로 만들 수 있어요. SQL 표준에 따르면 이것은 불가능해요. 그 이유는 PostgreSQL이 소유자의 권한을 소유자가 자신에게 부여한 것으로 취급하기 때문이에요. 따라서 그 권한도 박탈할 수 있는 것이죠. SQL 표준에서 소유자의 권한은 가정된 엔터티 “_SYSTEM”이 부여한 것이에요. _SYSTEM이 아니므로 소유자는 이 권한을 박탈할 수 없어요.
SQL 표준에 따르면 부여 옵션은 PUBLIC에 부여할 수 있어요. PostgreSQL은 부여 옵션을 역할에만 부여하는 것을 지원해요.
SQL 표준은 GRANTED BY 옵션이 CURRENT_USER 또는 CURRENT_ROLE만 지정하도록 허용해요. 다른 변형은 PostgreSQL 확장이에요.
SQL 표준은 다른 종류의 객체(문자 셋, 콜레이션, 번역)에 대한 USAGE 권한을 규정해요.
SQL 표준에서 시퀀스는 USAGE 권한만 가지며, 이는 PostgreSQL의 nextval 함수에 해당하는 NEXT VALUE FOR 표현식의 사용을 제어해요. 시퀀스의 SELECT와 UPDATE 권한은 PostgreSQL 확장이에요. 시퀀스 USAGE 권한을 currval 함수에 적용하는 것도 PostgreSQL 확장이에요(그 함수 자체도 마찬가지로 확장이에요).
데이터베이스, 테이블스페이스, 스키마, 언어, 구성 파라미터에 대한 권한은 PostgreSQL 확장이에요.
더 알아보기 (Learn more)
부여한 권한을 되돌리는 방법은 REVOKE 문서를, 역할과 권한의 개념에 대한 자세한 내용은 “Privileges” 절과 “Database Roles” 절을 함께 보면 좋아요.