通过 Azure Key Vault 为 Azure Cosmos 帐户配置客户管理的密钥

适用于: SQL API Cassandra API Gremlin API 表 API Azure Cosmos DB API for MongoDB

存储在 Azure Cosmos 帐户中的数据会使用 Azure 托管密钥(服务托管密钥)自动无缝地进行加密。 或者,你可以选择使用你管理的密钥(客户管理的密钥或 CMK)添加另一层加密。

围绕客户数据的加密层

必须将客户托管密钥存储在 Azure Key Vault 中,并为每个启用了客户托管密钥的 Azure Cosmos 帐户提供一个密钥。 此密钥用于加密存储在该帐户中的所有数据。

注意

当前,客户托管密钥仅适用于新的 Azure Cosmos 帐户。 应在创建帐户期间配置这些密钥。

为 Azure 订阅注册 Azure Cosmos DB 资源提供程序

  1. 登录到 Azure 门户,转到 Azure 订阅,并在 “设置” 选项卡下选择 “资源提供程序”

    左侧菜单中的“资源提供程序”项

  2. 搜索“Microsoft DocumentDB”资源提供程序。 确认该资源提供程序是否标记为已注册。 如果不是,请选择该资源提供程序,然后选择“注册”:

    注册“Microsoft DocumentDB”资源提供程序

配置 Azure Key Vault 实例

重要

Azure 密钥保管库实例必须可通过公共网络访问进行访问,或者允许受信任的 Azure 服务绕过其防火墙。 只能通过专用终结点访问的实例不能用于托管客户管理的密钥。

将客户管理的密钥与 Azure Cosmos DB 结合使用时,需要在计划用于托管加密密钥的 Azure Key Vault 实例上设置两个属性: “软删除”“清除保护”

如果创建新的 Azure Key Vault 实例,请在创建过程中启用以下属性:

为新的 Azure Key Vault 实例启用“软删除”和“清除保护”

如果使用的是现有 Azure Key Vault 实例,则可以通过查看 Azure 门户中的“属性”部分来验证是否已启用这些属性。 如果未启用任一属性,请参阅以下文章中的“启用软删除”和“启用清除保护”部分:

将访问策略添加到 Azure Key Vault 实例

  1. 在 Azure 门户中,转到你打算用来托管加密密钥的 Azure Key Vault 实例。 在左侧菜单中选择“访问策略”:

    左侧菜单中的“访问策略”

  2. 选择“+ 添加访问策略”

  3. 在“密钥权限”下拉菜单中,选择“获取”、“解包密钥”和“包装密钥”权限:

    选择适当的权限

  4. 在“选择主体”下,选择“未选择任何项”。

  5. 搜索“Azure Cosmos DB”主体并将其选中(为了便于查找,对于任何 Azure 中国区域,还可以按应用程序 ID a232010e-820c-4083-83bb-3ace5fc29d0b 进行搜索)。 如果列表中没有“Azure Cosmos DB”主体,可能需要根据本文的注册资源提供程序部分所述,重新注册 Microsoft.DocumentDB 资源提供程序)。

    注意

    这样便可在 Azure Key Vault 访问策略中注册 Azure Cosmos DB 第一方标识。 若要将第一方标识替换为 Azure Cosmos DB 帐户托管标识,请参阅使用 Azure Key Vault 访问策略中的托管标识

  6. 选择底部的“选择”。

    选择 Azure Cosmos DB 主体

  7. 选择“添加”以添加新的访问策略

  8. 在密钥保管库实例上选择“保存”,以保存所有更改。

在 Azure Key Vault 中生成密钥

  1. 在 Azure 门户中,转到你打算用来托管加密密钥的 Azure Key Vault 实例。 然后,从左侧菜单中选择“密钥”

    左侧菜单中的“密钥”项

  2. 选择“生成/导入”,为新密钥提供名称,并选择一个 RSA 密钥大小。 建议至少使用 3072,以获得最佳安全性。 然后选择“创建”

    新建密钥

  3. 创建密钥后,选择新创建的密钥,然后选择其当前版本。

  4. 复制密钥的密钥标识符(最后一个正斜杠之后的部分除外):

    复制密钥的密钥标识符

创建新的 Azure Cosmos 帐户

使用 Azure 门户

当你从 Azure 门户创建新的 Azure Cosmos DB 帐户时,请选择“加密”步骤中“客户管理的密钥”。 在“密钥 URI”字段中,粘贴从上一步复制的 Azure Key Vault 密钥的 URI/密钥标识符:

在 Azure 门户中设置 CMK 参数

使用 Azure PowerShell

使用 PowerShell 创建新的 Azure Cosmos DB 帐户时:

  • 在“PropertyObject”中,传递前面在“keyVaultKeyUri”属性下复制的 Azure Key Vault 密钥的 URI。

  • 使用 2019-12-12 或更高版本作为 API 版本。

重要

必须显式设置 locations 属性,才能通过客户管理的密钥成功创建帐户。

$resourceGroupName = "myResourceGroup"
$accountLocation = "China North 2"
$accountName = "mycosmosaccount"

$failoverLocations = @(
    @{ "locationName"="China North 2"; "failoverPriority"=0 }
)

$CosmosDBProperties = @{
    "databaseAccountOfferType"="Standard";
    "locations"=$failoverLocations;
    "keyVaultKeyUri" = "https://<my-vault>.vault.azure.cn/keys/<my-key>";
}

New-AzResource -ResourceType "Microsoft.DocumentDb/databaseAccounts" `
    -ApiVersion "2019-12-12" -ResourceGroupName $resourceGroupName `
    -Location $accountLocation -Name $accountName -PropertyObject $CosmosDBProperties

创建帐户后,可以通过提取 Azure Key Vault 密钥的 URI 来验证是否已启用客户管理的密钥:

Get-AzResource -ResourceGroupName $resourceGroupName -Name $accountName `
    -ResourceType "Microsoft.DocumentDb/databaseAccounts" `
    | Select-Object -ExpandProperty Properties `
    | Select-Object -ExpandProperty keyVaultKeyUri

使用 Azure 资源管理器模板

通过 Azure 资源管理器模板创建新的 Azure Cosmos 帐户时:

  • 在“属性”对象中,传递前面在“keyVaultKeyUri”属性下复制的 Azure Key Vault 密钥的 URI。

  • 使用 2019-12-12 或更高版本作为 API 版本。

重要

必须显式设置 locations 属性,才能通过客户管理的密钥成功创建帐户。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "accountName": {
            "type": "string"
        },
        "location": {
            "type": "string"
        },
        "keyVaultKeyUri": {
            "type": "string"
        }
    },
    "resources": 
    [
        {
            "type": "Microsoft.DocumentDB/databaseAccounts",
            "name": "[parameters('accountName')]",
            "apiVersion": "2019-12-12",
            "kind": "GlobalDocumentDB",
            "location": "[parameters('location')]",
            "properties": {
                "locations": [ 
                    {
                        "locationName": "[parameters('location')]",
                        "failoverPriority": 0,
                        "isZoneRedundant": false
                    }
                ],
                "databaseAccountOfferType": "Standard",
                "keyVaultKeyUri": "[parameters('keyVaultKeyUri')]"
            }
        }
    ]
}

使用以下 PowerShell 脚本部署模板:

$resourceGroupName = "myResourceGroup"
$accountName = "mycosmosaccount"
$accountLocation = "China North 2"
$keyVaultKeyUri = "https://<my-vault>.vault.azure.cn/keys/<my-key>"

New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile "deploy.json" `
    -accountName $accountName `
    -location $accountLocation `
    -keyVaultKeyUri $keyVaultKeyUri

使用 Azure CLI

通过 Azure CLI 创建新的 Azure Cosmos 帐户时,传递前面在 --key-uri 参数下复制的 Azure Key Vault 密钥的 URI。

resourceGroupName='myResourceGroup'
accountName='mycosmosaccount'
keyVaultKeyUri = 'https://<my-vault>.vault.azure.cn/keys/<my-key>'

az cosmosdb create \
    -n $accountName \
    -g $resourceGroupName \
    --locations regionName='China North 2' failoverPriority=0 isZoneRedundant=False \
    --key-uri $keyVaultKeyUri

创建帐户后,可以通过提取 Azure Key Vault 密钥的 URI 来验证是否已启用客户管理的密钥:

az cosmosdb show \
    -n $accountName \
    -g $resourceGroupName \
    --query keyVaultKeyUri

使用 Azure Key Vault 访问策略中的托管标识

此访问策略确保你的 Azure Cosmos DB 帐户可以访问你的加密密钥。 访问策略通过授予对特定 Azure Active Directory (AD) 标识的访问权限来实现。 支持两种类型的标识:

  • Azure Cosmos DB 的第一方标识,可用于授予对 Azure Cosmos DB 服务的访问权限。
  • Azure Cosmos DB 帐户的托管标识,可用于专门授予对帐户的访问权限。

若要使用系统分配的托管标识

由于只有在创建帐户后才能检索系统分配的托管标识,因此你仍然需要首先使用第一方标识创建你的帐户,如上所述。 那么:

  1. 如果在创建帐户期间未配置系统分配的托管标识,请在你的帐户上启用系统分配的托管标识并复制已分配的 principalId

  2. 上文所述,将新访问策略添加到 Azure Key Vault 帐户,但使用你在上一步复制的 principalId,而不是 Azure Cosmos DB 的第一方标识。

  3. 更新 Azure Cosmos DB 帐户,以指定在访问 Azure Key Vault 中的加密密钥时要使用系统分配的托管标识。 可以使用两个选项:

    • 在帐户的 Azure 资源管理器模板中指定属性:

      {
          "type": " Microsoft.DocumentDB/databaseAccounts",
          "properties": {
              "defaultIdentity": "SystemAssignedIdentity",
              // ...
          },
          // ...
      }
      
    • 使用 Azure CLI 更新帐户:

      resourceGroupName='myResourceGroup'
      accountName='mycosmosaccount'
      
      az cosmosdb update --resource-group $resourceGroupName --name $accountName --default-identity "SystemAssignedIdentity"
      
  4. (可选)然后从 Azure Key Vault 访问策略中删除 Azure Cosmos DB 第一方标识。

若要使用用户分配的托管标识

  1. 如上所述,在 Azure Key Vault 帐户中创建新的访问策略时,请使用想要使用的 Object ID 托管标识,而不是 Azure Cosmos DB 的第一方标识。

  2. 创建 Azure Cosmos DB 帐户时,必须启用用户分配的托管标识,并指定在 Azure Key Vault 中访问加密密钥时要使用此标识。 选项包括:

    • 使用 Azure 资源管理器模板:

      {
          "type": "Microsoft.DocumentDB/databaseAccounts",
          "identity": {
              "type": "UserAssigned",
              "userAssignedIdentities": {
                  "<identity-resource-id>": {}
              }
          },
          // ...
          "properties": {
              "defaultIdentity": "UserAssignedIdentity=<identity-resource-id>"
              "keyVaultKeyUri": "<key-vault-key-uri>"
              // ...
          }
      }
      
    • 使用 Azure CLI:

      resourceGroupName='myResourceGroup'
      accountName='mycosmosaccount'
      keyVaultKeyUri = 'https://<my-vault>.vault.azure.cn/keys/<my-key>'
      
      az cosmosdb create \
          -n $accountName \
          -g $resourceGroupName \
          --key-uri $keyVaultKeyUri
          --assign-identity <identity-resource-id>
          --default-identity "UserAssignedIdentity=<identity-resource-id>"  
      

将 CMK 与连续备份一同使用

可以通过使用 Azure CLI 或 Azure 资源管理器模板来创建一个连续备份帐户。

目前,仅支持使用用户分配的托管标识来创建连续备份帐户。

使用 Azure CLI 创建连续备份帐户

resourceGroupName='myResourceGroup'
accountName='mycosmosaccount'
keyVaultKeyUri = 'https://<my-vault>.vault.azure.cn/keys/<my-key>'

az cosmosdb create \
    -n $accountName \
    -g $resourceGroupName \
    --key-uri $keyVaultKeyUri \
    --locations regionName=<Location> \
    --assign-identity <identity-resource-id> \
    --default-identity "UserAssignedIdentity=<identity-resource-id>" \
    --backup-policy-type Continuous 

使用 Azure 资源管理器模板创建连续备份帐户

通过 Azure 资源管理器模板创建新的 Azure Cosmos 帐户时:

  • 在“属性”对象中,传递前面在“keyVaultKeyUri”属性下复制的 Azure Key Vault 密钥的 URI。
  • 使用 2021-11-15 或更高版本作为 API 版本。

重要

必须显式设置 locations 属性,才能通过客户管理的密钥成功创建帐户,如前面的示例所示。

 {
    "type": "Microsoft.DocumentDB/databaseAccounts",
    "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
            "<identity-resource-id>": {}
        }
    },
    // ...
    "properties": {
        "backupPolicy": { "type": "Continuous" },
        "defaultIdentity": "UserAssignedIdentity=<identity-resource-id>"
        "keyVaultKeyUri": "<key-vault-key-uri>"
        // ...
    }
}

客户管理的密钥和双重加密

使用客户管理的密钥时,存储在 Azure Cosmos DB 帐户中的数据最终会加密两次:

  • 通过 Azure 托管密钥执行的默认加密一次。
  • 通过客户管理的密钥执行额外加密一次。

双重加密仅适用于主 Azure Cosmos DB 事务存储。 某些功能涉及将数据内部复制到不提供双重加密的第二层存储,即使使用客户管理的密钥也是如此。 这些功能包括:

密钥轮换

可以通过两种方式来轮换 Azure Cosmos 帐户使用的客户托管密钥。

  • 创建当前在 Azure Key Vault 中使用的密钥的新版本:

    Azure 门户“版本”页中“新版本”选项的屏幕截图。

  • 通过更新帐户上的密钥 URI,将当前使用的密钥替换为其他密钥。 在 Azure 门户中转到你的 Azure Cosmos 帐户,然后在左侧菜单中选择“数据加密”:

    Azure 门户中“数据加密”菜单选项的屏幕截图。

    然后,将“密钥 URI”替换为要使用的新密钥,并选择“保存”:

    Azure 门户“密钥”页中“保存”选项的屏幕截图。

    下面介绍如何在 PowerShell 中实现相同的结果:

    $resourceGroupName = "myResourceGroup"
    $accountName = "mycosmosaccount"
    $newKeyUri = "https://<my-vault>.vault.azure.cn/keys/<my-new-key>"
    
    $account = Get-AzResource -ResourceGroupName $resourceGroupName -Name $accountName `
        -ResourceType "Microsoft.DocumentDb/databaseAccounts"
    
    $account.Properties.keyVaultKeyUri = $newKeyUri
    
    $account | Set-AzResource -Force
    

可以在 Azure Key Vault 审核日志不再显示该密钥或密钥版本 Azure Cosmos DB 中的活动之后禁用以前的密钥或密钥版本。 在密钥轮换 24 小时后,不应在以前的密钥或密钥版本上进行更多活动。

错误处理。

如果 Azure Cosmos DB 中客户管理的密钥有任何错误,Azure Cosmos DB 会在响应中返回错误详细信息以及 HTTP 子状态代码。 可以使用 HTTP 子状态代码来调试问题的根本原因。 请参阅 Azure Cosmos DB 的 HTTP 状态代码一文,获取支持的 HTTP 子状态代码的列表。

常见问题

启用客户管理的密钥是否需要支付更多费用?

否,启用此功能不收取任何费用。

客户管理的密钥如何影响容量计划?

数据库操作使用的请求单位有所增加,以反映在使用客户管理的密钥时执行数据加密和解密所需的额外处理。 额外的 RU 消耗可能会导致预配容量的利用率略高。 请参阅下表中的指南:

操作类型 请求单位增加
点读取(按 ID 获取项) 每个操作 + 5%
任何写入操作 每个操作 + 6%
每个索引属性大约 + 0.06 RU
查询、读取更改源或冲突源 每个操作 + 15%

哪些数据是通过客户管理的密钥加密的?

Azure Cosmos 帐户中存储的所有数据都将通过客户托管密钥加密,但以下元数据除外:

现有的 Azure Cosmos 帐户是否支持客户管理的密钥?

此功能目前仅适用于新帐户。

能否将客户管理的密钥与 Azure Cosmos DB 分析存储结合使用?

可以,Azure Synapse Link 仅支持使用 Azure Cosmos DB 帐户的托管标识配置客户管理的密钥。 在帐户上启用 Azure Synapse Link 之前,必须在 Azure Key Vault 访问策略中使用 Azure Cosmos DB 帐户的托管标识。 有关如何启用托管标识并在访问策略中使用它的操作指南,请参阅使用托管标识从 Azure Cosmos DB 访问 Azure Key Vault

是否有计划支持比帐户级别密钥更精细的粒度?

目前没有,但正在考虑容器级别的密钥。

如何判断是否在 Azure Cosmos 帐户上启用了客户管理的密钥?

在 Azure 门户中,转到 Azure Cosmos 帐户,并在左侧菜单中查看“数据加密”项;如果此项存在,则在帐户中启用了客户管理的密钥:

“数据加密”菜单项

还可以通过编程方式提取 Azure Cosmos 帐户的详细信息,并查找 keyVaultKeyUri 属性是否存在。 请参阅上面的方法,在 PowerShell 中使用 Azure CLI. 实现此操作。

客户管理的密钥如何影响定期备份?

Azure Cosmos DB 将定期自动备份存储在帐户中的数据。 此操作可备份加密的数据。

若要成功还原定期备份,必须满足以下条件:

  • 需要备份时使用的加密密钥,并且 Azure Key Vault 中必须提供该密钥。 此条件要求不进行任何吊销,并且备份时使用的密钥版本仍处于启用状态。
  • 如果在访问策略中使用了系统分配的托管标识,请在恢复数据之前暂时授予对 Azure Cosmos DB 第一方标识的访问权限。 存在此要求是因为系统分配的托管标识是特定于某个帐户,并且不能在目标帐户中重复使用。 将数据完全还原到目标帐户后,可以设置所需的标识配置,并从 Key Vault 访问策略中删除第一方标识。

客户管理的密钥如何影响连续备份?

Azure Cosmos DB 提供了在帐户上配置连续备份的选项。 通过连续备份,你可以将数据还原到过去 30 天内的任何时间点。 要在启用了客户管理的密钥的帐户上使用连续备份,必须在 Key Vault 访问策略中使用用户分配的托管标识。 使用连续备份的帐户当前不支持 Azure Cosmos DB 第一方标识或系统分配的托管标识。

成功执行时间点还原需要满足以下条件:

  • 需要备份时使用的加密密钥,并且 Azure Key Vault 中必须提供该密钥。 此要求意味着不会进行任何吊销,并且备份时使用的密钥版本仍处于启用状态。
  • 必须确保在源帐户上最初使用的用户分配的托管标识仍在 Key Vault 访问策略中声明。

重要

如果在删除帐户之前撤销了加密密钥,帐户的备份可能会遗漏在吊销前 1 小时内写入的数据。

如何吊销加密密钥?

密钥吊销是通过禁用密钥的最新版本来完成的:

禁用密钥的版本

或者,若要从 Azure Key Vault 实例撤消所有密钥,可以删除授予 Azure Cosmos DB 主体的访问策略:

删除 Azure Cosmos DB 主体的访问策略

吊销客户管理的密钥后可执行哪些操作?

吊销加密密钥后,删除帐户是唯一可执行的操作。

后续步骤