AuthDev
AuthDev (Hive 권한 부여 설계 문서)
이 문서는 기존(원래) Hive 권한 부여 모드의 설계 문서예요. 관리자(Admin)·데이터베이스·테이블·컬럼 수준의 권한(privilege)과 역할(role), grant/revoke 문법, 인증 확인 절차, metastore에 권한 정보를 저장하는 테이블 구조를 설명하고 있어요. 참고로이 모드는 deprecated됐고, storage based authorization과 SQL standards based authorization으로 대체됐어요.
출처: 문서
본문
이 문서는 기존 Hive 권한 부여 모드의 설계 문서예요. 권한 부여 모드의 개요는 Authorization을 참고해요. 여기에는 storage based authorization과 SQL standards based authorization이 포함돼요.
1. 권한 (Privilege)
1.1 접근 권한 (Access Privilege)
Admin 권한, DB 권한, 테이블 수준 권한, 컬럼 수준 권한
1.1.1 Admin 권한은 전역 권한이며 관리 수행에 사용돼요. 1.1.2 DB 권한은 데이터베이스별이며 그 데이터베이스 안의 모든 객체에 적용돼요. 1.1.3 테이블 권한은 주어진 데이터베이스의 테이블/뷰/인덱스에 적용돼요. 1.1.4 컬럼 권한은 컬럼 수준에 적용돼요.
모든 DB/Table/Column 권한은 읽기·쓰기 권한을 구분해요. 현재 hive가 컬럼 수준 overwrite를 지원하지는 않아도 마찬가지예요. 그리고 파티션 수준 권한은 없어요.
2. Hive 연산 (Hive Operations)
- create index/drop index
- create database/drop database
- create table/drop table
- create view/drop view
- alter table
- show databases
- lock table/unlock table/show lock
- add partition
- archive
- Select
- insert overwrite directory
- insert overwrite table
- 기타: "create table as", "create table like" 등
3. 메타데이터 (Metadata)
권한 정보를 새 metastore 테이블 'user', 'db', 'tables_priv', 'columns_priv'에 저장해요.
user 테이블은 모든 데이터베이스에 적용되는 사용자의 전역 권한을 나타내요. db 테이블은 그 데이터베이스 안의 모든 객체에 적용되는 데이터베이스 수준 접근 권한을 결정해요.
3.1 user, group, roles
사용자는 일부 그룹에 속할 수 있어요. 그룹 정보는 인증자(authenticator)가 제공해요.
그리고 각 사용자나 그룹은 일부 권한과 역할을 가질 수 있어요. 역할은 다른 역할의 구성원이 될 수 있지만 순환 방식으로는 안 돼요.
따라서 hive 메타데이터에 저장해야 하는 것:
- roles -> privileges, roles 매핑
- Hive user/group -> privileges, role 매핑
3.1.1 역할 관리 (Role management)
- create role
- drop role
- 사용자에게 role 부여(grant)
- 사용자에서 role 회수(revoke)
3.1.2 역할 메타데이터 (role metadata)
- role_name - string
- create_time - int
3.1.3 hive role user membership table
- role_name - string
- user_name - string
- is_group - user name이 group name인지
- is_role - user name이 role name인지
3.2 Hive가 지원할 권한들
3.2.1 메타데이터
아래는 grant 정보를 metastore에 저장하는 방식을 보여줘요. deny 정보는 같은 방식으로(다른 테이블에) 저장돼요.
그래서 각 grant 테이블에 대해 deny 테이블도 존재해요. metastore 테이블은:
user, deny_user, db, deny_db, tables_priv, deny_tables_priv, columns_priv, deny_columns_priv
다른 방법은 grant 테이블에 이 행이 grant인지 deny인지 기록하는 컬럼을 추가하는 것이에요.
권한은 한 컬럼에 저장하고, 서로 다른 권한은 콤마로 구분해요.
hive> desc user;
Field
- ---
User
isRole
isGroup
isSuper
db_priv - set (Select_priv, Insert_priv, Create_priv, Drop_priv, Reload_priv,
Grant_priv, Index_priv, Alter_priv, Show_db_priv,
Lock_tables_priv, Create_view_priv, Show_view_priv)
hive> desc db;
Field
- ---
Db
User
isRole
isGroup
Table_priv - set (Select_priv, Insert_priv, Create_priv, Drop_priv, Grant_priv,
Index_priv, Reload_priv, Alter_priv, Create_tmp_table_priv,
Lock_tables_priv, Create_view_priv, Show_view_priv)
hive> desc tables_priv;
Field
- ---
Db
User
isRole
isGroup
Table_name
Grantor
Timestamp
Table_priv - set('Select','Insert','Create','Drop','Grant','Index','Alter','Create View','Show view')
Column_priv - set('Select','Insert',)
mysql> desc columns_priv;
Field
- ---
Db
User
isRole
isGroup
Table_name
Column_name
Timestamp
Column_priv - set('Select','Insert','Update')
4. grant/revoke 접근 권한
4.1 권한 이름/타입 (Privilege names/types):
- ALL Privileges
- ALTER
- Create
- Create view
- Delete
- Drop
- Index
- Insert
- Lock Tables
- Select
- Show databases
- Super
4.2 show grant
4.3 grant/revoke 문
GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user [, user] ...
WITH ADMIN OPTION
object_type:
TABLE
priv_level:
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
REVOKE
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
FROM user [, user] ...
REVOKE ALL PRIVILEGES, GRANT OPTION
FROM user [, user] ...
DENY
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
FROM user [, user] ...
5. 권한 부여 확인 (Authorization verification)
5.1 USER/GROUP/ROLE
- USER
- GROUP
- ROLE
GROUP은 ROLE과 매우 비슷해요. 그리고 Group을 지원하는 이유는 그룹 정보를 HDFS/Map-reduce에 전달해야 할 수 있기 때문이에요.
역할은 다른 역할과 권한을 포함할 수 있고, 사용자와 그룹에 부여될 수 있어요.
역할은 중첩될 수 있지만 순환은 안 돼요.
5.2 확인 단계 (The verification steps)
사용자가 시스템에 로그인하면 사용자 이름과 그가 속한 하나 이상의 그룹을 가져요. 그래서 그것은
[
username,
list of group names,
list of privileges and roles that has been directly granted,
list of privileges and roles that been directly granted to groups that users belongs to
].
- 한 접근을 승인하는 단계: *
먼저 사용자 이름을 시도:
# 이 접근을 수락하는 'user'의 엔트리가 있으면 ACCEPT 반환
2. 이 접근을 수락하는 'db'의 엔트리가 있으면 ACCEPT 반환
3. 이 접근을 수락하는 'table'의 엔트리가 있으면 ACCEPT 반환
4. 이 접근을 수락하는 'column'의 엔트리가 있으면 ACCEPT 반환
둘째, ACCEPT를 얻을 때까지 사용자의 group/role 이름을 하나씩 시도.
각 role/group에 대해 사용자 이름에 했던 것과 같은 루틴을 수행.
5.3 예제 (Examples)
5.3.1 모든 사람(언제든 새 사람이 합류할 수 있음)에게 db_name.* 을 부여하고, 나중에 한 테이블 db_name.T를 일부 사용자를 제외한 모든 사용자로부터 보호하고 싶음
- 모든 사용자를 그룹 'users'에 추가. (가정: 새 사용자는 자동으로 이 그룹에 합류) 그리고 'users'에 db_name.*에 대한 ALL 권한을 부여.
- 그 몇몇 사용자를 새 그룹 'users2'에 추가. 그리고 'users'에서 REMOVE.
- 'users'에 db_name.T를 DENY.
- users2에 db_name.T에 ALL을 부여.
5.3.2 한 테이블 db_name.T를 한/몇 명의 사용자로부터 보호하고 싶지만, 그 외의 사람은 접근할 수 있게 하고 싶음
- 모든 사용자를 그룹 'users'에 추가. (가정: 새 사용자는 자동으로 이 그룹에 합류) 그리고 'users'에 db_name.*에 대한 ALL 권한을 부여.
- 그 몇몇 사용자를 새 그룹 'users2'에 추가. (참고: 그 몇몇 사용자는 이제 2개 그룹(users와 user2)에 속하게 됨)
- 'users2'에 db_name.T를 DENY.
6. Hive에서 권한 부여를 추가할 위치 (Where to add authorization in Hive)
CliDriver와 HiveServer. 기본적으로 같은 코드를 공유해요. HiveServer가 CliDriver를 호출하면 CliDriver에 추가할 수 있어요. 그리고 HiveServer가 여러 사용자/커넥션을 지원할 수 있게 해야 해요. 이것은 누군가 (Hive를 통하지 않고) metastore에 직접 접근할 경우 문제를 해결하지 못해요.
7. 구현 (Implementation)
7.1 인증자 인터페이스 (Authenticator interface)
우리는 인증자로부터 사용자의 사용자 이름, 그룹 이름만 얻어요. 인증자 구현은 이 정보를 제공해야 해요. 이것이 인증자와 권한 부여 사이의 유일한 인터페이스예요.
7.2 권한 부여 (Authorization)
권한 부여 결정 관리자(authorization decision manager)는 일련의 권한 부여 제공자(authorization provider)를 관리하고, 각 제공자는 수락하거나 거부할 수 있어요. 최종 결정을 하는 것은 결정 관리자예요. 투표 기반이거나, 하나가 -1이면 거부, 또는 하나가 +1이면 수락이 될 수 있어요. 권한 부여 제공자는 자신의 정보에 기반해 접근을 수락할지 거부할지 결정해요.
8. mysql용 metastore 업그레이드 스크립트
다음은 ROLES, ROLE_MAP, GLOBAL_PRIVS, DB_PRIVS, TBL_PRIVS, PART_PRIVS, TBL_COL_PRIVS, PART_COL_PRIVS 같은 새 테이블을 만드는 mysql 스크립트 구조예요. 각 테이블은 키-값 스키마로 grant 정보를 저장해요.
--
-- Table structure for table {{ROLES}}
--
DROP TABLE IF EXISTS {{ROLES}};
CREATE TABLE {{ROLES}} (
{{ROLE_ID}} bigint(20) NOT NULL,
{{CREATE_TIME}} int(11) NOT NULL,
{{OWNER_NAME}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{ROLE_NAME}} varchar(128) character set latin1 collate latin1_bin default NULL,
PRIMARY KEY ({{ROLE_ID}}),
UNIQUE KEY {{ROLEENTITYINDEX}} ({{ROLE_NAME}})
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Table structure for table {{ROLE_MAP}}
--
DROP TABLE IF EXISTS {{ROLE_MAP}};
CREATE TABLE {{ROLE_MAP}} (
{{ROLE_GRANT_ID}} bigint(20) NOT NULL,
{{ADD_TIME}} int(11) NOT NULL,
{{GRANT_OPTION}} smallint(6) NOT NULL,
{{GRANTOR}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{GRANTOR_TYPE}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{PRINCIPAL_NAME}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{PRINCIPAL_TYPE}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{ROLE_ID}} bigint(20) default NULL,
PRIMARY KEY ({{ROLE_GRANT_ID}}),
UNIQUE KEY {{USERROLEMAPINDEX}} ({{PRINCIPAL_NAME}},{{ROLE_ID}},{{GRANTOR}},{{GRANTOR_TYPE}}),
KEY {{ROLE_MAP_N49}} ({{ROLE_ID}}),
CONSTRAINT {{ROLE_MAP_FK1}} FOREIGN KEY ({{ROLE_ID}}) REFERENCES {{ROLES}} ({{ROLE_ID}})
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Table structure for table {{GLOBAL_PRIVS}}
--
DROP TABLE IF EXISTS {{GLOBAL_PRIVS}};
CREATE TABLE {{GLOBAL_PRIVS}} (
{{USER_GRANT_ID}} bigint(20) NOT NULL,
{{CREATE_TIME}} int(11) NOT NULL,
{{GRANT_OPTION}} smallint(6) NOT NULL,
{{GRANTOR}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{GRANTOR_TYPE}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{PRINCIPAL_NAME}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{PRINCIPAL_TYPE}} varchar(128) character set latin1 collate latin1_bin default NULL,
{{USER_PRIV}} varchar(128) character set latin1 collate latin1_bin default NULL,
PRIMARY KEY ({{USER_GRANT_ID}}),
UNIQUE KEY {{GLOBALPRIVILEGEINDEX}} ({{PRINCIPAL_NAME}},{{PRINCIPAL_TYPE}},{{USER_PRIV}},{{GRANTOR}},{{GRANTOR_TYPE}})
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
나머지 DB_PRIVS, TBL_PRIVS, PART_PRIVS, TBL_COL_PRIVS, PART_COL_PRIVS 테이블도 같은 패턴으로 만들며, 각각 DB_ID, TBL_ID, PART_ID 같은 외래 키로 참조하고 {{DB_PRIV}}, {{TBL_PRIV}}, {{PART_PRIV}}, {{TBL_COL_PRIV}}, {{PART_COL_PRIV}} 권한 컬럼을 저장해요.
HDFS 권한 (HDFS Permission)
위의 방식은 파일 계층 보안에 대한 강한 가정을 가져요. 사용자에게 hdfs 파일 권한이 열려 있으면 보안을 쉽게 우회할 수 있어요. 우리는 권한 부여 결과나 심지어 규칙을 변경하기 위해 외부 권한 부여(예: HDFS permission/Howl permission)를 쉽게 연결(plug in)할 수 있기를 바래요.
더 알아보기 (Learn more)
- Hive Authorization에서 권한 부여 모드 전반을 볼 수 있어요.
- SQL standards based authorization 및 storage based authorization 문서를 볼 수 있어요.