One is highly encouraged to be familiar with the following concepts before proceeding:
-
Vault’s Kubernetes authentication backend.
-
Vault’s GCP authentication backend.
kubernetes-vault-client
helps Kubernetes applications access Vault secrets in
a secure way. It runs as an
init container
that authenticates with Vault and dumps secrets as files to a shared volume:
-
kubernetes-vault-client
authenticates with Vault using agcp
orkubernetes
authentication backend by sending a signed token made available to the container. -
The target authentication backend verifies the authenticity of the signed token with Google Cloud IAM or the source Kubernetes cluster, respectively.
-
Upon successful authentication, Vault responds to
kubernetes-vault-client
with a Vault token that can be used to request secrets and certificates fromkv
[1] andpki
[2] secret backends, respectively. -
kubernetes-vault-client
then requests the necessary secrets and certificates from Vault, according to the provided configuration. -
Vault responds to
kubernetes-vault-client
with the requested secrets and certificates. -
kubernetes-vault-client
then dumps these secrets and certificates into a shared volume pre-configured in thePodSpec
— ideally one of typeemptyDir
and specmedium: Memory
— and exits. -
The application reads the necessary secrets and certificates from the
emptyDir
volume when necessary.
The easiest way to build kubernetes-vault-client
is to build the included
Dockerfile
with Docker ≥ 17.06:
$ docker build -t kubernetes-vault-client:latest .
Sending build context to Docker daemon 165MB
Step 1/8 : FROM golang:1.9.2-alpine AS builder
(...)
Successfully built 8793dbaf2b20
Successfully tagged kubernetes-vault-client:latest
kubernetes-vault-client
reads its configuration from an YAML file. The actual
format of the YAML file is dependent on the type of authentication being used —
iam
or kubernetes
— but it must conform to a well-defined schema:
address: <string>
auth:
type: (iam|kubernetes)
backend: <string>
data: ({iam-cfg}|{kubernetes-cfg})
mode:
name: initC
data:
kv:
- path: <string>
key: <string>
mountPath: <string>
(...)
pki:
- mountName: <string>
role: <string>
cn: <string>
sans:
- <string>
(...)
cnIsIdentifier: (true|false)
mountDir: <string>
(...)
A description of each property is given in the following table:
Property | Description |
---|---|
|
The address where Vault can be reached. |
|
The type of authentication being used (either |
|
The mount path of the target authentication backend in Vault. |
|
Backend-specific configuration (see below). |
|
The fixed value |
|
A list of requests for secrets from |
|
The full path to the requested secret in Vault (i.e., |
|
The requested key. |
|
The path where the value will be mounted. It should be a path inside the shared volume. |
|
A list of requests for secrets from |
|
The path to the |
|
The name of the role being requested. |
|
The common name ( |
|
An optional list of subject alternative names requested for the certificate. May include both hostnames and IP addresses. |
|
Whether the requested |
|
The path where the certificate bundle will be mounted. It should be a path inside the shared volume. |
Authentication with a Kubernetes backend is the simplest form of configuration. It takes a single configuration property:
Property | Description |
---|---|
|
The role to be used when authenticating with the |
One should note that if RBAC is enabled in the cluster where
kubernetes-vault-client
will be deployed, the service account and namespace
under which kubernetes-vault-client
will run must be authorized to perform
token review operations. For instance, if kubernetes-vault-client
runs
under the my-application
service account in the my-namespace
namespace, a
ClusterRoleBinding
similar to the following must be created for Kubernetes
authentication to work:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: my-application-my-namespace-tokenreview-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: my-application
namespace: my-namespace
address: https://vault.example.com
auth:
type: kubernetes
backend: kubernetes
data:
role: test-role
mode:
name: initC
data:
kv:
- path: secret/foo
key: one
mountPath: /secret/foo/one
- path: secret/foo
key: two
mountPath: /secret/foo/two
- path: secret/bar
key: one
mountPath: /secret/bar/one
pki:
- mountName: intermediate-ca
role: my-application
cn: my-application.my-namespace.svc.cluster.local
sans:
- my-application.my-namespace
- my-application
- localhost
- 127.0.0.1
cnIsIdentifier: false
mountDir: /secret
Authentication with Google Cloud IAM requires three configuration properties:
Property | Description |
---|---|
|
The role to be used when authenticating with the |
|
The ID of the service account with which to authenticate against Google Cloud IAM. |
|
The path to the private key of the service account that will sign tokens on behalf of |
The .auth.data.signingServiceAccountKeyPath
property exists to support
use-cases where there is a "global" service account responsible for signing
tokens. For instance, one may wish to have a single vault-authn
service
account belonging to the project where Vault is deployed and use it to sign
tokens in several different projects. This service account must have the
roles/iam.serviceAccountKeyAdmin
and roles/iam.serviceAccountTokenCreator
in
each project where kubernetes-vault-client
is deployed.
address: https://vault.example.com
auth:
type: iam
backend: gcp
data:
role: test-role
serviceAccountId: my-app@my-project.iam.gserviceaccount.com
signingServiceAccountKeyPath: /credentials/vault-authn.json
mode:
name: initC
data:
kv:
- path: secret/foo
key: one
mountPath: /secret/foo/one
- path: secret/foo
key: two
mountPath: /secret/foo/two
- path: secret/bar
key: one
mountPath: /secret/bar/one
pki:
- mountName: intermediate-ca
role: my-application
cn: my-application.my-namespace.svc.cluster.local
sans:
- my-application.my-namespace
- my-application
- localhost
- 127.0.0.1
cnIsIdentifier: false
mountDir: /secret
kubernetes-vault-client
is meant to be deployed to a Kubernetes cluster, and
as such the preferred way to provide it with the configuration file is to use a
ConfigMap
:
apiVersion: v1
data:
config.yaml: |
address: https://vault.example.com
auth:
type: kubernetes
backend: kubernetes
data:
role: test-role
mode:
name: initC
data:
kv:
- path: secret/foo
key: one
mountPath: /secret/foo/one
kind: ConfigMap
metadata:
name: my-kubernetes-vault-client-config
kubernetes-vault-client
expects the configuration file to be present at
/config/config.yaml
. The path can be overriden using the --config
flag.
In order to debug kubernetes-vault-client
one may use the --debug
flag. This
will make the output more verbose, but will also disclose sensitive information
like Kubernetes and Vault tokens. One may use this flag whenever necessary when
testing the deployment of a given application, but must remember to remove it
before moving to production.
A comprehensive usage example of kubernetes-vault-client
can be found here.