From 40fe163224607686f27b4c19256105cbbf817009 Mon Sep 17 00:00:00 2001 From: KK Sriramadhesikan Date: Tue, 8 Aug 2017 22:09:14 -0700 Subject: [PATCH] Vaultproviderspec (#1) * Initial version of Vault KMS Provider * Renamed image file to be consistent with spec name * Brought spec inline with EnvelopeTransformer interfaces in PR 49350 * Wrap at 80 --- .../vault-based-kms-class-diagram.png | Bin 0 -> 9490 bytes .../vault-based-kms-provider.md | 302 ++++++++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 contributors/design-proposals/vault-based-kms-class-diagram.png create mode 100644 contributors/design-proposals/vault-based-kms-provider.md diff --git a/contributors/design-proposals/vault-based-kms-class-diagram.png b/contributors/design-proposals/vault-based-kms-class-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..13d57884e8fe85502f3c599987b785df0bf986d2 GIT binary patch literal 9490 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:vault:len(::):::`` + +* ```` represents api version in the providers configuration file. +* ``vault`` represents the KMS service *kind* value. It is a fixed value for Vault +based provider. +* ``KEK-key-name`` is determined from the vault service configuration in providers +configuration file +* ``KEK-key-version`` is an internal identifier used by vault to identify specific +key version used to encrypt and decrypt. Vault sends ``kek-key-version`` +prefixed with encrypted data in the response to an encrypt request. The +``kek-key-version`` will be stored as part of prefix and returned back to Vault +during a decrypt request. + +Of the above metadata, + +* ``EnvelopeTransformer`` will add +``k8s:enc:kms::vault:len(::)`` +* while the ``vaultEnvelopeService`` will add +``::``. + + +#### For each write of DEK +``EnvelopeTransformer`` will write encrypted DEK along with encrypted secret in +etcd. + +Here's the pseudocode for ``vaultEnvelopeService.encrypt()``, invoked on each +write of DEK. + + KEY_NAME = + PLAIN_DEK = + ENCRYPTED_DEK_WITH_KEY_VERSION = encrypt(base64(PLAIN_DEK), KEY_NAME) + + // output from vault will have an extra prefix "vault" (other than key version) which will be stripped. + + STORED_DEK = KEY_NAME: + +#### For each read of DEK +``EnvelopeTransformer`` will read encrypted DEK along with encrypted secret from +etcd + +Here's the pseudocode ``vaultEnvelopeService.decrypt()`` invoked on each read of +DEK. + + // parse the provider kind, key name and encrypted DEK prefixed with key version + KEY_NAME = //key-name from the prefix + ENCRYPTED_DEK_WITH_KEY_VERSION = //: from the stored value + + // add "vault" prefix to ENCRYPTED_DEK_WITH_KEY_VERSION as required by vault decrypt API + + base64Encoded = decrypt(vault:ENCRYPTED_DEK_WITH_KEY_VERSION, KEY_NAME) + + PLAIN_DEK = base64.Decode(base64Encoded) + +#### Example + + DEK = "the quick brown fox" + provider kind = "vault" + api version version = "v1" + Key name = "kube-secret-enc-key" + key version = v1 + ciphertext returned from vault = vault:v1:aNOTZn0aUDMDbWAQL1E31tH/7zr7oslRjkSpRW0+BPdMfSJntyXZNCAwIbkTtn0= + prefixed DEK used to tag secrets = vault:kube-secret-enc-key:v1:aNOTZn0aUDMDbWAQL1E31tH/7zr7oslRjkSpRW0+BPdMfSJntyXZNCAwIbkTtn0= + +### Configuration + +No new configuration file or startup parameter will be introduced. + +The vault provider will be specified in the existing configuration file used to +configure any of the encryption providers. The location of this configuration +file is identified by the existing startup parameter: +`--experimental-encryption-provider-config` . + +Vault provider configuration will be identified by value "**vault**" for the +``name`` attribute in ``kms`` provider. + +The actual configuration of the vault provider will be in a separate +configuration identified by the ``configfile`` attribute in the KMS provider. + +Here is a sample configuration file with the vault provider configured: + + kind: EncryptionConfig + apiVersion: v1 + resources: + - resources: + - secrets + providers: + - kms: + name: vault + cachesize: 10 + configfile: /home/myvault/vault-config.yaml + +#### Minimal required Configuration +The Vault based Provider needs the following configuration elements, at a +minimum: + +1. ``addr`` Vault service base endpoint eg. https://example.com:8200 +2. ``key-names`` list of names of the keys in Vault to be used. eg: key-name: +kube-secret-enc-key. + +Note : key name does not need to be changed if key is rotated in Vault, the +rotated key is identified by key version which is prefix to ciphertext. + +A new key can be added in the list. Encryption will be done using the first key +in the list. Decryption can happen using any of the keys in the list based on +the prefix to the encrypted DEK stored in etcd + +#### Authentication Configuration +##### Vault Server Authentication + +For the Kubernetes cluster to authenticate the vault server, if TLS is enabled : +1. ``ca-cert`` location of x509 certificate to authenticate the vault server eg: +``/var/run/kubernetes/ssl/vault.crt`` + +##### Client Authentication Choices + +For client authentication, one of following **must** be used: (provider will +reject the configuration if parameters for more than one authentication backends +are specified ) + +###### X509 based authentication +1. ``client-cert``: location of x509 certificate to authenticate kubernetes API +server to vault server eg. ``/var/run/kubernetes/ssl/valut-client-cert.pem`` +2. ``client-key`` : location of x509 private key to authenticate kubernetes API +server to vault server eg. ``/var/run/kubernetes/ssl/vault-client-key.pem`` + +Here's a sample configuration file with ``client-cert``: + + kind: EncryptionConfig + apiVersion: v1 + resources: + - resources: + - secrets + providers: + - kms: + kind: vault + apiVersion: v1 + cache-size: 100 + config: + addr: https://localhost:8200 + key-names: + - kube-secret-enc-key + ca-cert:/var/run/kubernetes/ssl/vault.crt + client-cert:/var/run/kubernetes/ssl/vault-client-cert.pem + client-key:/var/run/kubernetes/ssl/vault-client-key.pem + +###### Vault token based authentication +1. ``token`` : limited access vault token required by kubernetes API sever to +authenticate itself while making requests to vault eg: +8dad1053-4a4e-f359-2eab-d57968eb277f + +Here's a sample configuration file when using a Vault Token for authenticating +the Kubernetes cluster as a client to Vault: + + kind: EncryptionConfig + apiVersion: v1 + resources: + - resources: + - secrets + providers: + - kms: + kind: vault + apiVersion: v1 + cache-size: 100 + config: + addr: https://localhost:8200 + key-names: + - kube-secret-enc-key + ca-cert:/var/run/kubernetes/ssl/vault.crt + token: 8dad1053-4a4e-f359-2eab-d57968eb277f + +###### Vault AppRole based authentication +1. ``role-id`` : RoleID of the AppRole +2. ``secret-id`` : secret Id only if associated with the appRole. + +Here's a sample configuration file with Vault AppRole + kind: EncryptionConfig + apiVersion: v1 + resources: + - resources: + - secrets + providers: + - kms: + kind: vault + apiVersion: v1 + cache-size: 100 + config: + addr: https://localhost:8200 + key-names: + - kube-secret-enc-key + ca-cert: /var/run/kubernetes/ssl/vault.crt + role-id: db02de05-fa39-4855-059b-67221c5c2f63 + +## Key Generation and rotation +The KEK is generated in Vault and rotated using direct API call or CLI to Vault +itself. The Key never leaves the vault. + +Note that when a key is rotated, Vault does not allow to choose a different +encryption algorithm or key size. If a key for different encryption algorithm or +a different key size is desired, new key needs to be generated in Vault and the +corresponding key name be added in the configuration. Subsequent encryption will +be done using the first key in the list. Decryption can happen using any of the +keys in the list based on the prefix to the encrypted DEK. + +## Backward compatibility +1. Unencrypted secrets and secrets encrypted using other non-KMS providers will +continue to be readable upon adding vault as a new KMS provider. +2. If a Vault KMS is added as first provider, the secrets created or modified +thereafter will be encrypted by vault provider. + +## Performance +1. KMS provider framework uses LRU cache to minimize the requests to KMS for +encryption and decryption of DEKs. +2. Note that there will be a request to KMS for every cache miss causing a +performance impact. Hence, depending on the cache size, there will be a +performance impact. +3. Response time. + 4. will depend on choice of encryption algorithm and strength. + 5. will depend on specific vault configurations like storage backend, +authentication mechanism, token polices etc.