Skip to content

本文为 SPIRE 官方文档 plugin_server_keymanager_gcp_kms 的中文译本,以英文原文为准。

🔗 穿越源码分析:Server 详解 · KeyManager

服务端插件:KeyManager "gcp_kms"

gcp_kms 密钥管理器(key manager)插件借助 Google Cloud 密钥管理服务(Key Management Service)来创建、维护并轮换密钥对,并按需签发 SVID。任何 Google Cloud 主体(principal)都无法查看或导出某个密钥所代表的原始加密密钥材料;相反,Cloud KMS 会代表 SPIRE 访问这些密钥材料。

配置

该插件接受以下配置项:

键名类型是否必填说明默认值
key_policy_filestring一个 JSON 格式的自定义 IAM 策略(v3) 文件路径,该策略会被附加到所创建的 CryptoKey 上。""
key_identifier_filestring若未设置 key_identifier_value 则必填一个文件路径,用于持久化插件所使用的密钥元数据(metadata)。更多信息见"密钥的管理"。""
key_identifier_valuestring若未设置 key_identifier_file 则必填SPIRE server 实例的静态标识符(用于替代 key_identifier_file)""
key_ringstring本插件所管理的密钥所在的密钥环(key ring)的资源 ID,格式为 projects/*/locations/*/keyRings/*""
service_account_filestring用于向 Cloud KMS API 认证的服务账号(service account)文件路径。环境变量 GOOGLE_APPLICATION_CREDENTIALS 的值。

向 Cloud KMS API 认证

插件使用应用默认凭据(Application Default Credentials)向 Google Cloud KMS API 认证,如 Setting Up Authentication For Server to Server 所述。当 SPIRE Server 运行在 GCP 内部时,它会使用其所在实例可用的默认服务账号凭据。当运行在 GCP 外部,或需要使用非默认凭据时,可以通过 GOOGLE_APPLICATION_CREDENTIALS 环境变量或 service_account_file 配置项(见配置)来指定包含凭据的服务账号文件路径。

密钥版本的使用

在 Cloud KMS 中,用于签名数据的加密密钥材料存储在密钥版本(CryptoKeyVersion)中。一个密钥(CryptoKey)可以有零个或多个密钥版本。

对于 server 管理的每一个 SPIRE Key ID,本插件都维护一个 CryptoKey。当密钥轮换时,会向该 CryptoKey 添加一个新的 CryptoKeyVersion,而被轮换掉的 CryptoKeyVersion 会被安排销毁(destruction)。

密钥的管理

插件会为它所管理的 CryptoKey 分配标签(label)以便跟踪它们。使用这些标签还能在服务中执行列举(listing)操作时进行高效过滤。所有标签均以 spire- 前缀命名。用户无需与插件管理的标签交互。下表仅供参考:

标签说明
spire-server-tdserver 信任域(trust domain)名称的 SHA-1 校验和(checksum)。
spire-server-idserver 的唯一标识符。由 key_identifier_filekey_identifier_value 配置项处理。
spire-last-update插件上一次更新该 CryptoKey 以保持其活跃状态的 Unix 时间。
spire-active指示该 CryptoKey 是否仍被插件使用。

插件需要一种方式来识别它正在其上运行的具体 server 实例。为此,必须使用 key_identifier_filekey_identifier_value 两者之一。设置**密钥标识文件(Key Identifier File)**会指示插件自动管理 server 的标识符,将 server ID 存储在指定 文件中。这种方式适用于大多数情况。如果配置了_密钥标识文件_而在 server 启动时未 找到该文件,则会以新的、自动生成的 server ID 重新创建该文件。因此,如果该文件丢 失,插件将无法识别它此前管理过的密钥,并会按需重新创建新密钥。

如果你需要对 server 所用的标识符有更多控制,可以使用 key_identifier_value 设置 来为 server 实例指定一个静态标识符。这种设置适用于无法持久化密钥标识文件的场景。

插件会尝试检测并清除陈旧(stale)的 CryptoKey。为便于陈旧 CryptoKey 检测,插件每 6 小时主动更新一次 server 所管理的所有 CryptoKey 上的 spire-last-update 标签。插件会周期性扫描 CryptoKey,查找信任域内那些 spire-last-update 值早于两周、且不属于本 server 的活跃 CryptoKey。这些陈旧 CryptoKey 对应的 CryptoKeyVersion 会被安排销毁,并且该 CryptoKey 的 spire-active 标签会被更新以指示其不再活跃。此外,如果插件检测到某个 CryptoKey 没有任何处于启用状态的 CryptoKeyVersion,它也会更新该 CryptoKey 的 spire-active 标签,将其设为非活跃。

所需权限

插件要求在配置的密钥环上向已认证的服务账号授予以下 IAM 权限:

text
cloudkms.cryptoKeys.create
cloudkms.cryptoKeys.getIamPolicy
cloudkms.cryptoKeys.list
cloudkms.cryptoKeys.setIamPolicy
cloudkms.cryptoKeys.update
cloudkms.cryptoKeyVersions.create
cloudkms.cryptoKeyVersions.destroy
cloudkms.cryptoKeyVersions.get
cloudkms.cryptoKeyVersions.list
cloudkms.cryptoKeyVersions.useToSign
cloudkms.cryptoKeyVersions.viewPublicKey

IAM 策略

Google Cloud 资源以层级方式组织,资源会继承其父资源的允许策略(allow policy)。插件会为它创建的 CryptoKey 设置一个默认 IAM 策略。此外也可以定义用户自定义的 IAM 策略。某个 CryptoKey 的有效允许策略是插件在该资源上设置的允许策略与其从父级继承的允许策略的并集。

默认 IAM 策略

插件为所创建的 CryptoKey 定义了一个默认 IAM 策略。该策略将已认证的服务账号与 Cloud KMS CryptoKey Signer/Verifier(roles/cloudkms.signerVerifier)预定义角色绑定。

json
{
    "bindings": [
        {
            "role": "roles/cloudkms.signerVerifier",
            "members": [
                "serviceAccount:SERVICE_ACCOUNT_EMAIL"
            ]
        }
    ],
    "version": 3
}

roles/cloudkms.signerVerifier 角色授予以下权限:

text
cloudkms.cryptoKeyVersions.useToSign
cloudkms.cryptoKeyVersions.useToVerify
cloudkms.cryptoKeyVersions.viewPublicKey
cloudkms.locations.get
cloudkms.locations.list
resourcemanager.projects.get

自定义 IAM 策略

用户也可以定义一个自定义 IAM 策略,它会被附加到所创建的 CryptoKey 上。如果设置了可配置项 key_policy_file,插件会使用该文件中定义的策略来替代默认策略。自定义 IAM 策略必须使用版本 3来定义。

插件配置示例

hcl
KeyManager "gcp_kms" {
    plugin_data {        
        key_ring = "projects/project-id/locations/location/keyRings/keyring"
        key_metadata_file = "./gcpkms-key-metadata"
    }
}

支持的密钥类型

插件支持 SPIRE 支持的所有密钥类型:rsa-2048rsa-4096ec-p256ec-p384