保险库配置操作员
该操作员帮助设置金库配置。主要意图是这样做,以便随后的pod可以消费所提供的秘密。
有两个主要原则贯穿于这个操作者的所有能力。
- 高保真API。该操作者暴露的CRD逐字段反映了Vault APIs。这是因为我们不想对用户将设置的各种配置工作流程做出任何假设。也就是说,Vault的API是非常广泛的,而且我们从足够的API覆盖面开始,以支持,我们认为,一些简单和非常常见的配置工作流程。
- 注意安全(毕竟我们在与安全工具集成)。为了防止凭证泄露,我们没有给操作者本身针对Vault的权限。该操作员暴露的所有API包含足够的信息,可以使用本地服务账户(存在API的命名空间的本地账户)对Vault进行验证。换句话说,一个名字空间的用户要想成功配置Vault,该名字空间的服务账户必须事先被赋予所需的Vault权限。
目前这个操作者支持以下CRD。
- 策略配置Vault策略
- VaultRole配置VaultKubernetes认证角色
- SecretEngineMount配置一个SecretEngine的挂载点。
- DatabaseSecretEngineConfig配置数据库秘密引擎的连接。
- DatabaseSecretEngineRole配置数据库秘密引擎角色
- RandomSecret在vaultkv秘密引擎中创建一个随机秘密,并使用PasswordPolicy生成一个密码字段。
认证部分
正如所讨论的,每个API都有一个认证部分,指定如何认证Vault。下面是一个例子。
authentication:
path: kubernetes
role: policy-admin
namespace: tenant-namespace
serviceAccount:
name: vaultsa
复制代码
path
字段指定了Kubernetes认证角色的安装路径。
role
字段指定了认证时要请求的角色。
namespace
字段指定了要使用的Vault命名空间(与Kubernetes命名空间无关)。这是可选的。
serviceAccount.name
指定在认证过程中使用哪个服务账户的令牌。
因此,上述配置大致对应于以下命令。
vault write [tenant-namespace/]auth/kubernetes/login role=policy-admin jwt=
复制代码
政策
Policy
CRD允许用户创建一个[Vault Policy],这里有一个例子。
apiVersion: redhatcop.redhat.io/v1alpha1
kind: Policy
metadata:
name: database-creds-reader
spec:
authentication:
path: kubernetes
role: policy-admin
policy: |
# Configure read secrets
path "/{{identity.entity.aliases.auth_kubernetes_804f1655.metadata.service_account_namespace}}/database/creds/+" {
capabilities = ["read"]
}
复制代码
注意,在这个策略中,我们根据连接服务账户的名称空间对路径进行了参数化。
VaultRole
VaultRole
,为Kubernetes认证挂载创建一个Vault认证角色,这里是一个例子。
apiVersion: redhatcop.redhat.io/v1alpha1
kind: VaultRole
metadata:
name: database-engine-admin
spec:
authentication:
path: kubernetes
role: policy-admin
path: kubernetes
policies:
- database-engine-admin
targetServiceAccounts:
- vaultsa
targetNamespaceSelector:
matchLabels:
postgresql-enabled: "true"
复制代码
path
字段指定了Kubernetes认证挂载的路径,该角色将被挂载在该处。
policies
字段指定了哪些Vault策略将与该角色相关联。
targetServiceAccounts
字段指定了哪些服务账户可以进行认证。如果没有指定,它默认为default
。
targetNamespaceSelector
字段指定了可以从哪些kubernetes命名空间进行认证。注意随着选择器选择的命名空间集的变化,这个配置将被更新。也可以指定一个静态的命名空间集。
许多其他标准的Kubernetes认证角色字段可用于微调,见Vault文档
这个CR大致等同于这个Vault CLI命令。
vault write [namespace/]auth/kubernetes/role/database-engine-admin bound_service_account_names=vaultsa bound_service_account_namespaces=
复制代码
SecretEngineMount
SecretEngineMount
CRD允许用户创建一个秘密引擎挂载点,下面是一个例子。
apiVersion: redhatcop.redhat.io/v1alpha1
kind: SecretEngineMount
metadata:
name: database
spec:
authentication:
path: kubernetes
role: database-engine-admin
type: database
path: postgresql-vault-demo
复制代码
type
字段指定了秘密引擎的类型。
path
字段指定了安装秘密引擎的路径。
许多其他标准的秘密引擎挂载字段可用于微调,见Vault文档。
这个CR大致等同于这个Vault CLI命令。
vault secrets
复制代码
DatabaseSecretEngineConfig
DatabaseSecretEngineConfig
CRD允许用户创建一个数据库秘密引擎配置,也称为现有数据库秘密引擎安装的连接。下面是一个例子
apiVersion: redhatcop.redhat.io/v1alpha1
kind: DatabaseSecretEngineConfig
metadata:
name: my-postgresql-database
spec:
authentication:
path: kubernetes
role: database-engine-admin
pluginName: postgresql-database-plugin
allowedRoles:
- read-write
- read-only
connectionURL: postgresql://{{username}}:{{password}}@my-postgresql-database.postgresql-vault-demo.svc:5432
username: admin
rootCredentialsFromSecret:
name: postgresql-admin-password
path: postgresql-vault-demo/database
复制代码
pluginName
字段指定了这个连接是用于什么类型的数据库。
allowedRoles
字段指定了哪些角色名称可以为这个连接创建。
connectionURL
字段指定了如何连接到数据库。
username
字段指定用于连接到数据库的用户名。这个字段是可选的,如果不指定,用户名将从凭证秘密中获取。
path
字段指定了该连接将被添加到的秘密引擎的路径。
密码和可能的用户名可以通过三种不同的方式来获取。
- 从Kubernetes秘密,指定
rootCredentialsFromSecret
字段。该秘密必须是基本认证类型的。如果秘密被更新,这个连接也会被更新。 - 从Vault的秘密,指定
rootCredentialsFromVaultSecret
字段。 - 从一个RandomSecret,指定
rootCredentialsFromRandomSecret
字段。当RandomSecret生成一个新的秘密时,这个连接也将被更新。
许多其他标准的数据库秘密引擎配置字段可用于微调,见Vault文档
这个CR大致相当于这个Vault CLI命令。
vault write [namespace/]auth/kubernetes/role/database-engine-admin bound_service_account_names=vaultsa bound_service_account_namespaces= <动态生成> policies=database-engine-admin
[](#databasesecretenginerole)DatabaseSecretEngineRole
-----------------------------------------------------
`DatabaseSecretEngineRole` CRD允许用户创建一个数据库秘密引擎角色,这里是一个例子。
apiVersion: redhatcop.redhat.io/v1alpha1
kind: DatabaseSecretEngineRole
metadata:
name: read-only
spec:
authentication:
path: kubernetes
role: database-engine-admin
path: postgresql-vault-demo/database
dBName: my-postgresql-database
creationStatements:
- CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";
复制代码
path
字段指定了将包含这个角色的秘密引擎的路径。
dBname
字段指定了与该角色一起使用的连接的名称。
creationStatements
字段指定了要运行的语句,以创建一个新账户。
许多其他标准的数据库秘密引擎角色字段可用于微调,见Vault文档
这个CR大致等同于这个Vault CLI命令。
vault write [namespace/]postgresql-vault-demo/database/config/my-postgresql-database plugin_name=postgresql-database-plugin allowed_roles="read-write,read-only" connection_url="postgresql://{{username}}:{{password}}@my-postgresql-database.postgresql-vault-demo.svc:5432/" username=<retrieved dynamically> password=<retrieved dynamically>
复制代码
RandomSecret
RandomSecret CRD允许用户生成一个随机的秘密(通常是一个密码),并将其存储在Vault的一个给定的密钥中。生成的秘密将符合Vault的[密码策略],这里有一个例子。
apiVersion: redhatcop.redhat.io/v1alpha1
kind: RandomSecret
metadata:
name: my-postgresql-admin-password
spec:
authentication:
path: kubernetes
role: database-engine-admin
path: kv/vault-tenant
secretKey: password
secretFormat:
passwordPolicyName: my-complex-password-format
refreshPeriod: 1h
复制代码
path
字段指定了秘密将被写入的路径,它必须对应于kv秘密引擎的安装。
secretKey
字段是该秘密的密钥。
secretFormat
是对Vault Password策略的引用,它也可以内联提供。
refreshPeriod
指定了该秘密的再生频率。这是一个可选的字段,如果不指定,秘密将被生成一次,然后不再更新。
有了RandomSecret,就有可能建立工作流程,其中我们需要保护的资源的根密码永远不会存储在任何地方,除了保险库。实现这一点的一个方法是让一个随机秘密作为根密码的种子。然后创建一个操作者,观察RandomSecret,从保险库中检索生成的秘密,并更新要保护的资源。最后配置秘密引擎对象来监视RandomSecret的更新。
这个CR大致等同于这个Vault CLI命令。
vault kv put [namespace/]kv/vault-tenant password=
复制代码