Authorization
상위 문서: SQL
개요
사용자에게 부여할 수 있는 데이터에 대한 권한(authorization)에는 다음과 같은 것들이 포함된다:
- 데이터를 읽을(read) 수 있는 권한
- 새로운 데이터를 삽입(insert) 할 수 있는 권한
- 데이터를 갱신(update) 할 수 있는 권한
- 데이터를 삭제(delete) 할 수 있는 권한
이러한 각 유형의 권한은 privilege(특권) 라고 불린다. 또한 all privileges는 허용 가능한 모든 권한을 간략하게 나타낸다. 이때 사용자에게 데이터베이스의 특정 부분[1]에 대해 사용자가 질의(query)나 갱신(update)을 제출하면, SQL 구현체는 먼저 해당 질의나 갱신이 허가된 것인지(authorized)를 사용자가 가진 권한을 기준으로 검사한다. 만약 허가되지 않은 작업이라면 거부된다.
데이터에 대한 권한 외에도, 사용자는 데이터베이스 스키마(schema) 에 대한 권한을 부여받을 수도 있다. 예를 들어, 사용자가 릴레이션을 생성(create), 수정(modify), 삭제(drop) 하는 것이 가능하게 된다. 어떤 형태로든 권한을 부여받은 사용자는, 이 권한을 다른 사용자에게 넘겨주거나(grant), 이전에 부여했던 권한을 회수(revoke) 할 수도 있다.
Granting and Revoking of Privileges
Authorization Specification in SQL
grant 문은 사용자에게 권한을 부여하기 위해 사용되며 기본적인 형태는 다음과 같다:
grant <privilege list> --privilege list를 통해 하나의 명령문으로 여러 권한을 동시에 부여할 수 있다.
on <relation/view name>
to <user/role list>;
select 권한은 릴레이션의 튜플을 읽기(read) 위해 필요하다. 예를 들어, 다음 grant 문은 데이터베이스 사용자 Amit와 Satoshi에게 department 릴레이션에 대한 select 권한을 부여한다:
grant select on department to Amit, Satoshi;
이 명령어는 해당 사용자들이 department 릴레이션에 대해 쿼리를 수행할 수 있도록 권한을 부여한다. update 권한은 사용자가 릴레이션의 어떤 튜플이든 갱신(update) 할 수 있도록 허용한다.
update 권한은 릴레이션의 모든 속성에 대해 부여할 수도 있고, 일부 속성에만 부여할 수도 있다. update 권한이 grant 문에 포함될 경우, 권한을 부여할 속성들의 목록은 update 키워드 바로 뒤에 괄호 안에 선택적으로 나타날 수 있다. 속성 목록이 생략되면, 해당 릴레이션의 모든 속성에 대해 update 권한이 부여된다. 다음 grant 문은 Amit와 Satoshi에게 department 릴레이션의 budget 속성에 대한 update 권한을 부여한다:
grant update (budget) on department to Amit, Satoshi;
insert 권한은 사용자가 릴레이션에 새로운 튜플을 삽입(insert) 할 수 있도록 허용한다. insert 권한도 속성 목록을 명시할 수 있는데, 이 경우 해당 릴레이션에 삽입되는 튜플은 반드시 이 속성들만 지정해야 하며, 나머지 속성은 기본값(default) 을 가지거나, 기본값이 정의되지 않은 경우에는 null로 설정된다.
delete 권한은 사용자가 릴레이션에서 튜플을 삭제(delete) 할 수 있도록 허용한다.
public이라는 사용자 이름은 모든 현재 및 미래의 사용자를 의미하며, public에게 부여된 권한은 모든 사용자에게 암묵적으로 부여된 것으로 간주된다.
Revoking Authorization in SQL
권한을 회수(revoke)하려면 revoke 문을 사용하며, 그 형식은 grant 문과 거의 동일하다:
revoke <privilege list>
on <relation name or view name>
from <user/role list>;
따라서 이전에 부여한 권한을 회수하기 위해서는 다음과 같이 작성할 수 있다.
revoke <privilege list>
revoke select on department from Amit, Satoshi;
revoke update (budget) on department from Amit, Satoshi;
Roles
대학 내 모든 교수(instructor)는 동일한 릴레이션 집합에 대해 동일한 종류의 권한을 가져야 한다. 하지만 새로운 교수가 임용될 때마다, 이러한 권한들을 개별적으로 모두 부여해야 하는 상황은 비효율적이다. 따라서 더 나은 접근 방식은, 모든 교수에게 부여할 권한을 미리 정의해두고, 어떤 데이터베이스 사용자가 교수인지 따로 지정하는 것이다.
시스템은 이 두 정보를 이용하여 각 교수의 권한을 결정할 수 있다. 새로운 교수를 채용할 경우, 해당 인물에게 사용자 식별자(user identifier)를 할당하고, 그를 “교수” 역할로 식별하면 된다. 이때 교수에게 개별 권한을 일일이 재지정할 필요는 없다. 이 개념을 역할(role) 이라고 하며 데이터베이스 안에 역할들의 집합이 생성된다. 사용자에게 권한을 부여하듯, 역할에도 권한을 부여할 수 있으며, 각 사용자에게는 수행할 수 있도록 허가된 역할들이 부여된다.[2] 이때 사용자에게 부여할 수 있는 모든 권한은 역할에도 부여할 수 있다.
SQL에서 역할은 다음과 같이 생성할 수 있다:
revoke <privilege list>
create role instructor;
역할에게 권할을 부여할 때 역시 사용자에게 권한을 부여하는 것과 비슷하다:
revoke <privilege list>
grant select on takes to instructor;
또한, 역할은 사용자뿐 아니라 다른 역할에게도 부여할 수 있다:
revoke <privilege list>
create role dean;
grant instructor to dean;
grant dean to Satoshi;
위와 같이 되면, 사용자 Satoshi는 dean 역할을 갖고, dean은 instructor 역할을 포함하므로, Satoshi는 instructor의 모든 권한도 자동으로 상속받는다. 이때 역할 간의 체인이 존재할 수도 있다. 예를 들어, teaching assistant 역할이 모든 instructor에게 부여되고 instructor 역할이 모든 dean에게 부여되었다면 dean 역할은 instructor, teaching ssistant의 권한을 모두 상속하게 된다.
사용자가 데이터베이스 시스템에 로그인하면, 해당 세션에서 수행하는 모든 작업은 사용자에게 직접 부여된 권한과 사용자에게 부여된 역할들(직접 또는 간접)에 포함된 권한을 모두 가진다.
Authorization on Views
대학 데이터베이스에서 어떤 직원이 지질학과(Geology department)에 소속된 모든 교수들의 급여 정보를 알아야 한다고 하자. 이 직원은 다른 학과 교수들에 대한 정보는 볼 수 있는 권한이 없으므로 이 직원은 instructor 릴레이션에 직접 접근해서는 안 된다. 하지만 지질학과 교수들의 정보는 볼 수 있어야 하므로, 해당 교수 튜플만으로 구성된 뷰(view)를 제공할 수 있다. 이 뷰를 geo_instructor라고 부를 수 있으며, SQL에서는 다음과 같이 정의할 수 있다:
create view geo_instructor as (
select * from instructor
where dept_name = 'Geology'
);
이제 이 직원이 다음과 같은 SQL 쿼리를 수행한다고 하자:
select * from geo_instructor;
해당 직원은 위 쿼리의 결과를 볼 수 있어야 한다. 하지만, SQL은 실제로는 뷰를 진짜 테이블로 변환해서 실행하려 한다.[3] 하지만 이는 instructor 테이블을 직접 조회하는 쿼리에 해당하므로, SQL은 instructor 테이블을 직접 조회하는 질의로 보고, 사용자는 instructor에 대한 권한이 없기 때문에 접근 불가 판정이 생긴다. 하지만 원래 직원은 geo_instructor 뷰에 대해서는 권한이 있었므로 서로 상충된다.
따라서 시스템은 사용자가 질의한 뷰(geo_instructor) 기준으로 먼저 권한 검사를 진행한 후, 사용자가 geo_instructor에 select 권한이 있다면 뷰를 instructor 기반의 쿼리로 치환해서 내부적으로 실행한다. 이때 뷰를 만든 사용자(view creator)가 그 뷰에 대한 모든 권한을 자동으로 받는 것은 아니다. 뷰를 통해 기존에 자신이 갖고 있던 권한을 넘어서는 권한이 생기지 않도록, 시스템은 뷰 생성자에게 원래 가진 권한에 해당하는 범위까지만 허용한다.
Authorizations on Schema
SQL은 데이터베이스 스키마에 대한 기본적인 권한 부여 메커니즘을 명시하고 있다. 가장 중요한 원칙은 스키마의 소유자만이 그 스키마에 대해 다음과 같은 수정 작업을 수행할 수 있다는 것이다:
- 릴레이션 생성 또는 삭제
- 릴레이션의 속성 추가 또는 제거
- 인덱스 추가 또는 제거
또한, SQL은 사용자가 릴레이션을 생성할 때 foreign key를 선언할 수 있도록 해주는 references 권한도 포함하고 있다. references 권한은 update 권한처럼, 특정 속성에 대해 부여할 수 있다. 다음 grant 문은 사용자 Mariano에게 department 릴레이션의 dept_name 속성을 foreign key로 참조할 수 있도록 허용한다:
grant references (dept_name) on department to Mariano;
이때 특별히 reference 권한이 존재하는 이유는 foreign key 제약 조건이 참조되는 릴레이션에서의 삭제(delete)나 갱신(update)을 제한하기 때문이다.
Transfer of Privileges
어떤 권한을 부여받은 사용자는, 그 권한을 다른 사용자에게 전달(pass on) 할 수 있도록 허가받을 수 있다. 만약 어떤 권한을 부여하면서, 해당 권한을 다른 사용자에게도 다시 부여할 수 있도록 허용하고 싶다면, grant 명령문에 with grant option절을 덧붙여야 한다. 예를 들어, 사용자 Amit에게 department 릴레이션에 대한 select 권한을 주면서, 다른 사용자에게도 해당 권한을 줄 수 있도록 하려면, 다음과 같이 작성한다:
grant select on department to Amit with grant option;
객체(릴레이션, 뷰, 역할 등)의 생성자(creator)는 그 객체에 대해 모든 권한을 가지며, 다른 사용자에게 권한을 부여할 수 있는 권한도 포함된다.