ablog

不器用で落着きのない技術者のメモ

Redshift で Datasharing している View を Drop/Create すると付与済みの権限は喪失するか

Redshift で Datasharing している View に対して、オブジェクトレベルで Grant している場合、Create or Replace すると権限は維持されるが、Drop/Create すると権限が喪失することを確認した。

Producer 側
  • データ共有を作成する
CREATE DATASHARE cnt_datashare;
ALTER datashare cnt_datashare SET publicaccessible = FALSE;
-- DROP は以下の通り
-- DROP DATASHARE cnt_datashare;
CREATE SCHEMA IF NOT EXISTS share_schema;

CREATE TABLE IF NOT EXISTS share_schema.share_table(
      id NUMERIC(18,0),
      name CHARACTER VARYING(10) 
);
INSERT INTO share_schema.share_table VALUES(1, 'chicken');
INSERT INTO share_schema.share_table VALUES(2, 'pook');
INSERT INTO share_schema.share_table VALUES(3, 'beef');

CREATE OR REPLACE VIEW share_schema.share_view AS SELECT * FROM share_schema.share_table;
-- ALTER DATASHARE cnt_datashare ADD TABLE share_schema.share_table;
  • データ共有の設定を変更する
ALTER DATASHARE cnt_datashare ADD SCHEMA share_schema;
ALTER DATASHARE cnt_datashare ADD ALL TABLES IN SCHEMA share_schema;
ALTER DATASHARE cnt_datashare SET INCLUDENEW=TRUE FOR SCHEMA share_schema;
-- false だとシェアリングされない

[ SET INCLUDENEW [=] TRUE | FALSE FOR SCHEMA schema ]
指定したスキーマで作成される将来のテーブル、ビュー、または SQL ユーザー定義関数 (UDF) をデータ共有に追加するかどうかを指定する句。

ALTER DATASHARE - Amazon Redshift
  • データ共有を Consumer に共有する
-- NAMESPACE には Consumer 側で 'select current_namespace' を実行した結果を指定する
GRANT USAGE ON DATASHARE cnt_datashare TO NAMESPACE 'b77f3524-8f94-46f9-bc61-b7d8a3026df5';
-- REVOKE は以下の通り
-- REVOKE USAGE ON DATASHARE cnt_datashare FROM NAMESPACE 'b77f3524-8f94-46f9-bc61-b7d8a3026df5';
  • 共有されているオブジェクトを確認する
\x

SELECT * FROM svv_datashares;
-[ RECORD 1 ]-------+-----------------------------------------------------------------
share_name          | cnt_datashare
share_id            | 3538669
share_owner         | 100
source_database     | dev
consumer_database   |
share_type          | OUTBOUND
createdate          | 2025-11-11 00:36:04
is_publicaccessible | f
share_acl           |
producer_account    | 542203247656
producer_namespace  | 8fe81794-e567-46f8-9d0d-3ddd862b7299
managed_by          |

SELECT * FROM svv_datashare_objects;
-[ RECORD 1 ]------+-------------------------------------
share_type         | OUTBOUND
share_name         | cnt_datashare
object_type        | schema
object_name        | share_schema
producer_account   | 542203247656
producer_namespace | 8fe81794-e567-46f8-9d0d-3ddd862b7299
include_new        | f
-[ RECORD 2 ]------+-------------------------------------
share_type         | OUTBOUND
share_name         | cnt_datashare
object_type        | table
object_name        | share_schema.share_table
producer_account   | 542203247656
producer_namespace | 8fe81794-e567-46f8-9d0d-3ddd862b7299
include_new        |
Consumer 側
  • ロールとユーザーを作成する
CREATE ROLE consumer_role;
CREATE USER consumer_user PASSWORD 'Password1!';
GRANT ROLE consumer_role TO consumer_user;
  • 共有されているデータ共有を確認する
\x

SELECT * FROM svv_datashares;
-[ RECORD 1 ]-------+-----------------------------------------------------------------
share_name          | cnt_datashare
share_id            |
share_owner         |
source_database     |
consumer_database   | cnt_datashare_db
share_type          | INBOUND
createdate          |
is_publicaccessible | f
share_acl           |
producer_account    | 542203247656
producer_namespace  | 8fe81794-e567-46f8-9d0d-3ddd862b7299
managed_by          |
  • データ共有を作成する
CREATE DATABASE cnt_datashare_db WITH PERMISSIONS FROM DATASHARE cnt_datashare OF NAMESPACE '8fe81794-e567-46f8-9d0d-3ddd862b7299';

SHOW DATABASES LIKE 'cnt_datashare_db';
-[ RECORD 1 ]------------+---------------------------------------------------------------------------------------------------------------------------------
database_name            | cnt_datashare_db
database_owner           | 100
database_type            | shared
database_acl             |
parameters               | {"datashare_name":"cnt_datashare","datashare_producer_account":"542203247656","datashare_producer_namespace":"8fe81794-e567-46f8
database_isolation_level | UNKNOWN

SHOW SCHEMAS FROM DATABASE cnt_datashare_db;

-[ RECORD 1 ]---+-----------------
database_name   | cnt_datashare_db
schema_name     | share_schema
schema_owner    | 100
schema_type     | shared
schema_acl      |
source_database |
schema_option   |
  • ROLE に作成したデータ共有へのアクセス権を付与する
GRANT USAGE ON DATABASE cnt_datashare_db TO ROLE consumer_role;
GRANT USAGE ON SCHEMA cnt_datashare_db.share_schema TO ROLE consumer_role;
GRANT SELECT ON TABLE cnt_datashare_db.share_schema.share_view TO ROLE consumer_role;
-- REVOKE SELECT ON TABLE cnt_datashare_db.share_schema.share_view FROM ROLE consumer_role;
-- SVV_RELATION_PRIVILEGES

/* Consumer でデータ共有作成時に "WITH PERMISSIONS" オプションをつけないと以下のエラーが発生する
ERROR:  database imported from datashare does not support fine grained permissions. Please create the database with permissions and retry.
*/

select * from SVV_DATASHARE_OBJECTS;
-[ RECORD 1 ]------+-------------------------------------
share_type         | INBOUND
share_name         | cnt_datashare
object_type        | schema
object_name        | share_schema
producer_account   | 542203247656
producer_namespace | 8fe81794-e567-46f8-9d0d-3ddd862b7299
include_new        |
-[ RECORD 2 ]------+-------------------------------------
share_type         | INBOUND
share_name         | cnt_datashare
object_type        | table
object_name        | share_schema.share_table
producer_account   | 542203247656
producer_namespace | 8fe81794-e567-46f8-9d0d-3ddd862b7299
include_new        |
-[ RECORD 3 ]------+-------------------------------------
share_type         | INBOUND
share_name         | cnt_datashare
object_type        | view
object_name        | share_schema.share_view
producer_account   | 542203247656
producer_namespace | 8fe81794-e567-46f8-9d0d-3ddd862b7299
include_new        |
  • データ共有したテーブルを参照する
$ psql "host=redshift-cluster-poc-commerce.********.ap-northeast-1.redshift.amazonaws.com user=consumer_user dbname=dev port=5439"

SELECT * FROM cnt_datashare_db.share_schema.share_table;
 id |  name
----+---------
  1 | chicken
  2 | pook
  3 | beef
  1 | chicken
(4 rows)

/*
Producer 側で "ALTER datashare cnt_datashare SET publicaccessible = FALSE;" を実行していないと以下のエラーが発生する
ERROR:  Publicly accessible consumer cannot access object in the database.
*/
[ec2-user@ip-172-31-0-101 ~]$ psql "host=redshift-cluster-poc-commerce.ceyg6jv96hfq.ap-northeast-1.redshift.amazonaws.com user=awsuser dbname=dev port=5439"
Timing is on.
psql (13.7, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

awsuser 01:20 =# GRANT SELECT ON TABLE cnt_datashare_db.share_schema.share_view TO ROLE consumer_role;
GRANT
Time: 353.331 ms
awsuser 01:20 =# \q
[ec2-user@ip-172-31-0-101 ~]$ psql "host=redshift-cluster-poc-commerce.ceyg6jv96hfq.ap-northeast-1.redshift.amazonaws.com user=consumer_user dbname=dev port=5439"
Password for user consumer_user:
Timing is on.
psql (13.7, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

consumer_user 01:20 => SELECT * FROM cnt_datashare_db.share_schema.share_view;
 id |  name
----+---------
  1 | chicken
  2 | pook
  3 | beef
  1 | chicken
(4 rows)


DROP VIEW share_s s;
CREATE OR REPLACE VIEW share_schema.share_view AS SELECT * FROM share_schema.share_table;
--> 参照できる

awsuser 01:21 =# DROP VIEW share_schema.share_view;
DROP VIEW
Time: 258.080 ms
awsuser 01:22 =# CREATE OR REPLACE VIEW share_schema.share_view AS SELECT * FROM share_schema.share_table;

--> 参照できる
  • 同じスキーマに別の View を作成しても、Grant していないので参照できない
-- Producer 側で superuser で実行
CREATE OR REPLACE VIEW share_schema.share_view2 AS SELECT * FROM share_schema.share_table;

-- Consumer 側 superuser で実行
 select * from SVV_DATASHARE_OBJECTS;
 share_type |  share_name   | object_type |       object_name        | producer_account |          producer_namespace          | include_new
------------+---------------+-------------+--------------------------+------------------+--------------------------------------+-------------
 INBOUND    | cnt_datashare | schema      | share_schema             | 542203247656     | 8fe81794-e567-46f8-9d0d-3ddd862b7299 |
 INBOUND    | cnt_datashare | table       | share_schema.share_table | 542203247656     | 8fe81794-e567-46f8-9d0d-3ddd862b7299 |
 INBOUND    | cnt_datashare | view        | share_schema.share_view  | 542203247656     | 8fe81794-e567-46f8-9d0d-3ddd862b7299 |
 INBOUND    | cnt_datashare | view        | share_schema.share_view2 | 542203247656     | 8fe81794-e567-46f8-9d0d-3ddd862b7299 |
(4 rows)

-- Consumer 側 consumer_user で実行
SELECT * FROM cnt_datashare_db.share_schema.share_view2;
ERROR:  Permission denied for relation share_view2

参考

ローカルデータベース内のオブジェクトへのアクセスをより細かく制御する場合は、データベースの作成時に WITH PERMISSIONS 句を使用します。これにより、ステップ 4 でデータベース内のオブジェクトにオブジェクトレベルのアクセス許可を付与できます。

CREATE DATABASE sales_db WITH PERMISSIONS FROM DATASHARE salesshare OF ACCOUNT '123456789012' NAMESPACE 'dd8772e1-d792-4fa4-996b-1870577efc0d';

(中略)

ステップ 2 で WITH PERMISSIONS を使用してデータベースを作成した場合は、共有データベース内のオブジェクトにオブジェクトレベルのアクセス許可を割り当てる必要があります。USAGE アクセス許可のみを持つユーザーは、追加のオブジェクトレベルのアクセス許可が付与されるまで、WITH PERMISSIONS を使用して作成されたデータベース内のオブジェクトにはアクセスできません。

GRANT SELECT ON sales_db.public.tickit_sales_redshift to Bob;
コンシューマー管理者のアクション - Amazon Redshift