KSE: Encode and Decode Kubernetes Secrets from the CLI
A Golang CLI tool to encode and decode Kubernetes Secrets while preserving YAML file order and supporting multiple secrets in a single file.
Introduction
Managing Kubernetes Secrets is a daily task for anyone working with container orchestration. The built-in kubectl approach of base64-encoding values works, but it becomes tedious when you’re dealing with multiple secrets across different files, or when you need to quickly inspect a secret’s actual values without manually decoding each field.
KSE (Kubernetes Secret Encoding) is a CLI tool built in Go that simplifies this workflow. It handles both encoding and decoding, preserves YAML file order, supports multiple secrets in a single file, and works with stdin, files, or entire directories.
Why Another Secret Tool?
The usual workflow looks like this:
1
2
3
4
5
6
7
8
# To decode a single secret
kubectl get secret my-secret -o yaml | grep "password:"
# Copy the encoded value to use, e.g., decode it with base64 -d
echo "c3VwZXJzZWNyZXQ=" | base64 -d
# To encode a new secret
echo -n "supersecret" | base64
This works for one-off tasks, but breaks down when:
- You have a directory of secret manifests and need to decode all of them
- You want to preserve the original YAML structure and ordering
- You’re piping secrets between tools in a CI/CD pipeline
- You’re working with multiple secrets in a single YAML file
KSE addresses these scenarios with a simpler interface.
Installation
1
2
3
4
5
# Via install script (requires jq and curl)
curl -fsSL https://raw.githubusercontent.com/leonardobiffi/kse/master/scripts/install.sh | sh
# Or with Go
go install github.com/leonardobiffi/kse@latest
Decoding Secrets
From a file or directory
1
2
3
4
5
# Decode all secrets in a directory
kse decode -o -f ./k8s/secrets/
# Decode a single file
kse decode -o -f ./k8s/secrets/production.yaml
The -o flag outputs the decoded result to stdout. The tool recursively finds all Secret resources in the target path.
From stdin
1
2
3
4
5
# From kubectl directly
kubectl get secret my-secret -o yaml | kse decode
# From a file via cat
cat secret.yaml | kse decode
This makes it easy to integrate into pipelines:
1
kubectl get secrets -n production -o yaml | kse decode | grep -i password
Encoding Secrets
Encoding works the same way, just in reverse:
1
2
3
4
5
# Encode all secrets in a directory
kse encode -o -f ./k8s/secrets/
# Encode from stdin
cat plain-secret.yaml | kse encode
The tool expects the input to have plaintext stringData fields and converts them to base64-encoded data fields, which is what Kubernetes expects.
How It Works
KSE looks for Kubernetes Secret resources (kind: Secret) in your YAML files and:
- Decode: Reads the
datafield (base64), decodes each value, and outputs the secret withstringDatapopulated - Encode: Reads the
stringDatafield, base64-encodes each value, and outputs the secret withdatapopulated
It preserves:
- YAML key ordering (using
gopkg.in/yaml.v3) - Comments in the original file
- Multiple Secret resources in a single file
- All other Secret metadata (labels, annotations, type)
Example
Input (encoded secret):
1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
name: database-credentials
namespace: production
type: Opaque
data:
username: YWRtaW4=
password: c3VwZXJzZWNyZXQ=
After kse decode:
1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
name: database-credentials
namespace: production
type: Opaque
stringData:
username: admin
password: supersecret
Conclusion
KSE fills a specific gap: making Kubernetes Secret encoding/decoding a one-command operation that works with the file-based workflows many teams already use. If you’re managing secrets as YAML manifests in Git (GitOps), it removes the friction of constantly switching between base64 and plaintext.
Try it out: go install github.com/leonardobiffi/kse@latest