MaxCompute通过基于标签的安全策略(LabelSecurity)实现用户对列级别敏感数据的访问。LabelSecurity是项目级别的一种强制访问控制策略。

DAC与MAC

自主访问控制策略DAC(Discretionary Access Control):由客体的属主对自己的客体进行管理,由属主决定是否将自己的客体访问权或部分访问权授予其他主体,这种控制方式是自主的。即在自主访问控制下,用户可以按自己的意愿,有选择地将权限授予给其他用户。

强制访问控制策略MAC(Mandatory Access Control):一种由系统约束的访问控制,目标是限制主体对对象执行某种操作的能力。

在MaxCompute中,强制访问控制机制MAC独立于自主访问控制机制DAC。

数据的敏感等级分类

LabelSecurity需要将数据和访问数据的人进行安全等级划分。

在政府和金融机构,通常将数据的敏感度标记(Label)分为四类,0级(不保密,Unclassified)、1级(秘密,Confidential)、2级(机密,Sensitive)、3级(高度机密,Highly Sensitive)。

MaxCompute也遵循这一分类方法。项目所有者(Project Owner)需要定义明确的数据敏感等级和访问许可等级划分标准。默认情况下所有用户的访问许可等级为0级,数据安全级别为0级。

LabelSecurity对敏感数据的支持如下:
  • 最小支持粒度为列级别。
  • 支持管理员对表的任何列设置敏感度标记,一张表可以由不同敏感等级的数据列构成。
  • 支持管理员对视图设置敏感度标记。视图的等级和它对应的基表的敏感度标记等级是独立的。视图创建时,默认的等级也是0。

默认安全策略

在对数据和用户分别设置安全等级标记之后,基于标签的默认安全策略如下:
  • No-ReadUp:不允许用户读取敏感等级高于用户等级的数据,除非有显式授权。
  • Trusted-User:允许用户写任意等级的数据,新创建的数据默认为0级(不保密)。
说明
  • 在一些传统的强制访问控制系统中,为了防止数据在项目内部被任意分发,通常还支持更多复杂的安全策略。例如,不允许用户写敏感等级不高于用户等级的数据(No-WriteDown)。但在MaxCompute平台中,考虑到项目管理员对数据敏感等级的管理成本,默认安全策略并不支持No-WriteDown。如果项目管理员有类似需求,可以通过修改项目安全配置(Set ObjectCreatorHasGrantPermission=false)以达到控制目的。
  • 为了控制数据在不同项目之间的流动,您可以将项目设置为受保护状态(ProjectProtection)。设置之后,只允许用户在项目内访问数据,有效防止数据流出到项目之外。详情请参见项目空间的数据保护

项目中的LabelSecurity安全机制默认是关闭的,Project Owner可以自行开启。LabelSecurity安全机制一旦开启,上述的默认安全策略将被强制执行。当用户访问数据表时,除了必须拥有SELECT权限外,还必须获得读取敏感数据的相应许可等级。

LabelSecurity操作

  • 开启LabelSecurity安全机制,默认情况下为False。该操作必须由Project Owner完成。
    Set LabelSecurity=true|false; 
  • 为用户设置安全许可标签。
    该操作只能由Project Owner或Admin角色完成。number取值范围为[0, 9]。
    SET LABEL <number> TO [USER|ROLE] <name>;
    示例如下。
    --添加云账号用户yunma,默认的安全许可标签为0级。
    ADD USER aliyun$yunma@aliyun.com;
    --添加yunma@aliyun.com的RAM子账号用户Allen。 
    ADD USER ram$yunma@aliyun.com:Allen;
    --设置yunma的安全许可标签为3级,他能访问敏感等级不超过3级的数据。 
    SET LABEL 3 TO USER aliyun$yunma@aliyun.com; 
    --设置yunma的子账号Allen的安全许可标签为1级,他能访问敏感等级不超过1级的数据。
    SET LABEL 1 TO USER ram$yunma@aliyun.com:Allen; 
  • 给数据设置敏感等级标签。

    该操作只能由Project Owner或Admin角色完成。number取值范围为[0, 9]。

    SET LABEL <number> TO TABLE tablename(column_list);
    示例如下。
    --设置表t1的label为1级。
    SET LABEL 1 TO TABLE t1; 
    --将t1的mobile,addr两列的label设置为2级。
    SET LABEL 2 TO TABLE t1(mobile, addr); 
    --设置表t1的label为3级。注意此时mobile,addr两列的label仍为2级。
    SET LABEL 3 TO TABLE t1; 
    说明 显式地对列设置的标签会覆盖对表设置的标签,与标签设置的顺序以及敏感等级的高低无关。
  • 显式授权低级别用户访问高敏感级数据表。
    • 授权低级别用户访问高敏感级数据表。 不指定WITH EXP <days>时,默认过期时间是180天。
      GRANT LABEL <number> ON TABLE <tablename>[(column_list)] TO [USER|ROLE] <name> [WITH EXP <days>];
    • 撤销授权。
      REVOKE LABEL ON TABLE <tablename>[(column_list)] FROM [USER|ROLE] <name>;
    • 清理过期的授权。
      CLEAR EXPIRED GRANTS;
    示例如下。
    --显式授权Allen访问t1表中敏感度不超过2级的数据,授权有效期为1天。
    GRANT LABEL 2 ON TABLE t1 TO USER ram$yunma@aliyun.com:Allen WITH EXP 1; 
    --显式授权alice访问t1(col1, col2)中敏感度不超过3级的数据,授权有效期为1天。
    GRANT LABEL 3 ON TABLE t1(col1, col2) TO USER ram$yunma@aliyun.com:Allen WITH EXP 1; 
    --撤销alice对t1表的敏感数据访问。
    REVOKE LABEL ON TABLE t1 FROM USER ram$yunma@aliyun.com:Allen; 
    说明 取消用户对表的label权限,会同时取消该用户对表字段的label的权限。
  • 查看指定用户可以访问的敏感数据集。
    SHOW LABEL [<level>] GRANTS [FOR USER <username>]; 
    参数说明:
    • FOR USER <username>:指定查询用户。省略此参数时,默认查看当前用户所能访问的敏感数据集。
    • <level>:指定查询等级。省略此参数时,将显示所有label等级的授权;如果指定此参数,则只显示指定等级的授权。
  • 查看允许访问指定敏感数据表的用户。
    SHOW LABEL [<level>] GRANTS ON TABLE <tablename>;
  • 查看指定用户对一个数据表的所有列级别的Label权限。
    SHOW LABEL [<level>] GRANTS ON TABLE <tablename> FOR USER <username>;
  • 查看一个表中所有列的敏感等级。
    DESCRIBE <tablename>;
  • 控制Package安装者对Package中敏感资源的许可访问级别。 此命令需要Package创建者执行。
    ALLOW PROJECT <prjName> TO INSTALL PACKAGE <pkgName> [USING LABEL <number>]; 
    命令说明如下:
    • [USING LABEL <number>]:指定访问数据敏感等级。不指定时,默认为0级,即只可以访问非敏感数据。
    • 跨项目访问敏感数据时,package安装者所在项目中的所有用户都将使用此命令中许可的访问级别。

LabelSecurity应用场景示例

  • 限制项目中所有非Admin角色的用户对指定表中敏感列的访问。

    假设user_profile是某项目中的一张含有敏感数据的表,它包含有100列,其中id_card、credit_card、mobile、user_addr、birthday5列包含敏感数据。当前已经授权了所有用户对该表的SELECT操作。Project Owner希望除了拥有Admin角色之外的其他用户都不被允许访问敏感数据。

    Project Owner执行如下命令进行设置。 执行下述命令后,所有非Admin角色的用户都将无法访问敏感数据。如果因业务需要确实要访问这些敏感数据,则需要获得Project Owner或Admin角色用户的授权。
    --开启LabelSecurity机制。
    set LabelSecurity=true; 
    --将指定列的敏感等级设置为2。
    set label 2 to table user_profile(mobile, user_addr, birthday); 
    --将指定列的敏感等级设置为3。
    set label 3 to table user_profile(id_card, credit_card); 
    Alice是项目中的一员,由于业务需要,她要申请访问user_profile的mobile列的数据,访问时间为1周。项目管理员需执行如下命令授权Alice的访问权限。
    GRANT LABEL 2 ON TABLE user_profile TO USER ALIYUN$alice@aliyun.com WITH EXP 7;
    说明 敏感等级为2的数据一共有三列:mobile,user_addr,birthday。当上述授权成功后,Alice将有权限访问这三列数据,但此处存在轻微地过度授权。管理员应通过合理设置数据列的敏感度,避免过度授权。
  • 限制项目中已获得敏感数据访问许可的用户在项目内对敏感数据的复制与传播。

    在上一个示例中,Alice由于业务需要而获得了等级为2的敏感数据的访问权限。但管理员仍然担心Alice可能会将user_profile表中的敏感等级为2的那些数据复制到她自己新建的另一张表user_profile_copy中,从而进一步将user_profile_copy表自主授权给Bob访问。因此需要限制Alice对敏感数据的复制与传播。

    考虑到安全易用性和管理成本,LabelSecurity的默认安全策略允许WriteDown,即允许用户向敏感等级不高于用户等级的数据列写入数据,因此MaxCompute还无法从根本上解决此问题。但这里可以限制用户的自主授权行为,即允许对象创建者只能访问自己创建的数据,而不允许自主授权该对象给其他用户。操作如下。
    --允许对象创建者操作对象。
    SET ObjectCreatorHasAccessPermission=true; 
    --不允许对象创建者授权对象给其他用户。
    SET ObjectCreatorHasGrantPermission=false;