PostgreSQL | 역할(사용자) ROLE 생성 | 역할 권한 삭제 (REVOKE)

GRANT 명령을 사용하여 역할에 추가된 권한은 REVOKE 명령으로 제거 할 수 있다. 여기에서는 REVOKE 명령을 사용하여 권한을 삭제하는 방법에 대해 설명하겠다.

REVOKE 명령을 사용하여 권한 제거

REVOKE 명령을 사용하여 역할에 추가된 권한을 제거 할 수 있다. 목적에 따라 여러 형식이 준비되어 있다.

REVOKE [ GRANT OPTION FOR ]
    { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
    [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
    ON [ TABLE ] table_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { USAGE | SELECT | UPDATE }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { SEQUENCE sequence_name [, ...]
         | ALL SEQUENCES IN SCHEMA schema_name [, ...] }
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
    ON DATABASE database_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON DOMAIN domain_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON FOREIGN DATA WRAPPER fdw_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON FOREIGN SERVER server_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { EXECUTE | ALL [ PRIVILEGES ] }
    ON { { FUNCTION | PROCEDURE | ROUTINE }
       function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...]
         | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] }
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON LANGUAGE lang_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
    ON LARGE OBJECT loid [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
    ON SCHEMA schema_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { CREATE | ALL [ PRIVILEGES ] }
    ON TABLESPACE tablespace_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
    { USAGE | ALL [ PRIVILEGES ] }
    ON TYPE type_name [, ...]
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

여러 형식이 있지만, 기본은 아래와 같다.

REVOKE 권한 ON 대상 FROM 누구

여기서 “권한, 대상, 누구” GRANT 명령과 동일하다. 자세한 내용은 “역할 테이블, 뷰 등에 대한 권한을 추가(GRANT)“를 참조하도록 하자.

GRANT OPTION FOR를 넣어 REVOKE 명령을 실행하게 되면 , 권한을 다른 역할에 부여 소유권만 삭제된다. (GRANT 명령에서 WITH GRANT OPTION에 의해 추가 된 권한). 지정하지 않으면 권한 자체와 권한을 다른 역할에 부여한 내용도 모두 삭제된다.

REVOKE 명령은 마지막에 CASCADE 또는 RESTRICT를 지정할 수 있다. 자신에 추가된 것과 동일한 권한을 다른 역할에 추가한 경우에 기본 설정(RESTRICT)으로 자신에 추가된 권한의 삭제를 시도하면 실패하게 된다. 이에 반해 CASCADE를 지정하게 되면 자신의 권한과 동시에 자신이 다른 역할에 추가한 동일한 권한도 함께 삭제된다.

권한을 다른 역할에서 제거는 개체의 소유자 및 수퍼 유저만 가능하다. 그 외에 역할의 경우는 GRANT 명령의 WITH GRANT OPTION으로 다른 역할에 추가한 권한만 삭제할 수 있다.

그러면보다 구체적으로 방법을 살펴 보도록 하겠다.

테이블에 대한 권한을 제거

테이블에 대한 권한을 삭제하는 경우를 예로 REVOKE 명령의 사용법을 확인하려고 한다. 사용하는 형식은 다음과 같다.

REVOKE [ GRANT OPTION FOR ]
    { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    FROM { [ GROUP ] role_name | PUBLIC } [, ...]
    [ CASCADE | RESTRICT ]

예제로 role_name 역할에 테이블 table_name을 대상으로 SELECT와 INSERT 권한을 제거하려면 다음과 같이 실행한다.

REVOKE SELECT, INSERT ON table_name FROM role_name;

role_name 역할에 테이블 table_name을 대상으로 SELECT 권한을 다른 역할에 추가할 권한만 제거하려면 다음과 같이 실행한다.

REVOKE GRANT OPTION FOR SELECT ON table_name FROM role_name;

role_name 역할에 테이블 table_name을 대상으로 SELECT 권한을 삭제하고 role_name 역할이 다른 역할에 추가 한 SELECT 권한도 동시에 제거하려면 다음과 같이 실행한다.

REVOKE SELECT ON table_name FROM role_name CASCADE;

role_name 역할에 테이블 table_name을 대상으로 모든 권한을 제거하려면 다음과 같이 실행한다.

REVOKE ALL PRIVILEGES ON table_name FROM role_name;

그러면 실제로 해보도록 하자. 현재 public 스키마에 staff 테이블이 생성되고, momo 역할에 대해 SELECT, INSERT, UPDATE 권한이 추가되어 있다. psql 메타 명령 \dp를 사용하여 확인을 해보자.

devkuma=# \dp
                                액세스 권한
 스키마 | 이름 |  종류  |        액세스 권한        | 칼럼 접근권한 | 정책
--------+------+--------+---------------------------+---------------+------
 public | memo | 테이블 | postgres=arwdDxt/postgres+|               |
        |      |        | mykuma=arw/postgres       |               |
(1개 행)


devkuma=#

※ 위 액세스 권한은 GRANT SELECT,INSERT,UPDATE ON memo TO mykuma;으로 추가된 권한이다.

memo 테이블의 액세스 권한에 다음과 같은 값이 설정되어 있다.

postgres=arwdDxt/postgres
mykuma=arw/postgres

값의 의미는 다음과 같다. mykuma 역할에 대해서는 postgres 역할이 a(INSERT), r(SELECT), w(UPDATE)의 권한이 추가되어 있다 것을 의미한다.

rolename=xxxx -- 롤에 부여 된 권한
=xxxx -- PUBLIC에 부여된 권한

            r -- SELECT (읽기 (read))
            w -- UPDATE (쓰기 (write))
            a -- INSERT (추가 (append))
            d -- DELETE
            D -- TRUNCATE
            x -- REFERENCES
            t -- TRIGGER
            X -- EXECUTE
            U -- USAGE
            C -- CREATE
            c -- CONNECT
            T -- TEMPORARY
      arwdDxt -- 모든 권한 (테이블 용 다른 객체는 다르다.)
            * -- 직전의 권한에 관한 그랜트 옵션

        / yyyy -이 권한을 부여한 역할

그러면, mykuma 역할에서 memo 테이블에 대한 SELECT 권한을 제거한다. 수퍼 유저로 접속하여 다음과 같이 실행한다.

devkuma=# revoke select on memo from mykuma;
REVOKE
devkuma=#

SELECT 권한이 삭제되었다. 확인을 위해 다시 \dp 명령을 실행해 보자.

devkuma=# \dp
                                액세스 권한
 스키마 | 이름 |  종류  |        액세스 권한        | 칼럼 접근권한 | 정책
--------+------+--------+---------------------------+---------------+------
 public | memo | 테이블 | postgres=arwdDxt/postgres+|               |
        |      |        | mykuma=aw/postgres        |               |
(1개 행)


devkuma=#

액세스 권한의 값이 mykuma=arw/postgres에서 mykuma=aw/postgres되어 r(SELECT)가 제거된 것을 확인할 수 있다.

다음은 mykuma 역할에서 memo 테이블에 대한 모든 권한을 제거해 보자. 수퍼 유저로 접속한 뒤 다음과 같이 실행한다.

devkuma=# revoke all privileges on memo from mykuma;
REVOKE
devkuma=#

남아 있던 INSERT 및 UPDATE 권한도 삭제되었다. 확인을 위해 다시 \dp 명령을 실행해 보도록 하자.

devkuma=# \dp
                                액세스 권한
 스키마 | 이름 |  종류  |        액세스 권한        | 칼럼 접근권한 | 정책
--------+------+--------+---------------------------+---------------+------
 public | memo | 테이블 | postgres=arwdDxt/postgres |               |
(1개 행)


devkuma=#

액세스 권한에 mykuma 역할 자체가 모두 삭제되었다.

CASCADE를 지정하고 권한을 모두 삭제하기

역할 A가 자신에게 추가된 권한을 다른 역할 B에 추가한 경우에 역할 A의 권한을 삭제하려고 하면 실패한다. 이러한 경우 REVOKE 명령을 실행할 때 CASCADE를 지정한다. CASCADE를 지정하면 역할 A의 권한을 제거하는 동시에 역할 A가 역할 B에 추가한 권한도 연쇄적으로 삭제된다.

그러면 실제로 해보도록 하자. 먼저 수퍼 유저로 PostgreSQL에 접속하여 mykuma 역할에 public 스키마에 memo 테이블을 대상으로 SELECT 권한을 추가한다. 이때 WITH GRANT OPTION을 추가하여 다른 역할에 권한을 추가할 수 있도록 한다.

devkuma=# grant select on memo to mykuma with grant option;
GRANT
devkuma=#

다음에 mykuma 역할로 PostgreSQL에 접속하여, superkuma 역할에 public 스키마에 memo 테이블을 대상으로 SELECT 권한을 추가한다.

C:\Users\kimkc>psql -U mykuma -d devkuma
mykuma 사용자의 암호:
psql (12.2)
도움말을 보려면 "help"를 입력하십시오.

devkuma=> grant select on memo to superkuma;
GRANT
devkuma=>

psql 메타 명령 \dp를 사용하여 테이블에 추가되는 권한을 확인하려고 한다.

devkuma=> \dp
                                액세스 권한
 스키마 | 이름 |  종류  |        액세스 권한        | 칼럼 접근권한 | 정책
--------+------+--------+---------------------------+---------------+------
 public | memo | 테이블 | postgres=arwdDxt/postgres+|               |
        |      |        | mykuma=r*/postgres       +|               |
        |      |        | superkuma=r/mykuma        |               |
(1개 행)


devkuma=>

staff 테이블의 액세스 권한 곳에 다음과 같은 값이 설정되어 있다.

postgres=arwdDxt/postgres+
mykuma=r*/postgres       +
superkuma=r/mykuma

mykuma 역할에 대해서는 postgres 역할이 r(SELECT) *(그랜트 옵션)의 권한이 추가되었으며, superkuma 역할에 대해서는 momo 역할은 r(SELECT)의 권한이 추가되었다.

이 상태에서 mykuma 역할에서 memo 테이블에 대한 SELECT 권한을 제거하려고 한다. 수퍼 유저로 접속하여 다음과 같이 실행한다.

devkuma=# revoke select on memo from mykuma;
오류:  ???의존(적인) 권한이 존재합니다
힌트:  그것들을 취소하려면 "CASCADE"를 사용하세요.
devkuma=#

그러자 “오류: ???의존(적인) 권한이 존재합니다“라는 오류가 발생하고 권한의 삭제에 실패하였다. mykuma 역할에서 제거하려고 권한 대해 mykuma 역할이 다른 역할에 권한을 추가하였기 때문이다.

이런 때는 REVOKE 명령에 CASCADE를 지정하여 실행한다. 수퍼 유저로 접속하여 다음과 같이 실행한다.

devkuma=# revoke select on memo from mykuma cascade;
REVOKE
devkuma=#

이번에는 권한의 삭제에 성공하였다. 확인을 위해 다시 \dp 명령을 실행해 본다.

devkuma=# \dp
                                액세스 권한
 스키마 | 이름 |  종류  |        액세스 권한        | 칼럼 접근권한 | 정책
--------+------+--------+---------------------------+---------------+------
 public | memo | 테이블 | postgres=arwdDxt/postgres |               |
(1개 행)


devkuma=#

액세스 권한의 값에 mykuma에 추가한 권한이 삭제되면서 superkuma에 추가한 권한도 삭제되었다. 이렇게 REVOKE 명령을 실행할 때 CASCADE를 지정하면, 제거하려는 권한이 다른 역할에 추가된 경우에도 연쇄 적으로 제거할 수 있다.

여기까지 REVOKE 명령을 사용하여 권한을 삭제하는 방법에 대해 알아 보았다.