보안 데이터베이스 객체 공유하기
보안 데이터베이스 객체 공유하기
셰어(share)를 만들어 데이터베이스와 그 객체를 하나 이상의 계정과 공유하는 방법을 다뤄요.
본문
셰어를 직접 셰어(direct share) 또는 listing으로 소비자에게 제공할 수 있어요. 셰어를 listing에 붙이거나, 활성 소비자가 있는 직접 셰어를 listing으로 변환할 수도 있어요. 공유된 데이터를 소비하려는 소비자라면 가져온 데이터 소비하기 문서를 참고해요.
참고: 프로바이더 공유는 대부분의 계정에서 기본적으로 활성화되어 있지만 전부는 아니에요. 소비자와 데이터 공유를 시도할 때 오류가 발생한다면 계정에서 이 기능이 활성화되지 않았을 수 있어요. 활성화를 문의하려면 Snowflake 지원에 연락해 주세요.
데이터베이스 객체를 공유하는 방법
셰어에 객체를 추가하는 옵션은 두 가지예요.
옵션 1 — 셰어에 데이터베이스 역할(database role) 부여하기
데이터베이스에 여러 데이터베이스 역할을 만들어 셰어 안의 보안 가능(securable) 객체를 분할해요. 데이터베이스 안 객체의 부분집합에 대한 권한을 각 데이터베이스 역할에 부여한 뒤, 각 데이터베이스 역할을 셰어에 부여해요. 데이터베이스 역할이 포함된 셰어에서 데이터베이스를 만든 뒤에는 데이터 소비자가 공유된 각 데이터베이스 역할을 자신의 계정 안의 하나 이상의 계정 역할에 부여해요.
데이터베이스 역할이 없으면 데이터 소비자 계정의 계정 관리자가 IMPORTED PRIVILEGES 단일 권한을 역할에 부여해 사용자가 셰어 안의 모든 데이터베이스와 데이터베이스 객체(테이블, 보안 뷰 등)에 접근하게 해줘요. 데이터 소비자 계정 안의 서로 다른 사용자 그룹이 공유된 객체의 부분집합에 접근하게 하는 옵션은 없어요. 이 전부 아니면 전무(all-or-nothing) 방식 때문에 같은 데이터베이스 안의 서로 다른 객체에 접근 권한을 주려면 여러 셰어를 만들어야 해요.
참고: 단일 셰어에 여러 데이터베이스의 데이터를 포함하려면 이 옵션을 사용할 수 없어요.
REFERENCE_USAGE권한은 데이터베이스 역할에 부여할 수 없기 때문이에요. 여러 데이터베이스의 데이터 공유에 대한 안내는 여러 데이터베이스의 데이터 공유하기를 참고해요.또는 데이터베이스 역할을 셰어에 부여하는(옵션 1) 동시에, 데이터베이스 역할에 권한을 부여하지 않고 같은 셰어에 직접 객체 권한을 부여하는(옵션 2) 셰어를 만들 수도 있어요. 이 셰어에서 데이터베이스를 만든 데이터 소비자는 데이터베이스에 대한
IMPORTED PRIVILEGES권한을 로컬 역할에 부여해 셰어에 직접 부여된 객체에 접근할 수 있어요.
팁: 공유된 데이터베이스 역할은 객체에 대한 향후 권한 부여(future grants)를 지원하지 않아요.
옵션 2 — 객체에 대한 권한을 셰어에 직접 부여하기
데이터베이스 안 특정 객체에 대한 권한을 셰어에 직접 부여해요. 이 옵션은 이 데이터베이스들이 같은 계정에 속하는 한, 여러 데이터베이스의 데이터를 하나의 셰어에 포함할 수 있게 해 줘요. 데이터 소비자 계정의 계정 관리자는 공유된 데이터베이스에 대한 IMPORTED PRIVILEGES 권한을 하나 이상의 역할에 부여해 사용자가 셰어 안의 데이터베이스와 데이터베이스 객체(테이블, 보안 뷰 등)에 접근하게 해줘요. 이 옵션은 셰어 안의 데이터베이스 객체를 역할에 따라 분할하는 것을 지원하지 않아요.
데이터베이스 역할을 셰어에 부여하기
이 섹션은 데이터 프로바이더가 데이터베이스 역할을 사용해 셰어 안의 데이터베이스와 데이터베이스 객체에 대한 접근을 제한하는 방법을 설명해요.
참고: 이 주제의 작업을 수행하려면 역할에 전역
CREATE DATABASE와CREATE SHARE권한이 있어야 해요.
이 섹션의 확장 예시에서 데이터 프로바이더는 다음 객체를 데이터 소비자와 공유해요.
- 데이터베이스:
d1 - 스키마:
d1.s1 - 보안 뷰:
d1.s1.v1(결과 집합에 테이블d1.s1.t1의 레코드 포함),d1.s1.v2(결과 집합에 테이블d1.s1.t2,d1.s1.t3의 레코드 포함)
데이터 프로바이더는 이 객체들에 대한 접근을 제어하기 위해 데이터베이스 d1에 d1.r1과 d1.r2 두 데이터베이스 역할을 만들어요.
데이터베이스 역할 만들기:
CREATE DATABASE ROLE로 새 데이터베이스 역할을 만들거나 기존 역할을 교체해요. 정규화된 식별자로 데이터베이스 역할 d1.r1, d1.r2를 만들어요.
CREATE DATABASE ROLE d1.r1;
CREATE DATABASE ROLE d1.r2;
또는 세션에서 원하는 데이터베이스를 현재 데이터베이스로 설정한 뒤 데이터베이스 역할을 만들어요.
USE DATABASE d1;
CREATE DATABASE ROLE r1;
CREATE DATABASE ROLE r2;
객체에 대한 권한을 데이터베이스 역할에 부여하기:
GRANT <privileges> … TO ROLE로 단일 데이터베이스와 데이터베이스 안 객체의 부분집합에 대한 권한을 각 데이터베이스 역할에 부여해요. 데이터베이스 역할이 접근을 허용해야 하는 객체에만 권한을 부여해요. 데이터베이스 역할의 정규화된 이름을 지정하거나, 데이터베이스를 세션의 활성 데이터베이스로 설정한 뒤 상대 이름을 지정해요.
참고:
- 이 주제의 작업을 수행하려면
ACCOUNTADMIN역할 또는 관련 권한이 부여된 역할을 사용해야 해요.- 데이터베이스 역할에 부여된 권한은 데이터베이스 역할을 포함하는 데이터베이스·스키마에 대한
USAGE와 같은 데이터베이스 안의 다른 객체에 대한 권한으로 제한돼요. 특히REFERENCE_USAGE권한은 데이터베이스 역할에 부여해 여러 데이터베이스의 객체를 셰어에 포함할 수 없어요.
확장 예시에 이어서 다음 권한이 데이터베이스 역할에 부여돼요.
| 데이터베이스 역할 | 권한 | 객체 |
|---|---|---|
d1.r1 |
USAGE |
데이터베이스 d1 |
USAGE |
스키마 d1.s1 |
|
SELECT |
보안 뷰 d1.s1.v1 |
|
d1.r2 |
USAGE |
데이터베이스 d1 |
USAGE |
스키마 d1.s1 |
|
SELECT |
보안 뷰 d1.s1.v2 |
d1.r1 데이터베이스 역할에 권한을 부여하는 SQL:
GRANT USAGE ON SCHEMA d1.s1 TO DATABASE ROLE d1.r1;
GRANT SELECT ON VIEW d1.s1.v1 TO DATABASE ROLE d1.r1;
d1.r2 데이터베이스 역할에 권한을 부여하는 SQL:
GRANT USAGE ON SCHEMA d1.s1 TO DATABASE ROLE d1.r2;
GRANT SELECT ON VIEW d1.s1.v2 TO DATABASE ROLE d1.r2;
부모 데이터베이스에 대한 USAGE 권한을 부여할 필요는 없어요. 이 권한은 데이터베이스 역할이 만들어질 때 암시적으로 부여돼요. 데이터베이스 역할에 부여된 모든 권한을 보려면 정규화된 식별자로 SHOW GRANTS TO DATABASE ROLE을 실행해요.
SHOW GRANTS TO DATABASE ROLE d1.r1;
SHOW GRANTS TO DATABASE ROLE d1.r2;
셰어 만들기:
CREATE SHARE로 셰어를 만들어요. 이 단계에서 셰어는 빈 컨테이너예요. 예를 들어 share1라는 새 셰어를 만들어요.
CREATE SHARE share1;
USAGE 권한을 셰어에 부여해 데이터베이스 추가하기:
현재는 데이터베이스를 셰어에 포함하려면 데이터베이스에 대한 USAGE 권한을 부여해야 해요. 예를 들어 d1 데이터베이스에 대한 USAGE 권한을 share1에 부여해요.
GRANT USAGE ON DATABASE d1 TO SHARE share1;
데이터베이스 역할을 셰어에 부여해 객체 추가하기:
GRANT DATABASE ROLE … TO SHARE로 데이터베이스 역할을 셰어에 부여해 데이터베이스와 데이터베이스 객체를 셰어에 추가해요. 예를 들어 d1.r1, d1.r2 역할을 share1에 부여해요.
GRANT DATABASE ROLE d1.r1 TO SHARE share1;
GRANT DATABASE ROLE d1.r2 TO SHARE share1;
하나 이상의 데이터 소비자 계정과 공유하기:
ALTER SHARE … ADD ACCOUNTS로 셰어를 수정하고 데이터베이스 객체를 공유할 데이터 소비자 계정을 추가해요. 다음 예시는 조직 org1의 계정 consumer1과 consumer2를 share1에 추가해요.
ALTER SHARE share1 ADD ACCOUNTS = org1.consumer1, org1.consumer2;
데이터베이스 역할 관리하기:
- 공유된 데이터베이스 역할 이름 바꾸기(프로바이더):
ALTER DATABASE ROLE … RENAME TO문으로 데이터베이스 역할 이름을 바꿔요. 예를 들어d1.r1을d1.r3으로 바꿔요.
데이터베이스 역할 이름이 바뀐 뒤에도ALTER DATABASE ROLE d1.r1 RENAME TO d1.r3;d1.r1에 부여된 모든 권한은 유지돼요. 셰어의 데이터 소비자에게 데이터베이스 역할 이름이 바뀌었음을 알려요.RENAME TO절로 데이터베이스 역할을 다른 데이터베이스로 이동하는 것은 금지돼요. 예:ALTER DATABASE ROLE d1.r1 RENAME TO d2.r1; -- 금지 - 공유된 데이터베이스 역할 삭제(프로바이더):
DROP DATABASE ROLE로 데이터베이스 역할을 삭제해요. 예를 들어d1.r2를 삭제해요.
역할이 포함된 셰어의 데이터 소비자에게 알려요. 데이터베이스 역할에 부여된 객체 접근은 회수돼요.DROP DATABASE ROLE d1.r2; - 새 공유 데이터베이스 역할 만들기(프로바이더):
CREATE DATABASE ROLE로 새 데이터베이스 역할을 만들어요. 데이터베이스 객체에 대한 권한을 데이터베이스 역할에 부여한 뒤 그 역할을 셰어에 부여해요. 새 데이터베이스 역할이 포함된 셰어의 데이터 소비자에게 알려요. 소비자는 그 역할이 연결된 객체에 접근하도록 새 데이터베이스 역할을 자신의 계정 역할에 부여해야 해요.
셰어에 직접 권한 부여하기
이 섹션은 데이터 프로바이더가 공유된 데이터베이스에 단일 권한을 부여해 소비자가 셰어 안의 모든 데이터베이스와 데이터베이스 객체에 접근하게 하는 방법을 설명해요.
셰어 만들기:
CREATE SHARE로 셰어를 만들어요. 이 단계에서 셰어는 객체와 계정이 추가되기를 기다리는 컨테이너일 뿐이에요.
권한 부여로 셰어에 객체 추가하기:
GRANT <privilege> … TO SHARE로 다음 객체 권한을 셰어에 부여해요.
- 공유하려는 데이터베이스에 대한
USAGE권한 - 공유하려는 객체를 포함한 각 데이터베이스 스키마에 대한
USAGE권한 - 각 공유 스키마에서 특정 객체를 공유하기 위한
SELECT권한 — 객체 유형: 테이블, 외부 테이블, 보안 뷰, 보안 구체화된 뷰, 보안 UDF
중요: 서로 다른 리전이나 클라우드 플랫폼의 데이터 소비자와 데이터를 안전하게 공유하려면, 현재로서는 데이터베이스 안에 외부 테이블이 하나 이상 있으면 기본 데이터베이스 복제가 차단된다는 점에 주의해요.
참고: 스트림은 직접 공유할 수 없어요. 스트림 위에 보안 뷰를 만든 뒤 그 뷰를 소비자와 공유하는 것은 피해요. 대신 소비자가 공유하는 테이블과 보안 뷰에 자신의 스트림을 만들게 해요.
선택적으로 SHOW GRANTS로 셰어의 객체 권한을 확인해요.
팁: 다음 단계를 완료하면 셰어가 셰어에 추가된 모든 계정에 보이므로, 이 시점에 셰어에 대해 이 최소한의 검증을 수행해요. 더 깊이 있는 검증을 하려면 계정 안에서 소비자 계정을 시뮬레이션할 수 있어요.
셰어에 계정 하나 이상 추가하기:
ALTER SHARE로 셰어에 계정을 하나 이상 추가해요. 셰어에 추가된 계정을 검토하려면 SHOW GRANTS를 사용해요. 이제 셰어는 지정된 계정이 소비할 준비가 됐어요.
예시:
다음 예시는 위에서 설명한 전체 프로바이더 과정을 보여줘요. 이 예시는 sales_db라는 데이터베이스에 aggregates_eula 스키마와 aggregate_1 테이블이 있으며, 그 데이터베이스·스키마·테이블을 xy12345, yz23456 두 계정과 공유한다고 가정해요.
USE ROLE accountadmin;
CREATE SHARE sales_s;
GRANT USAGE ON DATABASE sales_db TO SHARE sales_s;
GRANT USAGE ON SCHEMA sales_db.aggregates_eula TO SHARE sales_s;
GRANT SELECT ON TABLE sales_db.aggregates_eula.aggregate_1 TO SHARE sales_s;
SHOW GRANTS TO SHARE sales_s;
ALTER SHARE sales_s ADD ACCOUNTS = xy12345, yz23456;
SHOW GRANTS OF SHARE sales_s;