Create and recover sealed credentials
Sealed Secrets bridges Git and Kubernetes credentials. A public certificate encrypts the Secret; only the matching controller private key can decrypt it. Keep the original namespace, name, key names, and value formats aligned with the consuming application.
Choose the correct identity first
For an existing installation, restore its controller keys before reconciling encrypted resources. For a new installation, establish the controller, securely back up its identity, and seal fresh application credentials. Copying another installation’s SealedSecret YAML does not create usable credentials for a new key.
The current controller is sealed-secrets-controller in namespace sealed-secrets.
kubeseal --kubeconfig kubeconfig \ --controller-name sealed-secrets-controller \ --controller-namespace sealed-secrets \ --fetch-cert > /tmp/antalos-sealing-cert.pemThe certificate is public material. Verify that you are using the intended cluster before sealing credentials for it.
Create plaintext outside Git
This example produces the database owner Secret consumed by Authentik. Adapt the name, namespace, type, and keys together for a different consumer.
install -d -m 700 "$HOME/.kubernetes-secrets"umask 077Create $HOME/.kubernetes-secrets/authentik-db-app.yaml privately:
apiVersion: v1kind: Secretmetadata: name: authentik-db-app namespace: authentiktype: kubernetes.io/basic-authstringData: username: authentik password: REPLACE_WITH_A_UNIQUE_GENERATED_PASSWORDUse a password manager or cryptographically secure generator for the password, then insert it through a private editing workflow. stringData accepts plaintext; data expects base64-encoded values. Confusing the two can produce a generated Secret that the application cannot use.
Seal to the service directory
kubeseal \ --cert /tmp/antalos-sealing-cert.pem \ --scope strict \ --format yaml \ < "$HOME/.kubernetes-secrets/authentik-db-app.yaml" \ > apps/authentik/db-secret.yamlThe output is a SealedSecret. Under strict scope, changing its name or namespace later requires resealing. Do not rename ciphertext as a shortcut to deploying a second application.
Before replacing an existing file, preserve any annotations or additional SealedSecret documents that belong to it. If the service uses sync waves, place the wave annotation on the top-level SealedSecret metadata, so Argo CD orders the encrypted resource itself. An annotation only under spec.template.metadata is attached to the generated Secret and does not order the SealedSecret.
Match the consumer contract
| Credential type | What must agree |
|---|---|
| Database | Database role, password, connection URI encoding, and Secret key references |
| OIDC | Provider client ID, client secret, issuer/discovery URL, and callback URI |
| Redis Sentinel | Data authentication, replica authentication, Sentinel authentication, and client discovery settings |
| Application encryption | The original encryption/salt/session key and the data it protects |
| Structured configuration | The expected file format inside the Secret value, such as an OIDC provider document |
Changing a bootstrap database password Secret does not always rotate the password in an already initialized database. Follow the database’s documented rotation procedure, then update consumers together.
Inspect names and reconciliation status without dumping values:
/home/linuxbrew/.linuxbrew/bin/kubectl --kubeconfig kubeconfig \ -n authentik get sealedsecrets
/home/linuxbrew/.linuxbrew/bin/kubectl --kubeconfig kubeconfig \ -n authentik get secret authentik-db-appRestore controller keys
The bootstrap guide explains the OpenTofu key restore and its expected kubeconfig path. When restoring into an already existing namespace/controller installation:
/home/linuxbrew/.linuxbrew/bin/kubectl --kubeconfig kubeconfig \ apply -f sealed-secrets-priv-key.yaml
/home/linuxbrew/.linuxbrew/bin/kubectl --kubeconfig kubeconfig \ -n sealed-secrets rollout restart deployment/sealed-secrets-controllerA backup containing only a newer key cannot decrypt ciphertext made with a lost older key. Retain all keys still required by the repository.
Back up keys outside the cluster
umask 077/home/linuxbrew/.linuxbrew/bin/kubectl --kubeconfig kubeconfig \ -n sealed-secrets get secret \ -l sealedsecrets.bitnami.com/sealed-secrets-key \ -o yaml > "$HOME/.kubernetes-secrets/sealed-secrets-keys.yaml"Encrypt and copy that file to the external recovery location. The local file alone is not an off-cluster backup strategy. Refresh the backup after key rotation and prove it can decrypt representative ciphertext:
kubeseal --recovery-unseal \ --recovery-private-key "$HOME/.kubernetes-secrets/sealed-secrets-keys.yaml" \ < apps/authentik/db-secret.yaml \ > /dev/nullSee the official key backup and recovery documentation for the controller version in use.
