Template `data` field treated as `stringData`, `stringData` ignored
javajawa opened this issue · comments
Which component:
Isuse with controller, tested against v0.19.3
and 0.25.0
of docker.io/bitnami/sealed-secrets-controller
as deployed by Helm.
Describe the bug
When supplying a template Secret to the SealedSecret, the data
field is treated as if it was stringData
, and any stringData
field is ignored.
To Reproduce
First example -- data
is treated as if stringData
cat >secret.yaml <<EOF
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: hello
namespace: default
spec:
encryptedData: {}
template:
data:
bar: Y2F0Cg==
baz: hello
EOF
kubectl apply -f secret.yaml
kubectl get secret hello -o yaml | yq '.data | map_values(@base64d)'
kubectl delete -f secret.yaml
Expected
Either an error from trying to create a Secret where data is not base64
or { "bar": "Y2F0Cg==" }
Actual
bar: Y2F0Cg==
baz: hello
Second point -- stringData
is ignored from the template.
cat >secret.yaml <<EOF
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: hello
namespace: default
spec:
encryptedData: {}
template:
stringData:
bar: Y2F0Cg==
baz: hello
EOF
kubectl apply -f secret.yaml
kubectl get secret hello -o yaml | yq '.data | map_values(@base64d)'
kubectl delete -f secret.yaml
Expected
bar: Y2F0Cg==
baz: hello
Actual
[] # (empty)
Version of Kubernetes:
- Output of
kubectl version
:
Client Version: v1.29.1
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.26.11-eks-8cb36c9
Just realised I haven't included any context as to why this is relevant when the secret should be sealed, because that was originally in a slack thread.
The use case this was discovered by was setting up manual sharing in argocd in an incident response -- cluster connections are secrets, which are managed as sealed secrets. We discovered that we could get these in without having to encrypt them by adding them to the template.
This led to the question "is adding unencrypted values to the template a feature". The one answer I got over on the slack channel was "probably?".
It would be good to know what the expected behaviour is to make some secrets a lot less opaque -- going back to the Argo example, three of the four values (cluster name, url, and shard) are public knowledge (and are duplicated by our helm chart to the annotations) and having those not be large encrypted blobs improves readability.
More so than the bug itself, I'd like clarity on whether this is even a valid use, along the lines of:
- sealed secrets explicitly does not support data in templates, any use is undefined behaviour
- it's supported, but a special case where only data is unused and is unencrypted, as this reduced validation complexity (current behaviour)
- it is supported, and will follow the Secret semantics in some future version
Hi @javajawa thanks for the detailed report. Let us check this out and we'll get back to you with an explanation for the issue you're observing
This Issue has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thanks for the feedback.
Thank you bot! I am continuing to interact with this thread :3
I have a bit more time this week to actually look at the code myself, and reading through the codebase the behaviour is well defined. .spec.template.data
is treated as a source of go template strings that are rendered using the encrypted data as the source
sealed-secrets/pkg/apis/sealedsecrets/v1alpha1/sealedsecret_expansion.go
Lines 290 to 302 in 686b148
There is a concrete example in docs/examples/config-template linked from a not especially obvious section of the readme.
This is mentioned in the schema (and derived helm CRD, but the swagger docs are a lot less clear. There's also a line in the helm helper.tpl which may or may not be setting a default template context?
Overall conclusions:
- The behaviour is well defined
- The behaviour is supported
- The behaviour is documented (but only easy to find with a code search).
- The behaviour is not the "least surprising", and should probably be documented slightly better
I have put a proposed documentation update in #1456 -- but I'm doing so without a clear understanding of why this feature is "unadvertised". There may be a historical decision I am missing here.
Additionally, I feel that that bug
label doesn't apply here any more and should be replaced with the documentation
label.