本文介绍如何在 Azure Cosmos DB 帐户上配置动态数据掩码。
重要
动态数据掩码目前处于公共预览阶段。 此功能没有提供服务级别协议。 有关详细信息,请参阅适用于 Azure 预览版的补充使用条款。
概述
动态数据掩码(DDM)是 Azure Cosmos DB 中基于策略的服务器端安全功能,可帮助保护敏感数据免受未经授权的访问。 DDM 动态掩码非特权用户的数据,确保在向应用程序呈现之前实时编辑敏感信息,而原始数据在数据库中保持不变。
DDM 通过限制敏感数据(如个人数据和受保护的健康信息)的暴露,帮助组织满足安全、合规性和法规要求。
动态数据掩码如何帮助保护数据
- 限制敏感数据公开: 只有特权用户才能查看未屏蔽的数据;其他人会看到屏蔽或编辑的值。
- 基于策略的强制: 根据用户角色和特权应用掩码。
- 合规性支持: 帮助满足数据隐私和保护的法规要求。
- 对存储的数据没有影响: 在查询时发生掩码;基础数据保持不变。
支持的掩码策略
| 类型 | Description | Example |
|---|---|---|
| 违约 |
字符串 值将替换为固定掩码 "XXXX" 数字型数值 会被替换为默认值 0 布尔值始终设置为 false |
原文:雷德蒙德 蒙面: XXXX原始: 95 蒙面: 0原始: 真 蒙面: false |
| 自定义字符串 | 使用 MaskSubstring(Start、Length) 基于定义的起始索引和长度屏蔽字符串的一部分 | MaskSubstring(3,5) 原文:华盛顿 蒙面: WasXXXXXon |
只有用户名的第一个字母和域结尾(如.com)保持可见。 所有其他字符都替换为 X 字符。 |
源语言: alpha@microsoft.com 蒙面: aXXXX@XXXXXXXXX.com |
如何在 Azure Cosmos DB 上设置动态数据掩码
注释
动态数据掩码(DDM)需要Microsoft Entra ID 托管标识,不支持帐户密钥。
启用动态数据掩码
可以通过位于“设置”导航窗格下的“功能”选项卡为帐户配置动态数据掩码。
注释
在帐户上启用动态数据掩码后,无法将其关闭。 启用此功能可能需要长达 15 分钟才能在 Azure Cosmos DB 中准备就绪。
使用权限创建角色定义
数据掩码利用 Azure Cosmos DB 数据平面 [基于角色的访问控制] (how-to-connect-role-based-access-control.md)。 若要实现数据掩码,必须创建角色定义并分配用于取消掩码的数据作权限,如示例中所示。 内置数据参与者角色包括取消掩码权限,而默认情况下,数据读取者角色没有 unmask 权限。
使用
New-GuidPowerShell 中的命令生成新的 GUID,并将生成的 GUID 粘贴到 JSON 正文(之后/sqlRoleDefinitions/<NEW_GUID_HERE>)。 创建包含以下内容的 JSON 文件unmasked_role_definition.json:{ "Id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/Your-resource-group-name/providers/Microsoft.DocumentDB/databaseAccounts/Your-CosmosDB-account-name/sqlRoleDefinitions/00000000-0000-0000-0000-000000009999", "RoleName": "unmaskroledefinition1", "Type": "CustomRole", "AssignableScopes": [ "/" ], "Permissions": [ { "DataActions": [ "Microsoft.DocumentDB/databaseAccounts/readMetadata", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/unmask", "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery" ], "NotDataActions": [] } ] }运行以下命令以创建角色定义:
az cosmosdb sql role definition create ` --account-name "Your-CosmosDB-account-name" ` --resource-group "Your-resource-group-name" ` --body "@unmasked_role_definition.json"
将用户分配到角色
定义角色后,下一步是将用户分配到每个角色。 根据这些角色定义,用户分为两个组:高特权用户和低特权用户。
高特权用户
授予拥有高级权限的用户在容器级别的 unmask 权限。
az cosmosdb sql role assignment create `
--account-name "Your-CosmosDB-account-name" `
--resource-group "Your-resource-group-name" `
--scope "/" `
--principal-id "zzzzz-yyyy01-xxxx02-www3w3" `
--role-definition-id "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/Your-resource-group-name/providers/Microsoft.DocumentDB/databaseAccounts/Your-CosmosDB-account-name/sqlRoleDefinitions/00000000-0000-0000-0000-000000009999"
低特权用户
低特权用户具有最少的权限,例如内置的 Cosmos DB 数据读取者角色。
az cosmosdb sql role assignment create `
--account-name "Your-CosmosDB-account-name" `
--resource-group "Your-resource-group-name" `
--scope "/" `
--principal-id "zzzzz-yyyy01-xxxx02-www3w3" `
--role-definition-id "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/Your-resource-group-name/providers/Microsoft.DocumentDB/databaseAccounts/Your-CosmosDB-account-name/sqlRoleDefinitions/00000000-0000-0000-0000-000000000001"
(可选)列出角色定义
运行以下命令以显示和验证角色定义。
az cosmosdb sql role definition list `
--account-name "Your-CosmosDB-account-name" `
--resource-group "Your-resource-group-name"
应用数据掩码策略
注释
仅当启用了动态数据掩码功能时,才会显示掩码策略部分。
在 Azure 门户中,转到 Azure Cosmos DB 帐户,选择 “容器”,然后在 “设置”下,在“ 屏蔽策略”下创建数据掩码策略。
注释
如果未指定掩码策略,则会自动应用默认策略。
"dataMaskingPolicy":
{
"includedPaths": [
{
"path": "/" // Mask all fields
},
{
"path": "/profile/contact/email",
"strategy": "Email" //Email strategy overrides the default mask
},
{
"path": "/employment/history/[]/company",
"strategy": "MaskSubstring", // MaskSubstring overrides the default mask
"startPosition": 2,
"length": 4
}
],
"excludedPaths": [
{
"path": "/projects/[]/projectId" //Exclude projectId from masking
},
{
"path": "/id"
},
{
"path": "/department"
},
{
"path": "/employment/history/[]/duration"
},
{
"path": "/projects/[]/details/technologies"
}
],
"isPolicyEnabled": true
}
结果
{
"id": "ab12345-678a-4b7a-8d94-987654321",
"department": "Marketing",
"profile": {
"name": {
"first": "XXXX",
"last": "XXXX"
},
"contact": {
"email": "uXXXX@XXXXXXX.com",
"phone": "XXXX"
},
"address": {
"street": "XXXX",
"city": "XXXX",
"zipcode": "XXXX"
}
},
"employment": {
"role": "XXXX",
"startDate": "XXXX",
"history": [
{
"company": "CoXXXXy2",
"duration": "1 year",
"position": "XXXX"
}
]
},
"skills": [
{
"name": "XXXX",
"proficiency": "XXXX"
},
{
"name": "XXXX",
"proficiency": "XXXX"
}
],
"projects": [
{
"projectId": "1a",
"name": "XXXX",
"details": {
"description": "XXXX",
"teamSize": 0,
"durationMonths": 0,
"technologies": [
"MS Word",
"MS Excel",
"Project Management"
]
}
},
{
"projectId": "2a",
"name": "XXXX",
"details": {
"description": "XXXX",
"teamSize": 0,
"durationMonths": 0,
"technologies": [
"Dot Net",
"MS Excel"
]
}
}
],
"_rid": "E1234+Uyj18CAAAACCCCC==",
"_self": "dbs/E8mBDw==/colls/E8mBD+Uyj18=/docs/E1234+Uyj18CAAAACCCCC==/",
"_etag": "\"00001000-0000-0400-0000-98y1234z0000\"",
"_attachments": "attachments/",
"_ts": 1234567890
}
有效和无效的路径
有效路径
{ "path": "/CreditCard", "strategy": "MaskSubstring", "startPosition": 0, "length": 8 } // Masks first 8 characters using MaskSubstring(startPosition, length)
{ "path": "/profile/contact/phone", "strategy": "MaskSubstring", "startPosition": 4, "length": 6} // Masks characters for a nested field
{ "path": "/SSN", "strategy": "Default"} // Fully masked using default strategy
{ "path": "/PhoneNumber"} // Default masking applied
{ "path": "/Email", "strategy": "Email" } // Email masking strategy applied
{ "path": "/profile/contact/email", "strategy": "Email"} //Email masking strategy applied for a nested field
{ "path": "/Address/ZipCode" } // Masks the nested ZipCode field using the default masking method
{ "path": "/Projects/[]/name" } // Masks the name field within an array using the default strategy
{ "path": "/projects/[]/details/[]/technologies"} // Masking the technologies field in nested array using default strategy
无效的路径
{ "path": "/projects/[]", "strategy": "Default"} // Path can't end with []
{ "path": "/projects/[1]/name", "strategy": "Default"} // Specific index in array isn't supported
动态数据掩码对容量规划的影响
动态数据掩码(DDM)通过在查询时应用掩码规则来帮助保护敏感数据。 虽然此功能对应用程序是透明的,但计算使用情况有特定的注意事项:
包含屏蔽数据的查询: 应用掩码规则需要在返回结果之前对敏感字段进行额外的处理,这比不屏蔽的查询消耗 的请求单位(RU) 略有增加。
其他方案: 对于不涉及屏蔽列的查询,动态数据掩码对计算使用情况没有影响。
局限和限制
- 动态数据掩码仅限于 Azure Cosmos DB 中的 NoSQL API。
- 在帐户级别启用数据掩码后,它将保持活动状态,并且无法关闭。
- 除非将掩码策略应用于容器,否则启用掩码本身不会增加成本。
- 在 MaskSubstring 策略中,只允许正开始位置。 不允许反向索引。
- 仅当策略中包含所有路径(/)时,才能使用排除路径。
- 不支持对特定数组索引屏蔽值。
- 如果 ID 或分区键已屏蔽,则数据资源管理器(门户)中的文档视图不起作用。
- 更改源功能(Latest 和 AllVersionsAndDeletes)不适用于权限较低的用户。
- 构造镜像、具体化视图和备份(定期或连续)对未屏蔽的数据进行作。
- 复杂的查询偶尔可能会公开未屏蔽的数据或启用敏感值的推理。 动态数据掩码旨在最大程度地减少未经授权的用户的数据泄露,而不是防止直接数据库访问或详尽查询。