PR #375 closed #363, but the secret is still exposed in the rendered manifest.
Security impact
A secret (e.g. an OTel auth/Bearer token) is written in plaintext into the Deployment, readable by anyone with get on the Deployment.
Mechanism
The env var is emitted in components/tyk-gateway/templates/deployment-gw-repset.yaml as an inline value::
- name: TYK_GW_OPENTELEMETRY_HEADERS
value: "{{ include "otel-headers" . }}"
#375 (files changed) only touched the otel-headers helper in components/tyk-gateway/templates/_helpers.tpl and the values.yaml comments. It left that inline value: site untouched, and the helper now does a lookup + b64dec at render time:
{{- $secret := lookup "v1" "Secret" $.Release.Namespace $value.fromSecret.name -}}
{{- $secretValue := index $secret.data $value.fromSecret.key | b64dec -}}
{{- $headersList = append $headersList (printf "%s:%s" $key $secretValue) -}}
b64dec-ing a secret into a string that is then inlined as value: is the exposure. The result is visible in kubectl get deploy -o yaml and helm get manifest.
Reproduce (no cluster needed)
A direct-string header skips lookup and renders under helm template, proving the consumption site inlines the header string:
helm template tyk tyk-helm/tyk-data-plane \
--set tyk-gateway.gateway.opentelemetry.enabled=true \
--set tyk-gateway.gateway.opentelemetry.headers.Authorization="Bearer supersecrettoken" \
| grep -A1 TYK_GW_OPENTELEMETRY_HEADERS
Output:
- name: TYK_GW_OPENTELEMETRY_HEADERS
value: "Authorization:Bearer supersecrettoken"
fromSecret feeds the same helper and the same inline value: (see Mechanism), with the secret lookup-ed and b64dec-ed in first.
Expected
A reference, not a value:
- name: TYK_GW_OPENTELEMETRY_HEADERS
valueFrom:
secretKeyRef:
name: otel-auth-example
key: authorization
Why it's not a one-line swap
TYK_GW_OPENTELEMETRY_HEADERS is a single env var holding a joined key:value,key:value string, and K8s can't build one env var from multiple secretKeyRefs. The fix: when a header uses fromSecret, emit valueFrom and have that secret key hold the full formatted header string. Remove the lookup/b64dec path.
Environment
tyk-data-plane chart (latest); applies to any chart embedding the tyk-gateway otel-headers helper. The helm template repro above was run on Helm 4.2.0.
References
PR #375 closed #363, but the secret is still exposed in the rendered manifest.
Security impact
A secret (e.g. an OTel auth/Bearer token) is written in plaintext into the Deployment, readable by anyone with
geton the Deployment.Mechanism
The env var is emitted in
components/tyk-gateway/templates/deployment-gw-repset.yamlas an inlinevalue::#375 (files changed) only touched the
otel-headershelper incomponents/tyk-gateway/templates/_helpers.tpland the values.yaml comments. It left that inlinevalue:site untouched, and the helper now does alookup+b64decat render time:b64dec-ing a secret into a string that is then inlined asvalue:is the exposure. The result is visible inkubectl get deploy -o yamlandhelm get manifest.Reproduce (no cluster needed)
A direct-string header skips
lookupand renders underhelm template, proving the consumption site inlines the header string:Output:
fromSecretfeeds the same helper and the same inlinevalue:(see Mechanism), with the secretlookup-ed andb64dec-ed in first.Expected
A reference, not a value:
Why it's not a one-line swap
TYK_GW_OPENTELEMETRY_HEADERSis a single env var holding a joinedkey:value,key:valuestring, and K8s can't build one env var from multiplesecretKeyRefs. The fix: when a header usesfromSecret, emitvalueFromand have that secret key hold the full formatted header string. Remove thelookup/b64decpath.Environment
tyk-data-plane chart (latest); applies to any chart embedding the tyk-gateway
otel-headershelper. Thehelm templaterepro above was run on Helm 4.2.0.References
deployment-gw-repset.yaml)