基于标签的安全(LabelSecurity)是项目空间级别的一种强制访问控制策略(Mandatory Access Control, MAC),它的引入是为了让项目空间管理员能更加灵活地控制用户对列级别敏感数据的访问。

理解MaxCompute中的MAC与DAC差异

在MaxCompute中,强制访问控制机制(MAC)独立于自主访问控制机制(DAC)。为了便于理解,MAC与DAC的关系可以用下面的例子来做个类比。

对于一个国家来说(类比MaxCompute的一个项目空间),这个国家公民要想开车(类比读数据操作),必须先申请获得驾照(类比申请SELECT权限)。这些就属于DAC考虑的范畴。

但由于这个国家交通事故率一直居高不下,于是该国新增了一条法律:禁止酒驾。此后,所有想开车的人除了持有驾照之外,还必须不能喝酒。类比MaxCompute,这个禁止酒驾就相当于禁止读取敏感度高的数据。这就属于MAC考虑的范畴。

数据的敏感等级分类

LabelSecurity需要将数据和访问数据的人进行安全等级划分。在政府和金融机构,一般将数据的敏感度标记分为四类:0级 (不保密, Unclassified), 1级 (秘密, Confidential), 2级 (机密, Sensitive), 3级 (高度机密, Highly Sensitive)。MaxCompute也遵循这一分类方法。ProjectOwner需要定义明确的数据敏感等级和访问许可等级划分标准,默认时所有用户的访问许可等级为0级,数据安全级别默认为0级。

LabelSecurity对敏感数据的粒度可以支持列级别,管理员可以对表的任何列设置敏感度标记(Label),一张表可以由不同敏感等级的数据列构成。

对于view,也支持和表同样的设置,即管理员可以对view设置label等级,view的等级和它对应的基表的label等级是独立的,在view创建时,默认的等级也是0。

LabelSecurity默认安全策略

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

项目空间中的LabelSecurity安全机制默认是关闭的,ProjectOwner可以自行开启。

LabelSecurity安全机制一旦开启,上述的默认安全策略将被强制执行。当用户访问数据表时,除了必须拥有Select权限外,还必须获得读取敏感数据的相应许可等级。或者说,通过LabelSecurity只是通过CheckPermission的必要而非充分条件。

LabelSecurity操作

  • LabelSecurity机制的开/关
     Set LabelSecurity=true|false; 
       --开启或关闭LabelSecurity机制,默认为false。
       --此操作必须由ProjectOwner完成,其他操作则可以由Admin角色完成。
  • 给user设置安全许可标签
     SET LABEL <number> TO USER <username>; -- number取值范围:[0, 9],该操作只能由ProjectOwner或Admin角色完成
     --举例:
     ADD USER aliyun$yunma@aliyun.com; --添加用户,默认的安全许可标签为0级
     ADD USER ram$yunma@aliyun.com:Allen;--添加yunma@aliyun.com的RAM子账号用户Allen
     SET LABEL 3 TO USER aliyun$yunma@aliyun.com; 
       --设置yunma的安全许可标签为3级,他能访问敏感等级不超过3级的数据
     SET LABEL 1 TO USER ram$yunma@aliyun.com:Allen;  
       --设置yunma的子账号Allen的安全许可标签为1级,他能访问敏感等级不超过1级的数据
    
  • 给数据设置敏感等级标签
     SET LABEL <number> TO TABLE tablename[(column_list)]; -- number取值范围:[0, 9],该操作只能由ProjectOwner或Admin角色完成
     --举例:
     SET LABEL 1 TO TABLE t1; --设置表t1的label为1级
     SET LABEL 2 TO TABLE t1(mobile, addr); --将t1的mobile,addr两列的label设置为2级
     SET LABEL 3 TO TABLE t1; --设置表t1的label为3级. 注意此时mobile,addr两列的label仍为2级
    
    说明
    从上面例子可以看出,显式地对列设置的标签会覆盖对表设置的标签,而不会考虑标签设置的顺序以及敏感等级的高低。
  • 显式授权低级别用户访问特定的高敏感级数据表
     --授权:
     GRANT LABEL <number> ON TABLE <tablename>[(column_list)] TO USER <username> [WITH EXP <days>]; --默认过期时间是180天
     --撤销授权:
     REVOKE LABEL ON TABLE <tablename>[(column_list)] FROM USER <username>;
     --清理过期的授权:
     CLEAR EXPIRED GRANTS;
     --举例:
     GRANT LABEL 2 ON TABLE t1 TO USER ram$yunma@aliyun.com:Allen WITH EXP 1; --显式授权Allen访问t1表中敏感度不超过2级的数据,授权有效期为1天
     GRANT LABEL 3 ON TABLE t1(col1, col2) TO USER ram$yunma@aliyun.com:Allen WITH EXP 1; --显式授权alice访问t1(col1, col2)中敏感度不超过3级的数据,授权有效期为1天
     REVOKE LABEL ON TABLE t1 FROM USER ram$yunma@aliyun.com:Allen; --撤销alice对t1表的敏感数据访问
    
    说明
    目前取消用户对table的label权限,会同时取消该用户对table字段的label的权限
  • 查看一个用户能访问哪些敏感数据集
     SHOW LABEL [<level>] GRANTS [FOR USER <username>]; 
       --省略 [FOR USER <username>]时,查看当前用户所能访问的敏感数据集
       --省略<level>时,将显示所有label等级的授权;若指定<level>,则只显示指定等级的授权
    
  • 查看一个敏感数据表能被哪些用户访问
     SHOW LABEL [<level>] GRANTS ON TABLE <tablename>;
       --显示指定table上的Label授权
    
  • 查看一个用户对一个数据表的所有列级别的Label权限
     SHOW LABEL [<level>] GRANTS ON TABLE <tablename> FOR USER <username>;
       --显示指定用户对指定table上列级别的Label授权
    
  • 查看一个表中所有列的敏感等级
    DESCRIBE <tablename>;
    
  • 控制package安装者对package中敏感资源的许可访问级别
     ALLOW PROJECT <prjName> TO INSTALL PACKAGE <pkgName> [USING LABEL <number>]; 
       --由package创建者授权,授予package安装者对package中敏感资源的许可访问级别
    
    说明
    • 省略[USING LABEL <number>]时,默认为0级,即只可以访问非敏感数据。
    • 跨项目空间访问敏感数据时,package安装者的项目空间中的所有用户都将使用此命令中许可的访问级别

LabelSecurity应用场景示例

  • 限制项目空间中所有非Admin用户对一张表的某些敏感的列的读访问

    场景说明:user_profile是某项目空间中的一张含有敏感数据的表,它包含有100列,其中有5列包含敏感数据:id_card, credit_card, mobile, user_addr, birthday. 当前的DAC机制中已经授权了所有用户对该表的Select操作。ProjectOwner希望除了Admin之外,所有用户都不允许访问那5列敏感数据。

    ProjectOwner操作步骤如下:
     set LabelSecurity=true; 
       --开启LabelSecurity机制
     set label 2 to table user_profile(mobile, user_addr, birthday); 
       --将指定列的敏感等级设置为2
     set label 3 to table user_profile(id_card, credit_card); 
       --将指定列的敏感等级设置为3
    说明
    以上操作执行之后,所有非Admin用户都将无法访问那5列数据。如果有人因业务需要确实要访问这些敏感数据,那么需要ProjectOwner或Admin的授权。
    Alice是项目空间中的一员,由于业务需要,她要申请访问user_profile的mobile列的数据,需要访问1周时间。项目空间管理员操作步骤如下:
    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; 
       --不允许对象创建者授权对象给其他用户