Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/cn/guides/56-security/data-protection/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"label": "数据保护策略"
}
418 changes: 418 additions & 0 deletions docs/cn/guides/56-security/data-protection/index.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import EEFeature from '@site/src/components/EEFeature';

动态脱敏策略在查询时对列值进行转换,帮助你按照角色控制谁能看到真实数据、谁只能看到脱敏后的结果。

## 适用场景

- **客服系统**:客服能看到订单记录,但客户身份证号显示为 `3201**********1234`。
- **数据分析**:分析师跑报表时,邮箱字段显示为 `***@***.com`,不影响聚合统计。
- **VARIANT 日志**:所有人能查日志,但 JSON 中的 `secret_key`、`token` 字段对非管理员不可见。
- **部分脱敏**:客服看到信用卡后四位 `****-****-****-5678` 用于核实身份。

如果你需要隐藏整行而非脱敏列值,请使用[行访问策略](/guides/security/data-protection/row-access-policy)。

## 脱敏策略如何工作

策略会在查询阶段读取 `current_role()` 等信息并决定返回值。
Expand Down Expand Up @@ -260,9 +269,67 @@ ELSE delete_by_keypath(val, 'nested:secret')
```
:::

## 脱敏策略 vs 行访问策略

| | 脱敏策略 | 行访问策略 |
|---|---|---|
| 作用范围 | 列级(转换值) | 表级(过滤行) |
| 返回类型 | 必须与列类型相同 | 固定为 BOOLEAN |
| 每表限制 | 每列一个 | 每表一个 |
| 影响的操作 | 仅 SELECT | SELECT、UPDATE、DELETE、MERGE |

同一列不能同时绑定脱敏策略和行访问策略。当你希望所有用户都能看到行但敏感字段被替换时,使用脱敏策略;当某些行应该对未授权用户完全不可见时,使用行访问策略。

## 限制与要求

- 一个列最多绑定一个脱敏策略。
- 同一列不能同时绑定脱敏策略和行访问策略。
- 策略的返回类型必须与目标列的数据类型匹配。
- 被脱敏策略保护的列不能直接 ALTER 或 DROP——需先执行 `UNSET MASKING POLICY`。
- 仍被表引用的策略不能 DROP。使用 `POLICY_REFERENCES()` 查找所有绑定关系。
- 不支持 `CREATE OR REPLACE MASKING POLICY`,需先 DROP 再重建。
- 脱敏策略不能应用于临时表、视图或 stream。
- 脱敏仅影响读取路径(SELECT)。INSERT、UPDATE、DELETE 操作的是真实值。
- 策略名称在脱敏策略和行访问策略之间全局唯一。
- 策略参数名在创建时会被规范化为小写。

## 最佳实践

### 使用 is_role_in_session() 而非 current_role()

`current_role()` 只检查当前活跃角色,用户可以通过 `SET ROLE` 切换到未受限角色绕过脱敏。`is_role_in_session()` 检查所有已授予角色,无法绕过。

```sql
-- 推荐
CASE WHEN is_role_in_session('managers') THEN val ELSE '*********' END

-- 避免:可通过 SET ROLE 绕过
CASE WHEN current_role() = 'managers' THEN val ELSE '*********' END
```

### 条件脱敏尽量少引用额外列

`USING` 子句中的每个列都会在运行时求值。如果脱敏逻辑只依赖调用者的角色,不要引入多余的条件列。

### 脱敏值保持类型一致

返回 `'***'` 替代 email 没问题,但如果下游有 `LENGTH()` 或 `LIKE` 判断,考虑返回固定格式如 `'***@***.com'`,避免破坏应用假设。

### VARIANT 列使用 object_delete

隐藏 JSON 中的特定 key 时,`object_delete(val, 'secret_key', 'token')` 比替换整个值更精确——其他字段仍然可查询。

### 先解绑再删除

`DROP MASKING POLICY` 在仍有列引用时会失败。先用 `POLICY_REFERENCES(POLICY_NAME => '<name>')` 查找所有绑定,逐一 `UNSET MASKING POLICY` 后再删除。

### 用受限角色测试

创建策略后,用 `SET ROLE` 切换到受限角色执行 SELECT 验证脱敏效果。不要只在 admin 角色下测试就认为完成了。

## 权限与参考

- 将 `CREATE MASKING POLICY`(通常授予 `*.*`)赋予负责创建或替换策略的角色,创建者会自动获得策略的 OWNERSHIP。
- 将 `CREATE MASKING POLICY`(通常授予 `*.*`)赋予负责创建策略的角色,创建者会自动获得策略的 OWNERSHIP。
- 需要在全局授予 `APPLY MASKING POLICY`,或针对单个策略授予 `APPLY ON MASKING POLICY <policy_name>`,角色才能使用 `ALTER TABLE` 设置或解除策略;拥有 OWNERSHIP 的角色也可以执行这些操作。
- 使用 `SHOW GRANTS ON MASKING POLICY <policy_name>` 审计哪些角色拥有 APPLY/OWNERSHIP。
- 延伸阅读:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import EEFeature from '@site/src/components/EEFeature';

行访问策略(Row Access Policy)通过在查询时过滤表中的行来保护数据。你可以集中定义行级谓词,并将其绑定到表上,确保用户只能看到满足策略条件的行。

## 适用场景

- **多租户 SaaS**:每个租户只能查到自己的数据,无需为每个租户建单独的表或视图。
- **区域隔离**:销售只能看自己负责区域的订单,管理层看全部。
- **时间窗口控制**:实时告警系统只能查最近 1 天,离线分析系统可查 7 天。
- **合规审计**:外部审计人员只能看到特定时间段的数据。

如果你需要所有用户都能看到行但敏感列值需要脱敏,请使用[脱敏策略](/guides/security/data-protection/masking-policy)。

:::note
Row Access Policy 当前为实验性功能。可通过 `SET enable_experimental_row_access_policy = 1` 在当前会话启用,或通过 `SET GLOBAL enable_experimental_row_access_policy = 1` 在账号范围启用。
:::
Expand Down Expand Up @@ -72,7 +81,7 @@ CREATE ROW ACCESS POLICY rap_engineering
AS (dept STRING)
RETURNS BOOLEAN ->
CASE
WHEN current_role() = 'admin' THEN true
WHEN IS_ROLE_IN_SESSION('admin') THEN true
WHEN dept = 'Engineering' THEN true
ELSE false
END;
Expand Down Expand Up @@ -403,7 +412,51 @@ ALTER TABLE employees DROP ALL ROW ACCESS POLICIES;
- `SELECT` 会被 Row Access Policy 过滤,只返回策略可见的行。
- `UPDATE`、`DELETE` 和 `MERGE` 在匹配目标行时会被 Row Access Policy 过滤。不可见的目标行不会被更新、删除或合并。
- 修改或删除受保护列前,需要先解除相关策略。
- 当前不支持 `CREATE OR REPLACE ROW ACCESS POLICY` 和 `ALTER ROW ACCESS POLICY`。
- 当前不支持 `CREATE OR REPLACE ROW ACCESS POLICY` 和 `ALTER ROW ACCESS POLICY`,需先 DROP 再重建。
- 策略名称在行访问策略和脱敏策略之间全局唯一。
- 策略参数名在创建时会被规范化为小写。
- Row Access Policy 不能应用于 ICE 类型数据库中的表。

## 最佳实践

### 使用 IS_ROLE_IN_SESSION() 而非 current_role()

`IS_ROLE_IN_SESSION()` 检查用户被授予的所有角色,包括 session 中激活的 secondary roles。用户无法通过 `SET ROLE` 绕过策略。`current_role()` 只检查当前活跃的单个角色,可以被规避。

```sql
-- 推荐:考虑角色继承
CASE
WHEN IS_ROLE_IN_SESSION('admin') THEN true
WHEN IS_ROLE_IN_SESSION('sales_apac') THEN region = 'APAC'
ELSE false
END

-- 避免:可通过 SET ROLE 绕过
CASE WHEN current_role() = 'admin' THEN true ELSE false END
```

### CASE 分支从宽到窄排列

CASE 表达式从上到下求值。把最宽松的条件放在最前面(如 admin 直接返回 true),可以为高权限角色短路求值,减少不必要的计算。

### Mapping table 与被保护表放在同一 database

如果策略引用了查找表(如角色到区域的映射表),将其存放在与被保护表相同的 database 中,简化权限管理,避免跨库访问问题。

### 用多个角色测试

绑定策略后,用不同用户/角色分别连接并对比查询结果。验证:
- Admin 角色能看到所有行
- 受限角色只能看到其被允许的子集
- 没有匹配条件的角色看到零行

### 用 account_admin 查看全量数据

需要检查所有行时(调试、审计),使用满足策略条件的角色(如 `account_admin`),而不是反复解绑再绑定策略。

### 先解绑再删除

`DROP ROW ACCESS POLICY` 在策略仍绑定到表时会失败。先用 `ALTER TABLE ... DROP ROW ACCESS POLICY` 或 `DROP ALL ROW ACCESS POLICIES` 解绑,再执行 DROP。

## 权限与参考

Expand Down
3 changes: 1 addition & 2 deletions docs/cn/guides/56-security/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ Databend 提供**企业级安全与可靠性功能**,全方位保护您的数
| [**审计追踪**](audit-trail.md) | 记录数据库活动 | 需要完整审计日志用于安全监控、合规检查或性能分析 |
| [**网络策略**](/guides/security/network-policy) | 限制网络访问 | 需要限制只有特定 IP 段才能连接,即使凭据正确也拒绝其他来源 |
| [**密码策略**](/guides/security/password-policy) | 设定密码规则 | 需要强制密码复杂度、定期轮换或账户锁定策略 |
| [**脱敏策略**](/guides/security/masking-policy) | 隐藏敏感信息 | 需要在保护敏感数据的同时允许授权用户访问 |
| [**行访问策略**](/guides/security/row-access-policy) | 动态过滤行 | 需要用户只能看到满足角色访问规则的行 |
| [**数据保护策略**](/guides/security/data-protection) | 行级和列级数据保护 | 需要行级过滤、列级脱敏或两者组合使用 |
| [**故障保护**](/guides/security/fail-safe) | 防止数据丢失 | 需要从 S3 兼容存储中恢复误删数据 |
| [**误操作恢复**](/guides/security/recovery-from-operational-errors) | 修复操作失误 | 需要恢复被删除的数据库/表,或撤销错误的数据修改 |
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import EEFeature from '@site/src/components/EEFeature';
## 语法

```sql
CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <policy_name> AS
CREATE MASKING POLICY [ IF NOT EXISTS ] <policy_name> AS
( <arg_name_to_mask> <arg_type_to_mask> [ , <arg_1> <arg_type_1> ... ] )
RETURNS <arg_type_to_mask> -> <expression_on_arg_name>
[ COMMENT = '<comment>' ]
Expand All @@ -40,7 +40,7 @@ CREATE [ OR REPLACE ] MASKING POLICY [ IF NOT EXISTS ] <policy_name> AS

| 权限 | 描述 |
|:-----|:-----|
| CREATE MASKING POLICY | 创建或替换脱敏策略时所需的权限(通常授予 `*.*`)。 |
| CREATE MASKING POLICY | 创建脱敏策略时所需的权限(通常授予 `*.*`)。 |

策略创建成功后,Databend 会自动将该策略的 OWNERSHIP 授予当前角色,方便与其他角色协同管理该策略。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import EEFeature from '@site/src/components/EEFeature';

## 相关主题

- [掩码策略](/guides/security/masking-policy)
- [掩码策略](/guides/security/data-protection/masking-policy)

:::note
Databend 中的掩码策略允许您在用户没有适当权限查询时,动态转换或混淆敏感数据以保护数据。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import EEFeature from '@site/src/components/EEFeature';

## 相关主题

- [行访问策略](/guides/security/row-access-policy)
- [行访问策略](/guides/security/data-protection/row-access-policy)
- [ALTER TABLE](/sql/sql-commands/ddl/table/alter-table#row-access-policy-操作)
- [POLICY_REFERENCES](/sql/sql-functions/table-functions/policy-references)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ title: POLICY_REFERENCES

另请参阅:

- [MASKING POLICY](/guides/security/masking-policy):定义列级脱敏规则,并可通过本函数查询引用关系。
- [ROW ACCESS POLICY](/guides/security/row-access-policy):定义行级过滤规则,并可通过本函数查询表绑定关系。
- [MASKING POLICY](/guides/security/data-protection/masking-policy):定义列级脱敏规则,并可通过本函数查询引用关系。
- [ROW ACCESS POLICY](/guides/security/data-protection/row-access-policy):定义行级过滤规则,并可通过本函数查询表绑定关系。

## 语法

Expand Down
3 changes: 3 additions & 0 deletions docs/en/guides/56-security/data-protection/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"label": "Data Protection"
}
Loading
Loading