📣
TiDB Cloud Premium 开放公测中。为企业级工作负载提供无限扩展、即时弹性伸缩和高级安全保障。此页面由 AI 自动翻译,英文原文请见此处。

数据保护策略



TiDB Cloud Lake 在查询时保护敏感数据,而不会更改存储的值:

策略它的作用
脱敏策略转换列值——未授予权限的用户看到的是脱敏数据
行访问策略过滤整行——未授予权限的用户永远看不到这些行

两者对应用程序都是透明的:无需修改代码,无需额外视图,无需复制数据。

选择合适的策略

场景用途
隐藏整行行访问
保留该行,但对某一列脱敏脱敏
不同角色看到同一列的不同精度脱敏
多租户 / 区域隔离行访问
按角色进行时间窗口控制行访问
隐藏 JSON / VARIANT 中的键脱敏
行隔离 + 列脱敏两者都用(但不能用于同一列)

示例:一个包含 phone、amount 和 region 的 orders 表。

要求策略
支持团队只能看到其所在 region基于 region 的行访问
分析师看到 138****1234基于 phone 的掩码
管理员看到所有内容通过两种策略的角色

它们如何协同工作

Query → Row Access Policy filters rows → Masking Policy transforms surviving columns → Result returned

行过滤先执行。掩码仅应用于剩余的行。

掩码行访问
作用域列值整行
返回类型与列类型匹配BOOLEAN
限制每列一个每表一个
影响SELECTSELECT, UPDATE, DELETE, MERGE
存储的数据 / INSERT不变 / 不过滤不变 / 不过滤

同一张表可以同时使用两者。同一个 column 不能同时绑定到两者。

-- Rows: sales only see their region CREATE ROW ACCESS POLICY rap_region AS (r STRING) RETURNS BOOLEAN -> CASE WHEN is_role_in_session('admin') THEN true ELSE is_role_in_session(r) END; ALTER TABLE customers ADD ROW ACCESS POLICY rap_region ON (region); -- Columns: non-HR see redacted SSN CREATE MASKING POLICY mask_ssn AS (val STRING) RETURNS STRING -> CASE WHEN is_role_in_session('hr') THEN val ELSE '***-**-****' END; ALTER TABLE customers MODIFY COLUMN ssn SET MASKING POLICY mask_ssn;

端到端:职责分离

将 RBAC 与这两种策略结合使用,使创建者、应用者和读取者彼此分离。

角色工作可见内容
security_admin创建 / 拥有策略没有表 SELECT 权限
data_engineer拥有表,附加策略所有行,原始 phone
analyst_apac分析 APACAPAC 行,phone 已脱敏
support_global全局支持所有行,原始 phone
-- account_admin: roles, users, CREATE privileges CREATE ROLE security_admin; CREATE ROLE data_engineer; CREATE ROLE analyst_apac; CREATE ROLE support_global; CREATE USER sec_user IDENTIFIED BY 'password123'; CREATE USER eng_user IDENTIFIED BY 'password123'; CREATE USER analyst_user IDENTIFIED BY 'password123'; CREATE USER support_user IDENTIFIED BY 'password123'; GRANT ROLE security_admin TO USER sec_user; GRANT ROLE data_engineer TO USER eng_user; GRANT ROLE analyst_apac TO USER analyst_user; GRANT ROLE support_global TO USER support_user; GRANT CREATE DATABASE ON *.* TO ROLE data_engineer; GRANT CREATE MASKING POLICY ON *.* TO ROLE security_admin; GRANT CREATE ROW ACCESS POLICY ON *.* TO ROLE security_admin; GRANT GRANT ON *.* TO ROLE security_admin; -- data_engineer: table ownership SET ROLE data_engineer; CREATE DATABASE ecommerce; CREATE TABLE ecommerce.orders ( order_id INT, customer_name STRING, phone STRING, region STRING, amount DECIMAL(10,2), created_at TIMESTAMP ); INSERT INTO ecommerce.orders VALUES (1, 'Alice', '13812345678', 'APAC', 299.00, '2025-01-15 10:00:00'), (2, 'Bob', '14987654321', 'EMEA', 150.00, '2025-01-16 11:00:00'), (3, 'Charlie', '13698765432', 'APAC', 520.00, '2025-01-17 09:30:00'), (4, 'Diana', '15012349876', 'AMER', 89.00, '2025-01-18 14:00:00'); -- security_admin: create policies (auto OWNERSHIP) SET ROLE security_admin; SET enable_experimental_row_access_policy = 1; CREATE MASKING POLICY mask_phone AS (val STRING) RETURNS STRING -> CASE WHEN is_role_in_session('data_engineer') OR is_role_in_session('support_global') THEN val ELSE CONCAT(SUBSTRING(val, 1, 3), '****', SUBSTRING(val, 8)) END; CREATE ROW ACCESS POLICY rap_region AS (r STRING) RETURNS BOOLEAN -> CASE WHEN is_role_in_session('data_engineer') OR is_role_in_session('support_global') THEN true WHEN is_role_in_session('analyst_apac') AND r = 'APAC' THEN true ELSE false END; GRANT APPLY ON MASKING POLICY mask_phone TO ROLE data_engineer; GRANT APPLY ON ROW ACCESS POLICY rap_region TO ROLE data_engineer; -- data_engineer: attach (needs table ALTER + policy APPLY) SET ROLE data_engineer; SET enable_experimental_row_access_policy = 1; ALTER TABLE ecommerce.orders MODIFY COLUMN phone SET MASKING POLICY mask_phone; ALTER TABLE ecommerce.orders ADD ROW ACCESS POLICY rap_region ON (region); -- account_admin: grant table access through roles GRANT USAGE ON ecommerce.* TO ROLE analyst_apac; GRANT USAGE ON ecommerce.* TO ROLE support_global; GRANT SELECT ON ecommerce.orders TO ROLE analyst_apac; GRANT SELECT ON ecommerce.orders TO ROLE support_global;

结果:

角色行电话
analyst_apac仅 APAC已脱敏 (138****5678)
support_global全部原始值
security_admin—权限被拒绝(无 SELECT 权限)
SET ROLE analyst_apac; SELECT * FROM ecommerce.orders; -- Alice / Charlie only, phones masked SET ROLE support_global; SELECT * FROM ecommerce.orders; -- all 4 rows, phones visible SET ROLE security_admin; SELECT * FROM ecommerce.orders; -- ERROR: Permission denied

回收该角色后,无需更改表授权即可移除访问权限:

REVOKE ROLE analyst_apac FROM USER analyst_user;

经验法则:

  • 创建策略 ≠ 查询数据;附加策略需要同时具备策略 APPLY 和表 ALTER
  • 优先将权限授予角色,而不是用户
  • 创建者角色会自动获得 OWNERSHIP
  • CREATE MASKING/ROW ACCESS POLICY 是授予给角色,而不是用户
  • 使用 SHOW GRANTS ON MASKING POLICY ...、SHOW GRANTS ON ROW ACCESS POLICY ... 和 POLICY_REFERENCES(...) 进行审计

后续步骤

文档内容是否有帮助?