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.yamlCreate 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_CONFIGCreate 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: tokenGenerate 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-envVerify output:
ls -l generated_manifests/systemd ls -l generated_manifests/docker-compose ls -l generated_manifests/kustomize ls -l generated_manifests/helmDeploy 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.

