如何在 bigquery 中构建视图以实现高效的访问管理
How to structure views in bigquery for efficient access management
在 BigQuery 中,您授予 users/roles(或授权视图)数据集级别的访问权限,而不是 views/table-level。我想解决的挑战是,当我有数百个 table 和视图以及许多不同的 roles/departments 时,如何在 bigquery 中管理访问控制,这些 roles/departments 应该可以访问跨所有部门共享的视图和仅用于一个特定的 role/department?
示例:假设我有一个源数据集,其中源 tables A->D 和每个 table 的三个视图根据数据 1->3 的敏感性公开不同的字段。另外,我有三个角色(蓝色、绿色、红色)。如果我可以管理 table 级别的访问权限,它将如下所示:
查看:角色
A1:蓝色、红色
A2:红色
A3:红色
B1:蓝色、绿色、红色
B2:绿色、红色
B3:红色
C1:绿色、红色
C2:绿色、红色
C3:红色
D1: 红色
D2:红色
D3: 红色
鉴于这些要求,我无法仅基于敏感度 (1-3) 或来源 (A-D) 创建数据集并基于此管理访问权限。我能看到满足此要求的唯一解决方案是为每个角色生成一个数据集。如果角色和视图的数量很少,这可以手动完成,但是当管理 10 个以上的角色和 50 个以上的视图时,它变得更具挑战性。
我能想到的唯一解决方案是 CI/CD 设置(云构建),其中 file/s 定义数据集(即角色)、依赖项和 DDL-statement/s。让 script/program 遍历 file/s 并生成视图并授予对源的访问权限(授权视图)。
示例文件:
{"roles":["crm_analyst", "admin", "customer_service_agent"],
"ddl":"CREATE VIEW `myproject.'{role}'.newview` AS SELECT column_1, column_2, column_3 FROM myproject.mydataset.myview",
"dependencies":"myproject.mydataset.myview"}
其他公司是如何解决这个问题的?已经迁移到 bigquery 的大型银行必须有大量的部门和不同的数据集敏感性。
与群组而非角色共享数据集。每人一组"role";红色、绿色和蓝色。创建只有视图的数据集。与观点分享来源dataset.tables。
RED_DATASET:
共享:RED_GROUP
观点:
A1-A3,B1-B3,C1-C3,D1-D3
BLUE_DATASET:
共享:BLUE_GROUP
观点:
A1,B1
GREEN_DATASET:
共享:GREEN_GROUP
观点:
B1-B2,C1-C2
请注意,B1 视图将拥有它的三个副本(每个 "view_dataset" 一个)并且由同一个查询定义。
这是关于视图访问控制的recommended practice。
我最终编写了一个 python 脚本,该脚本从 json 文件中读取视图定义,然后生成数据集和视图并提供正确的访问权限。该解决方案有点粗糙,可以使用依赖映射(当一个视图查询另一个视图时)而不是当前的解决方案迭代视图,直到生成所有视图或脚本不能再生成视图(依赖关系中断)。该脚本每组生成两个数据集,一个带有READER(后缀'_ro')和一个带有WRITER(后缀'_rw')以确保数据团队生成的视图不能被修改并且同时给小组一个沙箱。该组应该是一个电子邮件组,数据集的名称将是电子邮件地址的本地部分。该脚本由 google 云构建执行,并通过推送到我们的 github 存储库触发。
示例视图定义(路径:views/view_test.json)
{
"groups":["developers@datahem.org", "analysts@datahem.org"],
"sql":"SELECT * FROM `{project}.shared_views.test_view`"
}
生成以下数据集(访问)和视图:
analysts_ro (analysts@datahem.org:READER):
- view_test
analysts_rw (analysts@datahem.org:WRITER):
(empty)
developers_ro (developers@datahem.org:READER):
- view_test
developers_rw (developers@datahem.org:WRITER):
(empty)
shared_views (analysts_ro.view_test:None, developers_ro.view_test:None):
- test_view
我制作了 python script available on github as open source as part of datahem,请随意克隆、改进和用于您自己的目的。
另一种选择是设置行级访问并将所有视图放在同一数据集中。
模拟一个 access_control table(用户、用户组)用于示例目的:
SELECT 'userA@datahem.org' as user_name, ['developer','analyst'] as user_groups
UNION ALL
SELECT 'userB@datahem.org' as user_name, ['developer'] as user_groups
并创建一个具有行级访问控制的视图,方法是添加一个包含 user_groups 数组的静态列并与 access_control "table" 连接,其中至少有一个当前用户组匹配 allowed_groups:
SELECT c.* EXCEPT(allowed_groups) FROM (
SELECT OrderReference, Date, ['developer', 'analyst'] AS allowed_groups
FROM `project.dataset.orders`) as c
INNER JOIN (
SELECT user_name, user_group
FROM `project.access.access_control`, UNNEST(user_groups) as user_group
WHERE SESSION_USER() = user_name) g
ON g.user_group IN UNNEST(c.allowed_groups)
这是一个不错的解决方案,但它会向用户公开所有视图,即使用户无权访问它也是如此。此外,用户将能够 运行 查询视图 he/she 无权访问(产生成本)但不会得到任何结果。从可用性的角度(仅显示用户有权访问的视图)我们选择了上面标记的解决方案。
在 BigQuery 中,您授予 users/roles(或授权视图)数据集级别的访问权限,而不是 views/table-level。我想解决的挑战是,当我有数百个 table 和视图以及许多不同的 roles/departments 时,如何在 bigquery 中管理访问控制,这些 roles/departments 应该可以访问跨所有部门共享的视图和仅用于一个特定的 role/department?
示例:假设我有一个源数据集,其中源 tables A->D 和每个 table 的三个视图根据数据 1->3 的敏感性公开不同的字段。另外,我有三个角色(蓝色、绿色、红色)。如果我可以管理 table 级别的访问权限,它将如下所示:
查看:角色
A1:蓝色、红色
A2:红色
A3:红色
B1:蓝色、绿色、红色
B2:绿色、红色
B3:红色
C1:绿色、红色
C2:绿色、红色
C3:红色
D1: 红色
D2:红色
D3: 红色
鉴于这些要求,我无法仅基于敏感度 (1-3) 或来源 (A-D) 创建数据集并基于此管理访问权限。我能看到满足此要求的唯一解决方案是为每个角色生成一个数据集。如果角色和视图的数量很少,这可以手动完成,但是当管理 10 个以上的角色和 50 个以上的视图时,它变得更具挑战性。
我能想到的唯一解决方案是 CI/CD 设置(云构建),其中 file/s 定义数据集(即角色)、依赖项和 DDL-statement/s。让 script/program 遍历 file/s 并生成视图并授予对源的访问权限(授权视图)。 示例文件:
{"roles":["crm_analyst", "admin", "customer_service_agent"],
"ddl":"CREATE VIEW `myproject.'{role}'.newview` AS SELECT column_1, column_2, column_3 FROM myproject.mydataset.myview",
"dependencies":"myproject.mydataset.myview"}
其他公司是如何解决这个问题的?已经迁移到 bigquery 的大型银行必须有大量的部门和不同的数据集敏感性。
与群组而非角色共享数据集。每人一组"role";红色、绿色和蓝色。创建只有视图的数据集。与观点分享来源dataset.tables。
RED_DATASET: 共享:RED_GROUP 观点: A1-A3,B1-B3,C1-C3,D1-D3
BLUE_DATASET: 共享:BLUE_GROUP 观点: A1,B1
GREEN_DATASET: 共享:GREEN_GROUP 观点: B1-B2,C1-C2
请注意,B1 视图将拥有它的三个副本(每个 "view_dataset" 一个)并且由同一个查询定义。
这是关于视图访问控制的recommended practice。
我最终编写了一个 python 脚本,该脚本从 json 文件中读取视图定义,然后生成数据集和视图并提供正确的访问权限。该解决方案有点粗糙,可以使用依赖映射(当一个视图查询另一个视图时)而不是当前的解决方案迭代视图,直到生成所有视图或脚本不能再生成视图(依赖关系中断)。该脚本每组生成两个数据集,一个带有READER(后缀'_ro')和一个带有WRITER(后缀'_rw')以确保数据团队生成的视图不能被修改并且同时给小组一个沙箱。该组应该是一个电子邮件组,数据集的名称将是电子邮件地址的本地部分。该脚本由 google 云构建执行,并通过推送到我们的 github 存储库触发。
示例视图定义(路径:views/view_test.json)
{
"groups":["developers@datahem.org", "analysts@datahem.org"],
"sql":"SELECT * FROM `{project}.shared_views.test_view`"
}
生成以下数据集(访问)和视图:
analysts_ro (analysts@datahem.org:READER):
- view_test
analysts_rw (analysts@datahem.org:WRITER):
(empty)
developers_ro (developers@datahem.org:READER):
- view_test
developers_rw (developers@datahem.org:WRITER):
(empty)
shared_views (analysts_ro.view_test:None, developers_ro.view_test:None):
- test_view
我制作了 python script available on github as open source as part of datahem,请随意克隆、改进和用于您自己的目的。
另一种选择是设置行级访问并将所有视图放在同一数据集中。
模拟一个 access_control table(用户、用户组)用于示例目的:
SELECT 'userA@datahem.org' as user_name, ['developer','analyst'] as user_groups
UNION ALL
SELECT 'userB@datahem.org' as user_name, ['developer'] as user_groups
并创建一个具有行级访问控制的视图,方法是添加一个包含 user_groups 数组的静态列并与 access_control "table" 连接,其中至少有一个当前用户组匹配 allowed_groups:
SELECT c.* EXCEPT(allowed_groups) FROM (
SELECT OrderReference, Date, ['developer', 'analyst'] AS allowed_groups
FROM `project.dataset.orders`) as c
INNER JOIN (
SELECT user_name, user_group
FROM `project.access.access_control`, UNNEST(user_groups) as user_group
WHERE SESSION_USER() = user_name) g
ON g.user_group IN UNNEST(c.allowed_groups)
这是一个不错的解决方案,但它会向用户公开所有视图,即使用户无权访问它也是如此。此外,用户将能够 运行 查询视图 he/she 无权访问(产生成本)但不会得到任何结果。从可用性的角度(仅显示用户有权访问的视图)我们选择了上面标记的解决方案。