A Kubernetes init Docker image for authenticating against Vault
100K+
This Docker image is designed to bootstrap the Vault secrets in a Kubernetes pods. This uses the Kubernetes Auth Method to request the secrets required to generate an AppRole Auth role id and secret id.
This will then authenticate against the AppRole and provide the Vault token in a file that can be sourced by other containers that share the volume.
This is useful to externalise the Vault authentication from the containers you want to run. When used in conjunction with the Kubernetes Vault Auth Renewer, then the secrets can be injected into a container and renewed for as long as the pod is running, without the main container requiring any knowledge of Vault. This allows you to run public docker images without modification.
A vault installation with the following auth methods enabled and configured:
The Kubernetes auth method must be configured with a policy
This grants access to the AppRole role-id and secret-id which is required to generate an auth token for accessing secrets.
path "auth/approle/role/my-app-role/role-id" {
capabilities = ["read"]
}
path "auth/approle/role/my-app-role/secret-id" {
capabilities = ["update"]
}
This grants read access to the secrets our application needs.
path "consul/creds/my-acl-policy" {
capabilities = ["read"]
}
path "secret/some/secret" {
capabilities = ["read"]
}
This should have a limited lifespan as it is only needed to bootstrap the AppRole.
vault write auth/kubernetes/role/my-kube-role \
bound_service_account_names=my-app-service-account \
bound_service_account_namespaces=my-namespace \
policies=my-app-role-login-policy \
ttl=300 \
max_ttl=300 \
num_uses=3
The 'secret_id_ttl' and 'secret_id_num_uses' should be kept limited, as we only used it to get a token.
We want a periodic token - this means that as long as it is renewed it never expires. 'Period' should be set with consideration to how often you want to renew the token. If you are going to check if it needs renewing 6 hours, then a sensible period might be 24 hours. Read the AppRole documentation to customise the other options based on your requirements.
vault write auth/approle/role/my-app-role \
secret_id_ttl=5m \
secret_id_num_uses=3 \
period=24h \
bound_cidr_list="10.0.0.0/32" \
bind_secret_id="true" \
policies="my-app-role-policy"
This is designed to be run as a Kubernetes init container, which means that it is run and terminates before the main pod containers are started. This allows us to request access to Vault and the secrets before the container starts.
The init container requires the following environmental variables:
The following are optional:
Any environment variables that start with 'SECRET_' are used to request secrets from Vault. The value must be the path to retrieve a secret from in Vault, with the data key optionally provided.
For example:
SECRET_CONSUL_TOKEN=consul/creds/my-acl-policy?token
Will create:
CONSUL_TOKEN=some-consul-acl-token
Where 'some-consul-acl-token' is stored in the the 'token' attribute of the following secret: consul/creds/my-acl-policy
Or
If there are multiple variables for the same vault path then only one request is made and all data keys are retrieved from the same Vault response. This is useful in the case of requesting access to secret backends, like a database, where you need more one field to access the resource.
For example:
SECRET_DATABASE_USER=database/creds/readonly?username
SECRET_DATABASE_PASSWORD=database/creds/readonly?password
Will create:
DATABASE_USER=some-database-username
DATABASE_PASSWORD=some-database-password
Where 'some-database-password' corresponds to the temporary user 'some-database-username' in the configured database.
Or:
SECRET_SOME_SECRET=secret/from/somewhere
Will create:
SOME_SECRET=some-secret-value
Where 'some-secret-value' is stored in the the 'value' attribute of the following secret: secret/from/somewhere
The output from this container is written to a file called /env/variables.
To make use of these you should mount this as a volume shared between this init container and your main
application container and then run source /env/variables as part of your containers command.
The outputs are:
kubectl apply -f myfile.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-service-account
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: my-app
spec:
template:
metadata:
labels:
app: my-app
tier: backend
spec:
serviceAccountName: my-app-service-account
volumes:
- name: shared-data
emptyDir: {}
initContainers:
- name: vault-init
image: wealthwizardsengineering/kube-vault-auth-init
env:
- name: KUBERNETES_AUTH_PATH
value: "kubernetes"
- name: VAULT_ADDR
value: "https://vault.example.com"
- name: VAULT_LOGIN_ROLE
value: "my-app-role"
- name: SECRET_SOME_SECRET
value: "secret/from/somewhere"
volumeMounts:
- name: shared-data
mountPath: /env
containers:
- name: my-app
image: my-app
command: ["/bin/sh", "-c", "source /env/variables; ./run-my-app.sh"]
volumeMounts:
- name: shared-data
mountPath: /env
Content type
Image
Digest
Size
3.8 MB
Last updated
over 7 years ago
docker pull wealthwizardsengineering/kube-vault-auth-init