The goal of this project is to be able to use Sops encryption with Kubernetes Secrets so they can be stored safely in Git.
The controller is fairly simple, it decrypts the data
field of SopsSecret
objects and inserts it into a v1/Secret
object with the corresponding name
and namespace
.
There is a helper CLI to convert existing Secrets to SopsSecrets. The CLI can also be used to edit secrets from their encrypted form.
Examples of usage can be found in docs/cli/README.md
Kustomize base can be found in deploy/kustomize/base
Examples of deployments with Kustomize can be found in docs/examples
This controller is safe to uninstall if you follow a few steps first.
Set the environment variable DISABLE_FINALIZERS=true
.
Once this environment variable is set, let the controller restart and finish reconciling all objects.
(tail the logs and wait for it to stop)
Check your SopsSecret objects, they should no long haver a finalizer set on them.
Scale down the controller, this will prevent deletes just in case an object still somehow has a finalizer set. Delete the CRD, this should cause Kubernetes to garbage collect all SopsSecret objects in the cluster. All of the secrets created by the controller will remain.
There was a concious decision to not use OwnerReferences as they would make this process more difficult and are in general less safe for something as critical as Secrets.
This controller uses an ownership label. If the label is not set on a secret the controller will not modify the secret. This kind of label is common in other secret operators, but was also a requirement here because of the lack of OwnerReferences.
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
labels:
secrets.dhouti.dev/owned-by-controller: my-secret.default
The value of the label is ${Name}.${Namespace}
of the SopsScret object that created it.
If you wish to delete a SopsSecret object and have the Secret remain you can set skipFinalizers.
apiVersion: secrets.dhouti.dev/v1beta1
kind: SopsSecret
metadata:
name: my-secret
namespace: default
spec:
skipFinalizers: true
Once this value is set you can delete the SopsSecret object and the underlying secret will remain.
You can deploy a secret to different namespaces or as a different name using the template.
Usage:
apiVersion: secrets.dhouti.dev/v1beta1
kind: SopsSecret
metadata:
name: my-secret
namespace: default
spec:
template:
metadata:
name: new-secret
namespaces:
- example1
- example2
This would create a secret named new-secret
in the example1
and example2
namespaces and not the default
namespace.
If you do not specify spec.template.metadata.namespaces
it will be defaulted to the namespace the SopsSecret object is in.
If you do not specify .spec.template.metadata.name
it will be defaulted to the name of the SopsSecret object.
You can prevent the controller from managing keys in the output secret. One use case would be ArgoCD. ArgoCD creates some keys in secret objects on controller start, you can let argocd create them instead of specifying them yourself.
apiVersion: secrets.dhouti.dev/v1beta1
kind: SopsSecret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
spec:
ignoredKeys:
- tls.crt
- tls.key
- server.secretKey