Prerequisites: sealedsecret
kubeseal is the workstation half of the sealed-secrets system: a single static binary that turns a Secret manifest into a sealedsecret. It ships from the same repository as the controller (releases); keep its version close to the controller’s, the release notes flag when it matters.
What it actually does
kubeseal encrypts locally. It needs the controller’s public certificate, and by default it fetches that live over the Kubernetes API (so it needs a working kubeconfig), then encrypts each data/stringData field on your machine and prints the SealedSecret. The plaintext is never sent anywhere: not to the controller, not to the API server. The cluster first sees the credential at unseal time, when the controller decrypts it into a Secret.
To find the controller it assumes the upstream defaults: a service named sealed-secrets-controller in namespace kube-system. If the controller lives elsewhere every invocation needs --controller-name and --controller-namespace. Devata’s install deliberately matches the defaults (the reasoning is in installing-sealed-secrets) so a bare kubeseal works.
The canonical pipe
Never write a Secret manifest with the plaintext into a file you might commit. Generate it with kubectl --dry-run=client, which renders the manifest without creating anything on the cluster, and pipe it straight through:
kubectl create secret generic <name> -n <namespace> \
--from-literal=<key>=<value> \
--dry-run=client -o yaml | kubeseal -o yaml > <name>.yamlThe name and namespace in the dry-run are load-bearing: strict scope bakes both into the ciphertext (sealedsecret), so they must be the final ones. For a value that already lives in a file, prefer --from-file or a "$(...)" substitution over typing the literal, so the credential does not land in your shell history.
Sealing without the cluster
The public certificate is public material, so it can be saved and even committed:
kubeseal --fetch-cert > pub-cert.pem
kubeseal --cert pub-cert.pem -o yaml < secret.yamlWith --cert kubeseal touches nothing but the local file, so sealing works offline, away from the cluster network. One caveat from key renewal: after the controller rotates to a new key, a saved cert keeps producing valid ciphertext (the controller retains old private keys), but new seals should use the newest cert, so re-fetch it when convenient.
Scope selection (--scope namespace-wide, --scope cluster-wide) exists but devata sticks to the strict default; the tradeoff is in sealedsecret.