认证方法

不同的组织对安全和认证有不同的要求。Vault 通过提供多种认证方法来体现这一需求。Spring Cloud Vault 支持 Token 和 AppId 认证。

Token 认证

Token 是 Vault 中最核心的认证方法。Token 认证需要在配置中提供一个静态 Token。作为备选方案,Token 也可以从 ~/.vault-token 中检索,这是 Vault CLI 用于缓存 Token 的默认位置。

Token 认证是默认的认证方法。如果 Token 被泄露,未经授权的第三方将获得对 Vault 的访问权限,并可以访问目标客户端的秘密。
application.yml
spring.cloud.vault:
    authentication: TOKEN
    token: 00000000-0000-0000-0000-000000000000
  • authentication 将此值设置为 TOKEN 会选择 Token 认证方法

  • token 设置要使用的静态 Token。如果缺失或为空,则将尝试从 ~/.vault-token 检索 Token。

另请参阅

Vault Agent 认证

自版本 0.11.0 起,Vault 附带了一个名为 Vault Agent 的 sidecar 工具。Vault Agent 实现了 Spring Vault 的 SessionManager 功能,并具有 Auto-Auth 特性。应用程序可以通过依赖在 localhost 上运行的 Vault Agent 来重用缓存的会话凭据。Spring Vault 可以发送不带 X-Vault-Token 请求头的请求。禁用 Spring Vault 的认证基础设施可以禁用客户端认证和会话管理。

application.yml
spring.cloud.vault:
    authentication: NONE
  • authentication 将此值设置为 NONE 会禁用 ClientAuthenticationSessionManager

另请参阅:Vault 文档:Agent

AppId 认证

Vault 支持 AppId 认证,它由两个难以猜测的 Token 组成。AppId 默认使用静态配置的 spring.application.name。第二个 Token 是 UserId,它由应用程序决定,通常与运行时环境相关。IP 地址、Mac 地址或 Docker 容器名称都是很好的例子。Spring Cloud Vault Config 支持 IP 地址、Mac 地址和静态 UserId(例如通过系统属性提供)。IP 和 Mac 地址以 Hex 编码的 SHA256 哈希值表示。

基于 IP 地址的 UserId 使用本地主机的 IP 地址。

使用 SHA256 IP 地址 UserId 的 application.yml
spring.cloud.vault:
    authentication: APPID
    app-id:
        user-id: IP_ADDRESS
  • authentication 将此值设置为 APPID 会选择 AppId 认证方法

  • app-id-path 设置要使用的 AppId mount 路径

  • user-id 设置 UserId 方法。可能的值包括 IP_ADDRESS, MAC_ADDRESS 或实现自定义 AppIdUserIdMechanism 的类名

从命令行生成 IP 地址 UserId 的相应命令是

$ echo -n 192.168.99.1 | sha256sum
包含 echo 的换行符会导致不同的哈希值,因此请确保包含 -n 标志。

基于 Mac 地址的 UserId 从绑定到本地主机的设备获取其网络设备。配置还允许指定一个 network-interface 提示来选择正确的设备。network-interface 的值是可选的,可以是接口名称或接口索引(从 0 开始)。

使用 SHA256 Mac 地址 UserId 的 application.yml
spring.cloud.vault:
    authentication: APPID
    app-id:
        user-id: MAC_ADDRESS
        network-interface: eth0
  • network-interface 设置获取物理地址的网络接口

从命令行生成 IP 地址 UserId 的相应命令是

$ echo -n 0AFEDE1234AC | sha256sum
Mac 地址指定为大写且不含冒号。包含 echo 的换行符会导致不同的哈希值,因此请确保包含 -n 标志。

自定义 UserId

UserId 生成是一个开放机制。您可以将 spring.cloud.vault.app-id.user-id 设置为任意字符串,配置的值将用作静态 UserId。

更高级的方法允许您将 spring.cloud.vault.app-id.user-id 设置为一个类名。该类必须位于您的 classpath 中,并且必须实现 org.springframework.cloud.vault.AppIdUserIdMechanism 接口和 createUserId 方法。每次使用 AppId 认证以获取 Token 时,Spring Cloud Vault 都将通过调用 createUserId 来获取 UserId。

application.yml
spring.cloud.vault:
    authentication: APPID
    app-id:
        user-id: com.examlple.MyUserIdMechanism
MyUserIdMechanism.java
public class MyUserIdMechanism implements AppIdUserIdMechanism {

  @Override
  public String createUserId() {
    String userId = ...
    return userId;
  }
}

AppRole 认证

AppRole 旨在用于机器认证,类似于已弃用(自 Vault 0.6.1 起)的 AppId 认证。AppRole 认证由两个难以猜测(秘密)的 Token 组成:RoleId 和 SecretId。

Spring Vault 支持各种 AppRole 场景(推/拉模式和 wrapped 模式)。

RoleId 和可选的 SecretId 必须通过配置提供,Spring Vault 不会查找或创建自定义 SecretId。

包含 AppRole 认证属性的 application.yml
spring.cloud.vault:
    authentication: APPROLE
    app-role:
        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52

以下场景及其所需的配置详情是支持的

表 1. 配置

方法

RoleId

SecretId

RoleName

Token

提供的 RoleId/SecretId

提供

提供

提供 RoleId,不含 SecretId

提供

提供 RoleId,Pull SecretId

提供

提供

提供

Pull RoleId,提供的 SecretId

提供

提供

提供

完全 Pull 模式

提供

提供

Wrapped

提供

Wrapped RoleId,提供的 SecretId

提供

提供

提供的 RoleId,wrapped SecretId

提供

提供

表 2. Pull/Push/Wrapped 矩阵

RoleId

SecretId

支持

提供

提供

提供

Pull

提供

Wrapped

提供

缺失

Pull

提供

Pull

Pull

Pull

Wrapped

Pull

缺失

Wrapped

提供

Wrapped

Pull

Wrapped

Wrapped

Wrapped

缺失

您仍然可以通过在上下文中提供配置好的 AppRoleAuthentication bean 来使用推/拉/wrapped 模式的所有组合。Spring Cloud Vault 无法从配置属性中推导出所有可能的 AppRole 组合。
AppRole 认证仅限于使用响应式基础设施的简单拉取(pull)模式。完全拉取模式尚不受支持。将 Spring Cloud Vault 与 Spring WebFlux 堆栈一起使用会启用 Vault 的响应式自动配置,可以通过设置 spring.cloud.vault.reactive.enabled=false 来禁用它。
包含所有 AppRole 认证属性的 application.yml
spring.cloud.vault:
    authentication: APPROLE
    app-role:
        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52
        secret-id: 1696536f-1976-73b1-b241-0b4213908d39
        role: my-role
        app-role-path: approle
  • role-id 设置 RoleId。

  • secret-id 设置 SecretId。如果 AppRole 配置为不需要 SecretId(参见 bind_secret_id),则可以省略 SecretId。

  • role: 在拉取(pull)模式下设置 AppRole 名称。

  • app-role-path 设置要使用的 approle 认证 mount 路径。

AWS-EC2 认证

aws-ec2 认证后端为 AWS EC2 实例提供了一种安全的引入机制,允许自动检索 Vault Token。与大多数 Vault 认证后端不同,此后端不需要首先部署或配置安全敏感凭据(Token、用户名/密码、客户端证书等)。相反,它将 AWS 视为一个可信第三方,并使用唯一代表每个 EC2 实例的经过加密签名的动态元数据信息。

使用 AWS-EC2 认证的 application.yml
spring.cloud.vault:
    authentication: AWS_EC2

AWS-EC2 认证默认启用 nonce,以遵循首次使用信任(Trust On First Use,TOFU)原则。任何意外获得 PKCS#7 身份元数据访问权限的第三方都可以对 Vault 进行认证。

在首次登录期间,Spring Cloud Vault 会生成一个 nonce,该 nonce 与实例 Id 一起存储在认证后端中。重新认证需要发送相同的 nonce。任何其他第三方没有该 nonce,并可以在 Vault 中触发警报以供进一步调查。

nonce 保存在内存中,并在应用程序重启时丢失。您可以使用 spring.cloud.vault.aws-ec2.nonce 配置一个静态 nonce。

AWS-EC2 认证角色是可选的,默认使用 AMI。您可以通过设置 spring.cloud.vault.aws-ec2.role 属性来配置认证角色。

包含配置的角色的 application.yml
spring.cloud.vault:
    authentication: AWS_EC2
    aws-ec2:
        role: application-server
包含所有 AWS EC2 认证属性的 application.yml
spring.cloud.vault:
    authentication: AWS_EC2
    aws-ec2:
        role: application-server
        aws-ec2-path: aws-ec2
        identity-document: http://...
        nonce: my-static-nonce
  • authentication 将此值设置为 AWS_EC2 会选择 AWS EC2 认证方法

  • role 设置尝试登录时使用的角色名称。

  • aws-ec2-path 设置要使用的 AWS EC2 mount 路径

  • identity-document 设置 PKCS#7 AWS EC2 身份文档的 URL

  • nonce 用于 AWS-EC2 认证。空的 nonce 默认为生成 nonce

AWS-IAM 认证

aws 后端为 AWS IAM 角色提供了一种安全的认证机制,允许基于运行中应用程序的当前 IAM 角色自动与 Vault 进行认证。与大多数 Vault 认证后端不同,此后端不需要首先部署或配置安全敏感凭据(Token、用户名/密码、客户端证书等)。相反,它将 AWS 视为一个可信第三方,并使用调用方使用其 IAM 凭据签名的 4 条信息来验证调用方是否确实在使用该 IAM 角色。

运行中应用程序的当前 IAM 角色会自动计算。如果您在 AWS ECS 上运行应用程序,则应用程序将使用分配给运行中容器的 ECS 任务的 IAM 角色。如果您在 EC2 实例上直接运行应用程序,则使用的 IAM 角色将是分配给该 EC2 实例的角色。

使用 AWS-IAM 认证时,您必须在 Vault 中创建一个角色并将其分配给您的 IAM 角色。空的 role 默认为当前 IAM 角色的友好名称。

包含必需的 AWS-IAM 认证属性的 application.yml
spring.cloud.vault:
    authentication: AWS_IAM
包含所有 AWS-IAM 认证属性的 application.yml
spring.cloud.vault:
    authentication: AWS_IAM
    aws-iam:
        region: aws-global
        role: my-dev-role
        aws-path: aws
        server-name: some.server.name
        endpoint-uri: https://sts.eu-central-1.amazonaws.com
  • region 设置 AWS 区域名称。如果未提供,区域将由 AWS 默认设置确定。

  • role 设置尝试登录时使用的角色名称。此角色应绑定到您的 IAM 角色。如果未提供,则当前 IAM 用户的友好名称将用作 Vault 角色。

  • aws-path 设置要使用的 AWS mount 路径

  • server-name 设置用于 X-Vault-AWS-IAM-Server-ID 请求头的值,以防止某些类型的重放攻击。

  • endpoint-uri 设置用于 iam_request_url 参数的 AWS STS API 的值。

AWS-IAM 需要 AWS Java SDK v2 依赖项(software.amazon.awssdk:auth),因为认证实现使用 AWS SDK 类型处理凭据和请求签名。

Azure MSI 认证

azure 认证后端为 Azure VM 实例提供了一种安全的引入机制,允许自动检索 Vault Token。与大多数 Vault 认证后端不同,此后端不需要首先部署或配置安全敏感凭据(Token、用户名/密码、客户端证书等)。相反,它将 Azure 视为一个可信第三方,并使用可以绑定到 VM 实例的托管服务身份和实例元数据信息。

包含必需的 Azure 认证属性的 application.yml
spring.cloud.vault:
    authentication: AZURE_MSI
    azure-msi:
        role: my-dev-role
包含所有 Azure 认证属性的 application.yml
spring.cloud.vault:
    authentication: AZURE_MSI
    azure-msi:
        role: my-dev-role
        azure-path: azure
        metadata-service: http://169.254.169.254/metadata/instance…
        identity-token-service: http://169.254.169.254/metadata/identity…
  • role 设置尝试登录时使用的角色名称。

  • azure-path 设置要使用的 Azure mount 路径

  • metadata-service 设置访问实例元数据服务的 URI

  • identity-token-service 设置访问身份 Token 服务的 URI

Azure MSI 认证从实例元数据服务获取有关虚拟机(订阅 Id、资源组、VM 名称)的环境详细信息。Vault 服务器的 Resource Id 默认值为 vault.hashicorp.com。要更改此设置,请相应地设置 spring.cloud.vault.azure-msi.identity-token-service

另请参阅

TLS 证书认证

cert 认证后端允许使用由 CA 签名或自签名的 SSL/TLS 客户端证书进行认证。

要启用 cert 认证,您需要

  1. 使用 SSL,参见 Vault 客户端 SSL 配置

  2. 配置包含客户端证书和私钥的 Java Keystore

  3. spring.cloud.vault.authentication 设置为 CERT

application.yml
spring.cloud.vault:
    authentication: CERT
    ssl:
        key-store: classpath:keystore.jks
        key-store-password: changeit
        key-store-type: JKS
        cert-auth-path: cert

Cubbyhole 认证

Cubbyhole 认证使用 Vault 原语提供一个安全的认证工作流程。Cubbyhole 认证使用 Token 作为主要登录方法。一个临时 Token 被用来从 Vault 的 Cubbyhole secret 后端获取第二个,即登录 VaultToken。登录 Token 通常具有更长的生命周期,用于与 Vault 交互。登录 Token 将从存储在 /cubbyhole/response 的 wrapped 响应中检索。

创建 wrapped token

Token 创建的 Response Wrapping 需要 Vault 0.6.0 或更高版本。
创建和存储 tokens
$ vault token-create -wrap-ttl="10m"
Key                            Value
---                            -----
wrapping_token:                397ccb93-ff6c-b17b-9389-380b01ca2645
wrapping_token_ttl:            0h10m0s
wrapping_token_creation_time:  2016-09-18 20:29:48.652957077 +0200 CEST
wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319
application.yml
spring.cloud.vault:
    authentication: CUBBYHOLE
    token: 397ccb93-ff6c-b17b-9389-380b01ca2645

另请参阅

GCP-GCE 认证

gcp 认证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据进行 Vault 登录。

GCP GCE (Google Compute Engine) 认证为服务账户创建一个 JSON Web Token (JWT) 形式的签名。通过实例身份识别从 GCE 元数据服务获取 Compute Engine 实例的 JWT。该 API 创建一个可用于确认实例身份的 JSON Web Token。

与大多数 Vault 认证后端不同,此后端不需要首先部署或配置安全敏感凭据(Token、用户名/密码、客户端证书等)。相反,它将 GCP 视为一个可信第三方,并使用唯一代表每个 GCP 服务账户的经过加密签名的动态元数据信息。

包含必需的 GCP-GCE 认证属性的 application.yml
spring.cloud.vault:
    authentication: GCP_GCE
    gcp-gce:
        role: my-dev-role
包含所有 GCP-GCE 认证属性的 application.yml
spring.cloud.vault:
    authentication: GCP_GCE
    gcp-gce:
        gcp-path: gcp
        role: my-dev-role
        service-account: [email protected]
  • role 设置尝试登录时使用的角色名称。

  • gcp-path 设置要使用的 GCP mount 路径

  • service-account 允许将服务账户 Id 覆盖为特定值。默认为 default 服务账户。

另请参阅

GCP-IAM 认证

gcp 认证后端允许使用现有的 GCP (Google Cloud Platform) IAM 和 GCE 凭据进行 Vault 登录。

GCP IAM 认证为服务账户创建一个 JSON Web Token (JWT) 形式的签名。通过调用 GCP IAM 的 projects.serviceAccounts.signJwt API 获取服务账户的 JWT。调用方向 GCP IAM 进行认证,从而证明其身份。此 Vault 后端将 GCP 视为一个可信第三方。

IAM 凭据可以从运行时环境获取(特别是 GOOGLE_APPLICATION_CREDENTIALS 环境变量)、Google Compute 元数据服务,或通过外部提供(例如 JSON 或 base64 编码)。JSON 是首选格式,因为它包含调用 projects.serviceAccounts.signJwt 所需的项目 ID 和服务账户标识符。

包含必需的 GCP-IAM 认证属性的 application.yml
spring.cloud.vault:
    authentication: GCP_IAM
    gcp-iam:
        role: my-dev-role
包含所有 GCP-IAM 认证属性的 application.yml
spring.cloud.vault:
    authentication: GCP_IAM
    gcp-iam:
        credentials:
            location: classpath:credentials.json
            encoded-key: e+KApn0=
        gcp-path: gcp
        jwt-validity: 15m
        project-id: my-project-id
        role: my-dev-role
        service-account-id: [email protected]
  • role 设置尝试登录时使用的角色名称。

  • credentials.location 凭据资源的路径,该资源包含 JSON 格式的 Google 凭据。

  • credentials.encoded-key OAuth2 账户私钥的 base64 编码内容,为 JSON 格式。

  • gcp-path 设置要使用的 GCP mount 路径

  • jwt-validity 配置 JWT Token 的有效期。默认为 15 分钟。

  • project-id 允许将项目 Id 覆盖为特定值。默认为从获取的凭据中提取的项目 Id。

  • service-account 允许将服务账户 Id 覆盖为特定值。默认为从获取的凭据中提取的服务账户。

GCP IAM 认证需要 Google Cloud Java SDK 依赖项(com.google.apis:google-api-services-iamcom.google.auth:google-auth-library-oauth2-http),因为认证实现使用 Google API 进行凭据和 JWT 签名。

Google 凭据需要一个维护 Token 生命周期长的 OAuth 2 Token。所有 API 都是同步的,因此 GcpIamAuthentication 不支持响应式使用所需的 AuthenticationSteps

另请参阅

Kubernetes 认证

Kubernetes 认证机制(自 Vault 0.8.3 起)允许使用 Kubernetes Service Account Token 与 Vault 进行认证。认证是基于角色的,角色绑定到服务账户名称和命名空间。

包含 pod 服务账户的 JWT token 的文件会自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token

包含所有 Kubernetes 认证属性的 application.yml
spring.cloud.vault:
    authentication: KUBERNETES
    kubernetes:
        role: my-dev-role
        kubernetes-path: kubernetes
        service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token
  • role 设置角色。

  • kubernetes-path 设置要使用的 Kubernetes mount 路径。

  • service-account-token-file 设置包含 Kubernetes Service Account Token 的文件的位置。默认为 /var/run/secrets/kubernetes.io/serviceaccount/token

另请参阅

Pivotal CloudFoundry 认证

pcf 认证后端为在 Pivotal 的 CloudFoundry 实例中运行的应用程序提供了一种安全的引入机制,允许自动检索 Vault Token。与大多数 Vault 认证后端不同,此后端不需要首先部署或配置安全敏感凭据(Token、用户名/密码、客户端证书等),因为身份提供由 PCF 本身处理。相反,它将 PCF 视为一个可信第三方,并使用托管实例身份。

包含必需的 PCF 认证属性的 application.yml
spring.cloud.vault:
    authentication: PCF
    pcf:
        role: my-dev-role
包含所有 PCF 认证属性的 application.yml
spring.cloud.vault:
    authentication: PCF
    pcf:
        role: my-dev-role
        pcf-path: path
        instance-certificate: /etc/cf-instance-credentials/instance.crt
        instance-key: /etc/cf-instance-credentials/instance.key
  • role 设置尝试登录时使用的角色名称。

  • pcf-path 设置要使用的 PCF mount 路径。

  • instance-certificate 设置 PCF 实例身份证书的路径。默认为 ${CF_INSTANCE_CERT} 环境变量。

  • instance-key 设置 PCF 实例身份密钥的路径。默认为 ${CF_INSTANCE_KEY} 环境变量。

PCF 认证需要 classpath 中包含 BouncyCastle (bcpkix-jdk15on) 才能进行 RSA PSS 签名。

ACL 要求

本节解释了 Spring Vault 访问哪些路径,以便您可以根据所需能力推导您的策略声明。

能力 关联的 HTTP 动词

创建

POST/PUT

读取

GET

更新

POST/PUT

删除

DELETE

列出

LIST (GET)

认证

登录:POST auth/$authMethod/login

KeyValue Mount 发现

GET sys/internal/ui/mounts/$mountPath

SecretLeaseContainer

SecretLeaseContainer 根据配置的 lease endpoint 使用不同的路径。

LeaseEndpoints.Legacy

  • 撤销:PUT sys/revoke

  • 续期:PUT sys/renew

LeaseEndpoints.Leases (SysLeases)

  • 撤销:PUT sys/leases/revoke

  • 续期:PUT sys/leases/renew

会话管理

  • Token 查找:GET auth/token/lookup-self

  • 续期:POST auth/token/renew-self

  • 撤销:POST auth/token/revoke-self