A multi KMS solution supporting the Kubernetes Provider Plugin data encryption for Secrets and ConfigMap in etcd.
Key Features • Why • Documentation • Press • Hands-on Lab • How to test • Roadmap • Contributing • License • Security
- Kubernetes native - no additional CLI tooling, respectful of the concern APIs (like Secrets, ConfigMap, ...)
- Encryption of sensitive data payload on the fly and store in etcd
- Multi KMS support - one KMS or two KMS at the same time[1]
- HashiCorp Vault (Community and Enterprise editions)
- AWS Key Vault
- Azure KeyVault
- Redesign to full micro-service architecture decloupling the core components for maximum resiliency and distributed handling
- proxy socket to address the Kubernetes API request for encryption/decryption
- trousseau to handle the proxy requests and KMS interaction
- KMS socket to address the connection towards the KMS providers
- Prometheus endpoint
Notes:
- Trousseau will use each KMS provider to encrypt the data and combine both payload within the same secret data section.
This design is provide more resiliency in case of a KMS failure by introducing reduancy, and add a fast decryption appraoch with first to response decryption approach along with roundrobin.
At the current stade, there is no option to have multi KMS configured and targeting one specific entry for scenario like multi-tenancy and/or multi-staging environment. This is due to a missing annotation extension within the Kubernetes API that we have address to the Kubernetes project.(see issue #146)
Clone the repo and create your environment file:
TR_VERSION=d3e4f2569b2eddeea992e47dae29a931182379dd
TR_VERBOSE_LEVEL=1
TR_SOCKET_LOCATION=/opt/trousseau-kms
TR_PROXY_IMAGE=ghcr.io/ondat/trousseau:proxy-${TR_VERSION}
TR_TROUSSEAU_IMAGE=ghcr.io/ondat/trousseau:trousseau-${TR_VERSION}
# Please configure your KMS plugins, maximum 2
TR_ENABLED_PROVIDERS="--enabled-providers=awskms --enabled-providers=azurekms --enabled-providers=vault"
TR_AWSKMS_IMAGE=ghcr.io/ondat/trousseau:awskms-${TR_VERSION}
TR_AWSKMS_CONFIG=awskms.yaml # For Kubernetes, file must exists only for generation
TR_AWSKMS_CREDENTIALS=.aws/credentials
TR_AZUREKMS_IMAGE=ghcr.io/ondat/trousseau:azurekms-${TR_VERSION}
TR_AZUREKMS_CONFIG=azurekms.yaml # For Kubernetes, file must exists only for generation
TR_AZUREKMS_CREDENTIALS=config.json
TR_VAULT_IMAGE=ghcr.io/ondat/trousseau:vault-${TR_VERSION}
TR_VAULT_ADDRESS=https://127.0.0.1:8200
TR_VAULT_CONFIG=vault.yaml
Create shared items on target host:
mkdir -p $TR_SOCKET_LOCATION
sudo chown 10123:10123 $TR_SOCKET_LOCATION
sudo chown 10123:10123 $TR_AWSKMS_CREDENTIALS
# On case you haven't enable Vault agen config generation
sudo chown 10123:10123 $TR_VAULT_CONFIG
Create your config files:
# awskms.yaml
profile: profile
keyArn: keyArn
# Optional fields
roleArn: roleArn
encryptionContext:
foo: bar
# azurekms.yaml
configFilePath: configFilePath
keyVaultName: keyVaultName
keyName: keyName
keyVersion: keyVersion
# vault.yaml
keyNames:
- keyNames
address: address
token: token
Generate service files or manifests:
make prod:generate:systemd ENV_LOCATION=./bin/trousseau-env
make prod:generate:docker-compose ENV_LOCATION=./bin/trousseau-env
make prod:generate:kustomize ENV_LOCATION=./bin/trousseau-env
make prod:generate:helm ENV_LOCATION=./bin/trousseau-env
Verify output:
ls -l generated_manifests/systemd
ls -l generated_manifests/docker-compose
ls -l generated_manifests/kustomize
ls -l generated_manifests/helm
Deploy the application and configure encryption:
kind: EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
resources:
- resources:
- secrets
providers:
- kms:
name: vaultprovider
endpoint: unix:///opt/trousseau-kms/proxy.socket
cachesize: 1000
- identity: {}
Reconfigure Kubernetes API server:
kind: ClusterConfiguration
apiServer:
extraArgs:
encryption-provider-config: "/etc/kubernetes/encryption-config.yaml"
extraVolumes:
- name: encryption-config
hostPath: "/etc/kubernetes/encryption-config.yaml"
mountPath: "/etc/kubernetes/encryption-config.yaml"
readOnly: true
pathType: File
- name: sock-path
hostPath: "/opt/trousseau-kms"
mountPath: "/opt/trousseau-kms"
Finally restart Kubernetes API server.