4. 系统定义角色与自定义角色
Snowflake 的访问控制体系建立在 RBAC(基于角色的访问控制)之上。理解这一点非常关键:在 Snowflake 中,权限从不直接授予用户,而是先授予角色,再把角色授予用户。用户通过“激活”某个角色来获得该角色所携带的权限。因此,角色体系的设计质量,直接决定了整个账户权限模型是否清晰、可维护、可审计。
Snowflake 预置了一组系统定义角色(System-Defined Roles),它们构成了权限管理的骨架。这些角色不能删除,也不能被重命名,但可以被授予给其他角色或用户。掌握它们的职责边界,是设计自定义角色体系的前提。
系统定义角色的职责分工
系统角色中最核心的是五个:ACCOUNTADMIN、SYSADMIN、SECURITYADMIN、USERADMIN 和 PUBLIC。它们之间存在明确的层级与制衡关系。
- ACCOUNTADMIN:账户的最高权限角色,拥有账户级的所有管理能力,包括计费、复制、资源监控、创建其他管理角色等。它同时被授予 SYSADMIN 和 SECURITYADMIN,因此天然具备这两条线的全部权限。最佳实践是:日常操作不要使用 ACCOUNTADMIN,仅在账户级配置、故障恢复等场景下临时激活。
- SYSADMIN:负责“对象与资源”这条线。所有数据库、模式、表、视图、仓库(Warehouse)等对象,理想情况下都应由 SYSADMIN 或其下级角色创建和持有。这样对象所有权集中,便于统一管理。
- SECURITYADMIN:负责“权限与用户”这条线。它可以管理 GRANT(授权),包括授予和撤销角色、管理网络策略等。它拥有 MANAGE GRANTS 权限,是权限治理的核心角色。
- USERADMIN:专注于用户和角色的创建与维护,可以创建用户、创建角色、授予角色,但不具备管理对象权限的能力。它适合交给 HR 或 IT 运维团队使用。
- PUBLIC:每个用户自动拥有的角色,用于存放“所有用户都应具备”的最小权限。默认情况下 PUBLIC 几乎无权限,应保持其精简。
这五个角色并非平级。ACCOUNTADMIN 位于顶端,SYSADMIN 与 SECURITYADMIN 分列两条主线,USERADMIN 从属于 SECURITYADMIN,PUBLIC 则是最底层的公共角色。这种“双线制衡”的设计,使得对象管理与权限管理相互独立,避免单一角色权力过大。
为什么需要自定义角色
系统角色只提供了“管理骨架”,它们并不了解业务。真实场景中,不同团队需要不同的数据访问范围:分析师需要读取销售数据但不能修改,ETL 工程师需要写入原始层但不能访问财务明细,数据科学家需要读取特征表但不能删除。如果直接把这些权限授予 SYSADMIN,就会导致权限泛滥、无法审计。因此,必须为每条业务线设计专门的自定义角色。
设计自定义角色体系时,推荐遵循“功能角色 + 访问角色”的双层结构。功能角色(Functional Role)描述“做什么”,例如 ANALYST_RO、ETL_RO、DATA_SCIENTIST_RO;访问角色(Access Role)描述“能访问什么”,例如 SALES_READ_RO、FINANCE_READ_RO、RAW_WRITE_RO。功能角色继承访问角色,用户只被授予功能角色。这样当某个数据源的访问策略变化时,只需调整访问角色,所有继承它的功能角色自动生效,无需逐个修改用户。
自定义角色体系设计示例
假设某零售公司有销售分析、财务分析和数据工程三条业务线,可以设计如下角色结构。以下 SQL 为教学示例,参数与命名可根据实际调整。
-- 1. 创建访问角色(描述可访问的数据范围)
CREATE ROLE SALES_READ_RO;
CREATE ROLE FINANCE_READ_RO;
CREATE ROLE RAW_WRITE_RO;
-- 2. 创建功能角色(描述业务职能)
CREATE ROLE ANALYST_RO;
CREATE ROLE FINANCE_ANALYST_RO;
CREATE ROLE ETL_RO;
-- 3. 功能角色继承访问角色
GRANT ROLE SALES_READ_RO TO ROLE ANALYST_RO;
GRANT ROLE FINANCE_READ_RO TO ROLE FINANCE_ANALYST_RO;
GRANT ROLE RAW_WRITE_RO TO ROLE ETL_RO;
-- 4. 将功能角色挂到 SYSADMIN 之下,保持对象管理线统一
GRANT ROLE ANALYST_RO TO ROLE SYSADMIN;
GRANT ROLE FINANCE_ANALYST_RO TO ROLE SYSADMIN;
GRANT ROLE ETL_RO TO ROLE SYSADMIN;
-- 5. 授予对象权限给访问角色
GRANT USAGE ON DATABASE RETAIL_DB TO ROLE SALES_READ_RO;
GRANT USAGE ON SCHEMA RETAIL_DB.SALES TO ROLE SALES_READ_RO;
GRANT SELECT ON ALL TABLES IN SCHEMA RETAIL_DB.SALES TO ROLE SALES_READ_RO;
GRANT USAGE ON WAREHOUSE ANALYST_WH TO ROLE ANALYST_RO;
这段脚本体现了几个关键原则。第一,访问角色只持有对象权限,功能角色只负责“继承”和“被授予用户”,职责分离。第二,所有自定义角色最终都挂到 SYSADMIN 之下,保证对象所有权链条完整,未来 SYSADMIN 可以统一管理所有下级对象。第三,仓库(Warehouse)的使用权限授予功能角色而非访问角色,因为仓库是计算资源,与数据访问范围无关。
角色命名与治理建议
角色命名应具备自解释性。推荐使用“业务域_职能_后缀”的格式,例如 SALES_ANALYST_RO、FINANCE_READ_RO、ETL_RAW_WRITE_RO。后缀统一使用 _RO 表示只读、_RW 表示读写、_ADMIN 表示管理,便于快速识别权限级别。
治理层面,应定期执行以下检查:确认没有用户直接持有 ACCOUNTADMIN;确认所有自定义角色都挂在 SYSADMIN 或 SECURITYADMIN 之下;确认 PUBLIC 角色没有被授予敏感对象权限;确认离职或转岗用户的角色授予已被回收。Snowflake 提供 ACCOUNT_USAGE 中的 GRANTS_TO_ROLES、GRANTS_TO_USERS 等视图,可以编写查询来审计这些关系。
总结来说,系统定义角色提供了账户管理的骨架,自定义角色则承载了业务权限的细节。设计时把握三条主线:对象线归 SYSADMIN,权限线归 SECURITYADMIN,用户线归 USERADMIN;自定义角色采用“功能角色继承访问角色”的双层结构,并统一挂到 SYSADMIN 之下。这样构建出来的角色体系,既符合 Snowflake 的最佳实践,也能在业务扩张时保持可维护、可审计。