Troussseau Architecture
Trousseau: KMS Provider with Plugin for external KMS
Overview
The Kubernetes API Server can encrypt the sensitve data from Secrets using the KMS Provider. In this scenario, an external KMS is used to encrypt in-flight the Data Encryption Key using to encrypt the sensitive data. This process is called an encryption envelop scheme.
The Trousseau project is providing an implementation of the Plugin component allowing the interaction of the API Server KMS Provider with an external KMS Server. The current list of supported KMS Servers is available within the release notes.
When creating the Secret with kubectl apply -f mysecret.yml
, the following flow will be triggered:
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant kube-controller-manager
participant kube-scheduler
end
box Compute Node
participant kubelet
participant container runtime
participant Pod
end
autonumber
User or App->>kube-apiserver: create Pod
kube-apiserver->>etcd: store Pod specs
kube-apiserver->>kube-controller-manager: reconcile desired state
kube-controller-manager->>kube-apiserver: current state different than desired
kube-apiserver->>kube-scheduler: create Pod
kube-scheduler->>kube-apiserver: available node
kube-apiserver->>etcd: store node specs
kube-apiserver->>kubelet: bind Pod to node
kubelet->>container runtime: run Pod
container runtime->>Pod: status
container runtime->>kubelet: OK
kubelet->>kube-apiserver: Pod status
kube-apiserver->>etcd: store Pod status
kube-apiserver->>User or App: Pod created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
end
autonumber
User or App->>kube-apiserver: create Secret
Note right of User or App: base64 encoded data
kube-apiserver->>etcd: store Secret
kube-apiserver->>User or App: Secret created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant kube-controller-manager
participant kube-scheduler
end
box Compute Node
participant kubelet
participant container runtime
participant Pod
end
autonumber
User or App->>kube-apiserver: create Pod
kube-apiserver->>etcd: store Pod specs
kube-apiserver->>kube-controller-manager: reconcile desired state
kube-controller-manager->>kube-apiserver: current state different than desired
kube-apiserver->>kube-scheduler: create Pod
kube-scheduler->>kube-apiserver: available node
kube-apiserver->>etcd: store Node specs
kube-apiserver->>kubelet: bind Pod to node
kubelet->>container runtime: run Pod
kubelet->>kube-apiserver: get Secret
kube-apiserver->>kubelet: put Secret
container runtime->>kubelet: OK
kubelet->>kube-apiserver: Pod status
kube-apiserver->>etcd: store Pod status
kube-apiserver->>User or App: Pod created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
end
autonumber
User or App->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: identity
kube-apiserver->>etcd: store base64-encoded Secret
kube-apiserver->>User or App: Secret created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
end
autonumber
User or App->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: aesgcm
kube-apiserver->>kube-apiserver: encrypt Secret with key
kube-apiserver->>etcd: store encrypted Secret
kube-apiserver->>User or App: Secret created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
participant KMS Plugin
end
participant KMS Server
autonumber
User or App->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: KMSv1
kube-apiserver->>kube-apiserver: generate a dedicated DEK per object
kube-apiserver->>kube-apiserver: encrypt Secret with DEK
kube-apiserver->>KMS Plugin: encrypt DEK with KMS KEK
KMS Plugin->>KMS Server: encrypt DEK
KMS Server->>KMS Server: encrypt DEK with KEK
KMS Plugin->>kube-apiserver: return encrypted DEK
kube-apiserver->>etcd: store encrypted Secret and encrypted DEK
kube-apiserver->>User or App: Secret created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
participant KMS Plugin
end
participant KMS Server
autonumber
User or App->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: KMSv2
opt if no existing DEK
kube-apiserver->>kube-apiserver: generate a DEK
kube-apiserver->>KMS Plugin: encrypt DEK with KMS KEK
KMS Plugin->>KMS Server: encrypt DEK
KMS Server->>KMS Server: encrypt DEK with KEK
KMS Plugin->>kube-apiserver: return encrypted DEK
kube-apiserver->>etcd: store encrypted DEK
end
kube-apiserver->>kube-apiserver: encrypt Secret with DEK
kube-apiserver->>etcd: store encrypted Secret
kube-apiserver->>User or App: Secret created
sequenceDiagram
participant User or App
box Control Plane
participant etcd
participant kube-apiserver
participant KMS Provider
participant KMS Plugin
end
participant KMS Server
autonumber
User or App->>kube-apiserver: create Secret
kube-apiserver->>KMS Provider: request to encrypt Secret
Note left of KMS Provider: generate a DEK
Note left of KMS Provider: encrypt Secret
KMS Provider->>KMS Plugin: hand off the DEK for encryption
KMS Plugin->>KMS Server: encrypt DEK with KEK from KMS
KMS Plugin->>KMS Provider: return encrypted DEK with KID
KMS Provider->>kube-apiserver: return encrypted DEK with KID
kube-apiserver->>etcd: store Secrets and DEK both encrypted
sequenceDiagram
participant User
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
autonumber
User->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: aesgcm
kube-apiserver->>kube-apiserver: encrypt Secret with key
kube-apiserver->>etcd: store encrypted Secret
sequenceDiagram
participant User
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
participant KMS Plugin
participant KMS Server
autonumber
User->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: KMSv1
kube-apiserver->>kube-apiserver: generate a dedicated DEK per object
kube-apiserver->>kube-apiserver: encrypt Secret with DEK
kube-apiserver->>KMS Plugin: encrypt DEK with KMS KEK
KMS Plugin->>KMS Server: encrypt DEK
KMS Server->>KMS Server: encrypt DEK with KEK
KMS Plugin->>kube-apiserver: return encrypted DEK
kube-apiserver->>etcd: store encrypted Secret and encrypted DEK
sequenceDiagram
participant User
participant etcd
participant kube-apiserver
participant EncryptionConfiguration
participant KMS Plugin
participant KMS Server
autonumber
User->>kube-apiserver: create Secret
kube-apiserver->>EncryptionConfiguration: which provider?
EncryptionConfiguration->>kube-apiserver: KMSv2
opt if no DEK
kube-apiserver->>kube-apiserver: generate a DEK
kube-apiserver->>KMS Plugin: encrypt DEK with KMS KEK
KMS Plugin->>KMS Server: encrypt DEK
KMS Server->>KMS Server: encrypt DEK with KEK
KMS Plugin->>kube-apiserver: return encrypted DEK
kube-apiserver->>etcd: store encrypted DEK
end
kube-apiserver->>kube-apiserver: encrypt Secret with DEK
kube-apiserver->>etcd: store encrypted Secret
Software Components
Trousseau
Trousseau deploys as a container on the Control Plane node. It will create a temporary Unix socket instantiating a gRPC server that the KMS Provider component from Kubernetes API Server will be able to communicate with.
Vault Agent
Trousseau leverages a sidecar with the HashiCorp Vault Agent to recover the Transit Engine parameters. This allows to avoid direct exposure to the Encryption Transit Engine.
Vault
Trousseau requires a KMS like HashiCorp Vault to provide access to a Transit Encryption Engine for the Kubernetes KMS Provider.
Kubernetes Components
ServiceAccount
A ServiceAccount is created to using a certificate token used for a mutual authentication with the HashiCorp Vault instance. This is leverage by the sidecar to recover the Transit Engine parameters.
ConfigMap
A ConfigMap is used by the HashiCorp Vault Agent sidecar to hand over the Encryption Transit Engine parameters to Trousseau. The following parameters are expected:
- the Transit Engine Endpoint
- the Transit Engine Key name
- the Transit Engine dedicated access Token
DaemonSet
Trousseau deploys as a DaemonSet to guarantee that every Control Plane node will have a running instance with its gRPC server addressing any potential partitioning that could occur during the Control Plane lifetime.
Trousseau Architecture Workflow
Kubernetes & Vault Configuration
sequenceDiagram
participant k8s
participant vault
autonumber
k8s->>vault: ServiceAccount for Kubernetes Auth
k8s->>k8s: RBAC rules
Note right of vault: Enable Transit Engine
Note right of vault: Create Transit Key
Note right of vault: Create Transit policy
Note right of vault: Create Token linked to policy
Note right of vault: Create Key-Value storing config
vault->>k8s: Bind vault config to Trousseau Specs
Trousseau Deployment
sequenceDiagram
participant k8s
participant trousseau
participant vault
autonumber
Note over k8s,trousseau: Deployment
k8s->>trousseau: Apply Trousseau DaemonSet
Note right of trousseau: Vault Agent Sidecar
trousseau->>vault: Recover Trousseau ConfigMap config
vault->>trousseau: Inject Transit Engine Key config
loop Healthcheck
trousseau->>vault: check Vault connection
vault->>trousseau: report Vault connection
end
Trousseau Operations
sequenceDiagram
participant k8s
participant trousseau
participant vault
autonumber
Note over k8s,vault: Encryption Operation
k8s->>trousseau: kube-manager sent Secret for Encryption
trousseau->>vault: Encrypt Secret payload with Transit Key
trousseau->>k8s: Send encrypted payload to kube-manager
Note over k8s,vault: Decryption Operation
k8s->>trousseau: kube-manager sent Secret for Decryption
trousseau->>vault: Decrypt Secret payload with Transit Key
trousseau->>k8s: Send decrypted payload to kube-manager
Vault Token Renewal
sequenceDiagram
participant k8s
participant trousseau
participant vault
autonumber
Note over k8s,vault: Token Rotation
vault->>vault: Renew Token
Note right of vault: Update Key-Value config
k8s->>trousseau: Delete all Trousseau POD
Note right of trousseau: Vault Agent Sidecar
trousseau->>vault: Recover Trousseau ConfigMap config
vault->>trousseau: Inject Transit Engine Key config
loop Healthcheck
trousseau->>vault: validate Vault connection
end