Search code examples
securityencryptionkubernetesstorageetcd

What kind of security does `identity` provider in Kubernetes EncryptionConfiguration provide?


Ref: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers

According to the docs

Resources written as-is without encryption. When set as the first provider, the resource will be decrypted as new values are written.

When set as the first provider, the resource will be decrypted as new values are written. sounds confusing. If resources are written as is with no encryption into etcd, why does decrypted as new values are written mean ?

And following that

By default, the identity provider is used to protect secrets in etcd, which provides no encryption.

What kind of security does identity provider give if no encryption happens and if encryption happens, what kind of encryption is it?


Solution

  • As stated in etcd about security

    Does etcd encrypt data stored on disk drives?

    No. etcd doesn't encrypt key/value data stored on disk drives. If a user need to encrypt data stored on etcd, there are some options:

    • Let client applications encrypt and decrypt the data
    • Use a feature of underlying storage systems for encrypting stored data like dm-crypt

    First part of the question:

    By default, the identity provider is used to protect secrets in etcd, which provides no encryption. It means that by default k8s api is using identity provider while storing secrets in etcd and it doesn't provide any encryption.

    Using EncryptionConfiguration with the only one provider: identity gives you the same result as not using EncryptionConfiguration at all (assuming you didn't have any encrypted secrets before at all). All secret data will be stored in plain text in etcd.

    Example:

        providers:
        - identity: {}
    

    Second part of your question:

    Resources written as-is without encryption. This is described and explained in the first part of the question

    When set as the first provider, the resource will be decrypted as new values are written.

    Take a look at this example:

        providers:
        - aescbc:
            keys:
            - name: key1
              secret: <BASE 64 ENCODED SECRET>
        - identity: {}
    

    What this configuration means for you:

    • The new provider introduced into your EncryptionConfiguration does not affect existing data.
    • All existing secrets in etcd (before this configuration has been applied) are still in plain text.
    • Starting with this configuration all new secrets will be saved using aescbc encryption. All new secrets in etcd will have prefix k8s:enc:aescbc:v1:key1.
    • In this scenario you will have in etcd a mixture of encrypted and not encrypted data.

    So the question is why we are using those two providers?

    • provider: aescbc is used to write new secrets as encrypted data during write operation and to decrypt existing secrets during read operation.
    • provider: identity is still necessary to read all not encrypted secrets.

    Now we are switching our providers in EncryptionConfiguration:

        providers:
        - identity: {}
        - aescbc:
            keys:
            - name: key1
              secret: <BASE 64 ENCODED SECRET>
    
    • In this scenario you will have in etcd a mixture of encrypted and not encrypted data.
    • Starting with this configuration all new secrets will be saved in plain text
    • For all existing secrets in etcd with prefix k8s:enc:aescbc:v1:key1 provider: aescbc configuration will be used to decrypt existing secrets stored in etcd.

    When set as the first provider, the resource will be decrypted as new values are written

    In order to switch from mixture of encrypted and not encrypted data into scenario that we have only "not encrypted" data, you should perform read/write operation for all secrets:

    $ kubectl get secrets --all-namespaces -o json | kubectl replace -f -

    why's it there if it offers no encryption but the docs seem to talk about decryption and how it protects.

    It's necessary to have the provider type of identity if you have a mixture of encrypted and not encrypted data or if you want to decrypt all existing secrets (stored in etcd) encrypted by another provider.

    The following command reads all secrets and then updates them to apply server side encryption. More details can be found in this paragraph

    $ kubectl get secrets --all-namespaces -o json | kubectl replace -f -

    Depending on your EncryptionConfiguration, all secrets will be saved as not encrypted -if the first provider is: identity or encrypted if the first provider is different type.

    In addtion

    EncryptionConfig is disabled as default setting. To use it, you have to add --encryption-provider-config in your kube-apiserver configuration. Identity is not encrypting any data, as per Encrypted Providers documentation it has 3x N/A.