Encrypting Kubernetes Secrets With Sealed Secrets
By: Gaurav Agarwal
Tags: Programming, Software Engineering, Kubernetes, DevOps, Technology

‘SealedSecret’ Scopes

From the end-user perspective, a SealedSecret is a write-only device.

No one apart from the running controller can decrypt the SealedSecret , not even the author of the Secret .

It’s a general best practice to disallow users to have direct access to read secrets. You can create RBAC rules to forbid low-privilege users from reading Secrets . You can also restrict users to only be able to read Secrets from their namespace.

While the SealedSecrets are designed in a way that it’s impossible to read them directly, users can work around the process and gain access to secrets they’re not allowed to view.

SealedSecret resources provide multiple ways to prevent such misuse. They are namespace-aware by default. Once you generate a SealedSecret using kubeseal for a particular namespace, you can’t use the SealedSecret in another namespace.

For instance, if you create a Secret named foo with a value bar for namespace web , you can’t apply the Secret on the database namespace — even if it requires the same Secret .

It’s by design, as we can’t allow a user who has access to the database namespace to see Secrets from the web namespace by just applying the web namespace’s SealedSecrets on the database namespace. SealedSecrets behave as if every namespace has its own decryption key.

While Sealed Secret’s controller doesn’t use an independent private key for each namespace, it takes into consideration the namespace and name during the encryption process, which achieves the same result.

Another scenario is we might have a user on the web namespace who can only view certain secrets and not all of them. SealedSecrets allow this as well.

When you generate a SealedSecret for a Secret named foo for the web namespace, a user who just has read access to the Secret named bar on the web namespace can’t change the name of the Secret within the SealedSecret manifest to bar and apply it to view the Secret .

While these ways help you prevent people from misusing the Secrets , they may give you a management headache. In the default configuration, you won’t be able to define generic Secrets to be used in multiple namespaces.

You might not have a large team, and your Kubernetes cluster might be accessed and managed only by admins. Therefore, you may not need that level of role-based access control.

You also may want to define SealedSecrets that you can move across namespaces. You don’t want to manage multiple copies of SealedSecrets for the same Secret .

SealedSecrets allow these possibilities using scopes.

There are three scopes you can create your SealedSecrets with:

strict (default): In this case, you need to seal your Secret considering the name and the namespace. You can’t change the name and the namespaces of your SealedSecret once you've created it. If you try to do that, you get a decryption error.

(default): In this case, you need to seal your considering the name and the namespace. You can’t change the name and the namespaces of your once you've created it. If you try to do that, you get a decryption error. namespace-wide : This scope allows you to freely rename the SealedSecret within the namespace for which you’ve sealed the Secret .

: This scope allows you to freely rename the within the namespace for which you’ve sealed the . cluster-wide : This scope allows you to freely move the Secret to any namespace and give it any name you wish.

Apart from the name and namespace, you can rename the secret keys without losing any decryption capabilities.

You can select the scope with the --scope flag while using kubeseal :

$ kubeseal --scope cluster-wide --format yaml <secret.yaml >sealed-secret.yaml

You can also use annotations within your Secret to apply scopes before you pass the configuration to kubeseal :

sealedsecrets.bitnami.com/namespace-wide: "true" for namespace-wide

for sealedsecrets.bitnami.com/cluster-wide: "true" for cluster-wide