为 Cloud Healthcare API 数据集启用客户管理的加密密钥 (CMEK)

默认情况下, Google Cloud 会使用 Google 管理的加密密钥自动加密静态数据。如果您对保护数据的密钥有特定的合规性或监管要求,则可以将客户管理的加密密钥 (CMEK) 用于 Cloud Healthcare API 数据集。您的 Cloud Healthcare API 数据集使用由您在 Cloud Key Management Service (Cloud KMS) 中控制和管理的密钥进行加密,而不是由 Google 拥有和管理用于保护您的数据的加密密钥。

如需大致了解 CMEK(包括其启用时间和原因),请参阅客户管理的加密密钥 (CMEK)

准备工作

确定您的 Cloud Healthcare API 数据集和 Cloud KMS 将位于同一 Google Cloud 项目中还是不同的项目中。如需获取指导,请参阅职责分离

为了方便说明,本文档将采用下列惯例:

  • PROJECT_ID:Cloud Healthcare API 项目 ID
  • KMS_PROJECT_ID:运行 Cloud KMS 的项目 ID,可能与 PROJECT_ID 相同

如需了解 Google Cloud 项目 ID 和项目编号,请参阅识别项目

限制

  • 您只能在创建 Cloud Healthcare API 数据集时使用 Cloud KMS 密钥。您无法对现有 Cloud Healthcare API 数据集启用、更改或停用 Cloud KMS 密钥。
  • CMEK 加密数据集中仅支持 FHIR、DICOM 和 HL7v2 存储区。CMEK 保护适用于数据集中的 DICOM、FHIR 和 HL7v2 存储区及其资源。
  • 您无法对使用 CMEK 加密的资源进行去标识化处理。

CMEK 操作

在创建、读取、更新或删除使用 CMEK 加密的资源时,以及执行结算或确保密钥可用等操作任务时,系统会使用 Cloud KMS 密钥。

外部密钥注意事项

如需了解如何使用您在支持的外部密钥管理合作伙伴系统内管理的密钥来保护Google Cloud中的数据,请参阅 Cloud External Key Manager

如果您丢失了在 Google Cloud外部管理的密钥,Google 将无法恢复您的数据。

密钥不可用和数据丢失

如果数据集由密钥加密,而该密钥变得不可用且一直不可用,Cloud Healthcare API 会停用并最终删除该数据集。有时,如果密钥已停用或销毁,或者因权限被撤消而无法访问,则密钥会变为不可用,但如果密钥因任何原因而不可用,也会出现这种行为。密钥的保护级别或是否为外部密钥不会影响此行为。外部密钥也可能会不可预测地变为不可用。例如,您的Google Cloud 资源和 EKM 之间可能会出现连接问题。

以下流程介绍了如何检查密钥可用性,以及如何停用和删除数据集:

  1. 创建使用 CMEK 加密的 Cloud Healthcare API 数据集后,Cloud Healthcare API 会每 5 分钟检查一次密钥的状态,以确保密钥可用。如果密钥不可用,Cloud Healthcare API 会继续支持对数据集的请求,最长可达一小时。

  2. 一小时后,如果 Cloud Healthcare API 仍无法连接到 Cloud KMS,系统会停用 Cloud Healthcare API 数据集作为保护措施。如需重新启用 Cloud Healthcare API 数据集,请与您的支持代表联系。

    停用后,您只能向 Cloud Healthcare API 数据集发送 datasets.getdatasets.delete 请求。其他请求会失败并显示 400 FAILED_PRECONDITION 错误。

  3. 如果 Cloud Healthcare API 数据集在 30 天内仍不可用,则会被永久删除。数据集中的所有 DICOM、FHIR 和 HL7v2 存储区及其关联数据也会一并删除。这些数据一旦删除将无法恢复。

密钥创建

以下部分介绍了如何创建 Cloud KMS 密钥环和密钥。仅支持 Cloud KMS 对称加密密钥

支持的位置

Cloud KMS 密钥可在 Cloud Healthcare API 位置中使用。请在与 Cloud Healthcare API 数据集的区域或多区域匹配的位置创建密钥环。

  • 任何多区域 Cloud Healthcare API 数据集都必须使用来自匹配位置的多区域密钥环。例如,位于区域 us 的 Cloud Healthcare API 数据集必须使用位于区域 us 的密钥环进行保护,位于区域 eu 的 Cloud Healthcare API 数据集必须使用位于区域 europe 的密钥环进行保护。

  • 区域 Cloud Healthcare API 数据集必须使用匹配的区域密钥。例如,位于区域 asia-northeast1 的 Cloud Healthcare API 数据集必须使用区域 asia-northeast1 中的密钥环进行保护。

  • 为 Cloud Healthcare API 数据集配置 CMEK 时,您不能使用 global 区域。

如需了解详情,请参阅 Cloud Healthcare API 位置Cloud KMS 位置

创建密钥环和密钥

在运行 Cloud KMS 的 Google Cloud 项目中,完成以下步骤:

  1. 创建密钥环
  2. 创建密钥

授予加密和解密权限

如需使用 Cloud KMS 密钥保护 Cloud Healthcare API 数据,请向 Cloud Healthcare 服务代理服务账号授予该密钥的 CryptoKey Encrypter/Decrypter (roles/cloudkms.cryptoKeyEncrypterDecrypter) 角色。如需了解相关说明,请参阅数据集 CMEK 权限

向服务账号授予该角色后,Cloud Healthcare API 便可以加密和解密使用 CMEK 加密的资源。在读取或写入数据时,应用无需指定密钥。Cloud Healthcare API 会处理加密。

当请求者读取或写入使用 Cloud KMS 密钥加密的对象时,他们会照常访问该对象。在请求期间,服务代理会自动加密或解密请求的对象,前提是满足以下两个条件:

  • 服务代理仍拥有所需的权限。
  • 密钥可用且已启用。

创建使用 CMEK 加密的 Cloud Healthcare API 数据集

以下示例展示了如何创建使用 CMEK 加密的数据集。

您必须在创建数据集时指定 Cloud KMS 密钥资源 ID。此密钥区分大小写,格式如下:

projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME

如需查看 Cloud KMS 密钥资源 ID,请参阅获取 Cloud KMS 资源 ID

如需执行此任务,您必须已获得以下权限或以下 Identity and Access Management (IAM) 角色:

权限

  • healthcare.datasets.create

角色

您可以要求管理员为您授予这些 Identity and Access Management 角色。如需了解如何授予角色,请参阅管理访问权限控制对 Cloud Healthcare API 资源的访问。您也可以通过自定义角色或其他预定义角色来获取所需的权限。

  1. 在 Google Cloud 控制台中,前往浏览器页面。

    转到浏览器

  2. 点击 创建数据集。系统随即会显示创建数据集页面。

  3. 名称字段中,输入数据集的标识符,该标识符应符合数据集允许的字符和大小要求

  4. 选择以下某一类型的位置:

    • Region 绑定将多选选项设置为所有记录中 Region 的所有值。数据集永久驻留在一个 Google Cloud 区域中。选择此选项后,在区域字段中输入或选择位置。

    • 多区域。数据集永久驻留在跨多个 Google Cloud 区域的位置中。选择此选项后,在多区域字段中输入或选择多区域位置。

  5. 加密部分,选择以下加密类型之一:

    • Google-managed encryption key:默认加密方法。 如果您希望 Google 管理用于保护此 Cloud Healthcare API 数据集中数据的加密密钥,请使用此方法。

    • Cloud KMS 密钥:使用客户管理的加密密钥 (CMEK)。

  6. 点击创建。系统会显示浏览器页面。新数据集将显示在数据集列表中。

使用 gcloud healthcare datasets create 命令创建数据集。

在使用下面的命令数据之前,请先进行以下替换:

执行以下命令:

Linux、macOS 或 Cloud Shell

gcloud healthcare datasets create DATASET_ID \
  --location=LOCATION \
  --encryption-key=KEY_RESOURCE_ID
gcloud healthcare datasets create DATASET_ID `
  --location=LOCATION `
  --encryption-key=KEY_RESOURCE_ID
gcloud healthcare datasets create DATASET_ID ^
  --location=LOCATION ^
  --encryption-key=KEY_RESOURCE_ID

您应该会收到类似如下所示的响应:

Create request issued for: [DATASET_ID]
Waiting for operation [projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID] to complete...
Created dataset [DATASET_ID].
  1. 使用 datasets.create 方法创建数据集。

    在使用任何请求数据之前,请先进行以下替换:

    • PROJECT_ID:您的 Google Cloud 项目的 ID
    • DATASET_ID:一个标识符,须遵循数据集允许的字符和大小要求
    • LOCATION:数据集的受支持的位置
    • KEY_RESOURCE_ID:Cloud KMS 密钥的资源 ID,格式为 projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME

    请求 JSON 正文:

    {
      "encryptionSpec": {
        "kmsKeyName": "KEY_RESOURCE_ID"
      }
    }
    

    如需发送请求,请选择以下方式之一:

    将请求正文保存在名为 request.json 的文件中。在终端中运行以下命令,在当前目录中创建或覆盖此文件:

    cat > request.json << 'EOF'
    {
      "encryptionSpec": {
        "kmsKeyName": "KEY_RESOURCE_ID"
      }
    }
    EOF

    然后,执行以下命令以发送 REST 请求:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets?datasetId=DATASET_ID"

    将请求正文保存在名为 request.json 的文件中。在终端中运行以下命令,在当前目录中创建或覆盖此文件:

    @'
    {
      "encryptionSpec": {
        "kmsKeyName": "KEY_RESOURCE_ID"
      }
    }
    '@  | Out-File -FilePath request.json -Encoding utf8

    然后,执行以下命令以发送 REST 请求:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets?datasetId=DATASET_ID" | Select-Object -Expand Content

    复制请求正文并打开方法参考页面。APIs Explorer 面板会在页面右侧打开。您可以与此工具进行交互以发送请求。 将请求正文粘贴到此工具中,填写任何其他必填字段,然后点击执行

    输出如下所示。响应包含长时间运行的操作 (LRO) 的标识符。当方法调用可能需要额外时间才能完成时,会返回长时间运行的操作。记下 OPERATION_ID 的值。下一步中您需要用到该值。
    {
      "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
    }
    
    

  2. 使用 projects.locations.datasets.operations.get 方法获取长时间运行的操作的状态。

    在使用任何请求数据之前,请先进行以下替换:

    • PROJECT_ID:您的 Google Cloud 项目的 ID
    • LOCATION:数据集位置
    • DATASET_ID:数据集 ID
    • OPERATION_ID:从长时间运行的操作返回的 ID

    如需发送请求,请选择以下方式之一:

    执行以下命令:

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

    执行以下命令:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method GET `
    -Headers $headers `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

    打开方法参考页面。APIs Explorer 面板会在页面右侧打开。您可以与此工具进行交互以发送请求。 填写所有必填字段,然后点击执行

    输出如下所示。如果响应包含 "done": true,则表示长时间运行的操作已完成。
    {
      "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
      "metadata": {
        "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
        "apiMethodName": "google.cloud.healthcare.v1.dataset.DatasetService.CreateDataset",
        "createTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
        "endTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
        "logsUrl": "https://console.cloud.google.com/CLOUD_LOGGING_URL"
        "counter": {
          "success": "SUCCESS_COUNT",
          // If there were any failures, they display in the `failure` field.
          "failure": "FAILURE_COUNT"
        }
      },
      "done": true,
      // The `response` field only displays if there were no errors.
      "response": {
        "@type": "type.googleapis.com/google.cloud.healthcare.v1.dataset.Dataset",
        "name": "PROJECT_ID/locations/LOCATION/datasets/DATASET_ID",
      },
      // If there were any errors, an `error` field displays instead of a `response` field.
      // See Troubleshooting long-running operations for a list of response codes.
      "error": {
        "code": ERROR_CODE,
        "message": "DESCRIPTION",
        "details": [
          {
            "@type": "...",
            FIELD1: ...,
            ...
          }
        ]
      }
    }
    

确定数据集是否受 Cloud KMS 保护

对于您创建的或用于保护 Cloud Healthcare API 数据集的每个密钥,您都可以通过密钥使用情况跟踪来查看该密钥所保护的资源。如需了解详情,请参阅查看密钥使用情况

密钥轮替

Cloud KMS 支持自动和手动将密钥轮替到新版本。

轮替密钥会导致以下结果:

  • 轮替后创建的 Cloud Healthcare API 数据集将使用新密钥版本进行加密和执行所有操作。
  • 现有数据集中使用该密钥加密的资源不会自动使用新的主密钥版本重新加密。

为了使加密功能正常运行,必须确保所有密钥版本均可用。否则,Cloud Healthcare API 数据集将被停用,并且对该数据集的所有请求都会失败。如需了解详情,请参阅外部密钥注意事项停用的数据集和永久删除数据集

移除 Cloud Healthcare API 对 Cloud KMS 密钥的访问权限

您可以控制自己的密钥,并可以停用、销毁或撤消密钥的权限,以便 Cloud Healthcare API 无法访问使用 CMEK 加密的数据。销毁与 Cloud Healthcare API 数据集关联的密钥或密钥版本后,使用该密钥或密钥版本加密的所有数据都将永久丢失。

停用密钥或密钥版本后,需等待一段时间,该密钥或密钥版本才会停止可用。此外,从您撤消密钥的 Cloud Healthcare Service Agent 服务账号权限到无法再访问该密钥之间也会有延迟。如需了解详情,请参阅 Cloud KMS 资源一致性

将数据导出和导入到启用了 CMEK 的实例

如需在导出操作期间使用客户管理的密钥加密数据,您必须先在存储目的地设置 CMEK,然后再开始导出。从非 CMEK 或 CMEK 加密存储空间导入数据到 CMEK 加密数据集时,没有特殊要求或限制。

限制

价格

无论数据集是否采用 CMEK 加密,其计费方式都是相同的。如需了解详情,请参阅 Cloud Healthcare API 价格

Cloud KMS 会向您收取该密钥以及针对该密钥执行的任何加密操作的费用。当 Cloud Healthcare API 使用密钥进行加密或解密时,就会发生这些操作。根据 Cloud Healthcare API 生成的加密操作的预期数量,您可以预计这些费用会很小。如需了解详情,请参阅 Cloud KMS 价格

Cloud KMS 配额和 Cloud Healthcare API

在 Cloud Healthcare API 中使用 CMEK 时,您的项目可能会消耗 Cloud KMS 加密请求配额。使用 CMEK 加密的 Cloud Healthcare API 数据集及其 DICOM、FHIR 和 HL7v2 存储区会消耗这些配额,但 datasets.get 除外。仅当您使用硬件 (Cloud HSM) 或外部 (Cloud EKM) 密钥时,使用 CMEK 密钥执行的加密和解密操作才会影响 Cloud KMS 配额。如需了解详情,请参阅 Cloud KMS 配额

后续步骤