在实际业务处理过程中,用户可能会同时具备多个项目的访问权限,此时会存在数据在项目间流转的安全问题。MaxCompute提供了数据保护机制,支持对数据流出行为进行控制,为项目数据的安全性提供保障。本文为您介绍MaxCompute的数据保护机制以及开启数据保护机制后数据的流出策略。

背景信息

部分公司对数据安全非常敏感,例如,只允许员工在公司内部进行操作、禁用公司所有电脑上的USB存储接口。这样做的目的是禁止员工将敏感数据泄漏出去。在MaxCompute项目中,也会存在用户将数据流出到项目之外的安全问题。

假设用户Alice可以同时访问Project1和Project2,Alice拥有访问Project1.table1的Select权限,同时也拥有在Project2中CreateTable的权限。在该情况下,如果未设置任何数据保护机制,Alice可以执行如下语句将Project1.table1的数据流出到Project2中,该操作存在数据泄露风险。

create table project2.table2 as select * from project1.table1;

基于上述示例可知,同时在多个MaxCompute项目中拥有访问权限的用户,可以执行在权限范围内允许的跨项目数据操作来流出项目的数据。MaxCompute已提供数据保护机制能力,如果项目中的数据敏感度很高,则需要项目所有者自行设置数据保护机制。

MaxCompute项目的数据保护机制默认为关闭状态。项目所有者可以在项目中执行set projectProtection=true;命令开启数据保护机制,项目中的数据流向会得到控制,数据只能流入,不能流出。

注意事项

开启数据保护机制后,您需要注意:
  • 跨项目的数据访问操作将失效,因为该操作违背了数据保护机制。如果需要打破机制,例如允许部分数据流出到其他项目,MaxCompute提供了数据流出策略一:设置Exception Policy数据流出策略二:设置TrustedProject两种方案供您选择。
  • 数据保护机制是对数据流向的控制,而不是对数据访问权限的控制。只有在用户具备数据访问权限的前提下,控制数据流向才有意义。
  • 基于Package跨项目访问资源机制与数据保护机制是正交的(相互独立),但在功能上是相互制约的。在MaxCompute中,Package资源分享优先于数据保护机制。即如果某个对象已通过Package方式为其他项目用户授予访问权限,那么该对象不受数据保护机制的限制。

数据流出策略一:设置Exception Policy

项目所有者需要提前规划Exception Policy,允许指定用户将指定对象的数据流出至指定项目,所有符合Exception Policy中描述的情形都可以打破数据保护机制。

设置方法
在开启项目数据保护机制的同时,配置Exception Policy。完成配置后,您可以通过show SecurityConfiguration;命令查看Exception Policy信息。设置Exception Policy的命令如下。
set ProjectProtection=true with exception <policyfile>;
policyfile为Exception Policy文件,内容格式如下,您需要将该文件以TXT格式保存在MaxCompute客户端安装路径的bin目录下。
    {
    "Version": "1",
    "Statement":
    [{
        "Effect":"Allow",
        "Principal":"<Principal>",
        "Action":["odps:<Action1>[, <Action2>, ...]"],
        "Resource":"acs:odps:*:<Resource>",
        "Condition":{
            "StringEquals": {
                "odps:TaskType":["<Tasktype>"]
            }
        }
    }]
    }
参数 说明
Effect 固定取值为Allow,表示允许数据流出。
Principal 表示允许执行数据流出操作的阿里云账号或RAM用户账号。
Action 表示允许执行的数据流出操作。各类型对象的操作取值信息,请参见权限一览表
Resource 表示允许数据流出的项目及对象。格式为projects/<project_name>/{tables|resources|functions|instances}/<name>更多对象取值信息,请参见权限一览表
Tasktype 表示允许执行的作业类型。取值可以为DT(Tunnel)、SQL、MapReduce。
配置样例
--开启数据保护机制并设置Exception Policy。policy_file已存储在MaxCompute客户端安装路径的bin目录下。
set ProjectProtection=true with exception policy_file;  
--policy_file内容如下。
{
    "Version": "1",
    "Statement":
    [{
        "Effect":"Allow",
        "Principal":"ALIYUN$Alice@aliyun.com",
        "Action":["odps:Select"],
        "Resource":"acs:odps:*:projects/project_test/tables/table_test",
        "Condition":{
            "StringEquals": {
                "odps:TaskType":["DT", "SQL"]
            }
        }
    }]
    }

该Exception Policy样例表示允许Alice可以通过SQL作业对表project_test.table_test执行SELECT操作时,将数据流出到project_test项目之外。

说明 如果Alice本身没有表project_test.table_test的SELECT权限,即使设置了Exception Policy,Alice仍然无法导出数据。
注意事项
设置Exception Policy可能存在TOCTOU(Time-of-Check to Time-of-Use)数据泄露问题(即Race Condition问题):
  • 问题描述

    假设,用户的数据流出流程如下:

    1. (TOC阶段)用户A向项目所有者申请导出表t1的数据。项目所有者对t1的数据敏感程度进行评估,同意后通过Exception Policy设置A可以导出t1的数据。
    2. 在用户A导出t1的数据前,其他用户修改了t1的内容,将敏感数据写入了t1中。
    3. (TOU阶段)用户A将t1的数据导出。但是,此时导出的t1并不是项目所有者审查过的t1,t1中包含了敏感数据。
  • 解决措施

    为了防止出现TOCTOU问题,对于用户申请导出的表,建议项目所有者确保没有任何其他用户能对该表执行更新(Update)操作或重建同名表操作(Drop + CreateTable)。在上述示例中,为防止出现TOCTOU问题,建议项目所有者在第一步中创建表t1的一个快照,设置Exception Policy时使用这个快照,并且不要为任何用户授予Admin角色。

数据流出策略二:设置TrustedProject

如果当前项目处于数据保护状态,当需要支持向目标项目执行数据流出操作时,项目所有者可以将目标项目设置为当前项目的TrustedProject,则此行为不会被视为触犯数据保护机制。如果多个项目之间两两互相设置为TrustedProject,这些项目会形成一个TrustedProject Group,数据可以在TrustedProject Group内流转,但禁止流出到TrustedProject Group之外。

设置方法
项目所有者可以通过如下命令管理信任项目:
  • 在当前项目中添加一个TrustedProject。
     add trustedproject <project_name>;               
  • 从当前项目中移除一个TrustedProject。
     remove trustedproject <project_name>;            
  • 查看当前项目的所有TrustedProject。
     list trustedprojects;                  

实践建议

如果要严格禁止数据从项目流出,在设置set projectProtection=true;之后,项目所有者还需要检查如下配置:
  • 执行list trustedprojects; 命令,确保项目中没有添加TrustedProject。如果有TrustedProject,则需要评估可能存在的风险,对不需要的TrustedProject执行remove trustedproject <project_name>;命令进行删除。
  • 执行show packages; 命令,确保项目中没有使用Package分享数据。如果有Package,则需要确保Package中没有敏感数据,或者对不需要的Package执行delete package <package_name>;命令进行删除。