| name | sealed-secrets |
| description | Create sealed secrets for Kubernetes using kubeseal |
Sealed Secrets
Create encrypted sealed secrets for storing sensitive data in Git repositories.
Prerequisites
kubesealCLI installed- Access to Kubernetes cluster with sealed-secrets-controller
- kubectl configured with cluster access
Workaround for Network Issues
The sealed-secrets-controller may not be directly reachable due to network policies. Use port-forwarding as a workaround:
# Start port-forward in background
kubectl port-forward -n flux-system svc/sealed-secrets-controller 8080:8080 &
PF_PID=$!
sleep 3
# Fetch the certificate
CERT=$(curl -s http://localhost:8080/v1/cert.pem)
# Create and seal the secret using the certificate
cat <<EOF | kubeseal --cert <(echo "$CERT") --format yaml > sealed-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: my-namespace
type: Opaque
stringData:
key1: "value1"
key2: "value2"
EOF
# Clean up port-forward
kill $PF_PID 2>/dev/null || true
Process
1. Prepare the secret manifest
Create a standard Kubernetes Secret manifest with your sensitive data:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: target-namespace
type: Opaque
stringData:
api-key: "your-api-key"
password: "your-password"
For docker registry secrets:
apiVersion: v1
kind: Secret
metadata:
name: registry-secret
namespace: target-namespace
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64-encoded-docker-config>
2. Seal the secret
Using port-forward (recommended for our environment):
kubectl port-forward -n flux-system svc/sealed-secrets-controller 8080:8080 &
PF_PID=$!
sleep 3
CERT=$(curl -s http://localhost:8080/v1/cert.pem)
cat secret.yaml | kubeseal --cert <(echo "$CERT") --format yaml > sealed-secret.yaml
kill $PF_PID 2>/dev/null || true
3. Apply or commit the sealed secret
The sealed secret can be safely committed to Git:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: my-secret
namespace: target-namespace
spec:
encryptedData:
api-key: AgB...encrypted...
password: AgC...encrypted...
template:
metadata:
name: my-secret
namespace: target-namespace
type: Opaque
Common Secret Types
API Credentials
stringData:
api-key: "${API_KEY}"
private-key: |
${PRIVATE_KEY_CONTENT}
Docker Registry (GHCR)
# Get existing secret from another namespace
kubectl get secret ghcr-secret -n source-namespace -o jsonpath='{.data.\.dockerconfigjson}'
TLS Certificates
type: kubernetes.io/tls
data:
tls.crt: <base64-cert>
tls.key: <base64-key>
Troubleshooting
"Resource already exists and is not managed by SealedSecret"
Delete the existing secret first:
kubectl delete secret my-secret -n target-namespace
"illegal base64 data"
Ensure the encrypted data has no line breaks or extra whitespace. The sealed secret YAML should have the encrypted values on single lines.
Controller not reachable (502 Bad Gateway)
Use the port-forward workaround described above.
Notes
- Sealed secrets are namespace-scoped by default
- The encryption key is stored in the sealed-secrets-controller
- If the controller key rotates, old sealed secrets still work but you should re-seal with new key
- Always verify the sealed secret syncs correctly:
kubectl get sealedsecrets -n namespace