From ae80d7779f9635c3be58a7c37deb56fbe3cd176f Mon Sep 17 00:00:00 2001 From: clippy Date: Sat, 3 Oct 2026 16:56:11 -0700 Subject: [PATCH] feat(helm): authenticate OTLP log export to a hosted collector `server.otlp.endpoint` can already point the gateway at a collector, but there is no way to authenticate to one. Any hosted collector needs a credential, and the gateway TOML has no `headers` field, so the only route into the process is the standard OpenTelemetry environment variable. Adds `server.otlp.headersSecret`, naming an existing Secret that holds the full header string, for example `authorization=ApiKey `. The value reaches the gateway as OTEL_EXPORTER_OTLP_HEADERS via secretKeyRef, so the token is never a chart value, never a rendered manifest literal, and never visible to `helm get values`. Inert unless `headersSecret.name` is set: with it empty the env var is not emitted at all, so existing deployments render byte-identically. `key` defaults to OTEL_EXPORTER_OTLP_HEADERS and can be overridden for a Secret that already carries the string under another name. Without this, exporting to anything other than an unauthenticated in-cluster collector is not expressible, which in practice means a fleet running on this chart has no telemetry it can ship anywhere durable. Signed-off-by: clippy Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01ReW6fW9rodn627GJ8a63S9 Signed-off-by: clippy --- deploy/helm/openshell/README.md | 2 ++ .../helm/openshell/templates/_gateway-workload.tpl | 14 ++++++++++++++ deploy/helm/openshell/values.yaml | 13 +++++++++++++ 3 files changed, 29 insertions(+) diff --git a/deploy/helm/openshell/README.md b/deploy/helm/openshell/README.md index 5426527d1d..c29a207123 100644 --- a/deploy/helm/openshell/README.md +++ b/deploy/helm/openshell/README.md @@ -451,6 +451,8 @@ discovery endpoint or its TLS CA. | server.oidc.userRole | string | `""` | Role name for standard user access. | | server.otlp.endpoint | string | `""` | OTLP/gRPC collector endpoint, conventionally using port 4317. | | server.otlp.exportLogs | bool | `false` | Also export gateway and sandbox logs (including OCSF events) as OTLP log records to the same endpoint. Drops are reported downstream as telemetry_gap records. | +| server.otlp.headersSecret.key | string | `""` | Key within that Secret. Defaults to OTEL_EXPORTER_OTLP_HEADERS. | +| server.otlp.headersSecret.name | string | `""` | Name of an existing Secret holding the OTLP header string. Empty disables the env var entirely. | | server.otlp.ocsfFullPayload | bool | `true` | Carry the structured OCSF document (ocsf.raw) on exported OCSF records. Set false to export only the shorthand line. | | server.otlp.serviceName | string | `""` | Gateway OpenTelemetry service name. Empty uses openshell-gateway. | | server.policyValidationFailureMode | string | `"fail_closed"` | Posture when a candidate sandbox policy fails validation. `fail_closed` deactivates the previous policy; `retain_last_valid` keeps it active. | diff --git a/deploy/helm/openshell/templates/_gateway-workload.tpl b/deploy/helm/openshell/templates/_gateway-workload.tpl index 919d3a4313..a9efcc452c 100644 --- a/deploy/helm/openshell/templates/_gateway-workload.tpl +++ b/deploy/helm/openshell/templates/_gateway-workload.tpl @@ -122,6 +122,20 @@ spec: - name: SSL_CERT_FILE value: /etc/openshell-tls/oidc-ca/ca.crt {{- end }} + {{- with .Values.server.otlp.headersSecret }} + {{- if .name }} + # OTLP collector authentication. The gateway reads the standard + # OpenTelemetry header variables; there is no `headers` field in the + # gateway TOML, so a hosted collector can only be authenticated through + # the process environment. Sourced from a Secret so the token is never + # a chart value or a rendered manifest literal. + - name: OTEL_EXPORTER_OTLP_HEADERS + valueFrom: + secretKeyRef: + name: {{ .name | quote }} + key: {{ .key | default "OTEL_EXPORTER_OTLP_HEADERS" | quote }} + {{- end }} + {{- end }} - name: OPENSHELL_TELEMETRY_ENABLED value: {{ .Values.server.telemetryEnabled | quote }} {{- if .Values.server.providerTokenGrants.spiffe.enabled }} diff --git a/deploy/helm/openshell/values.yaml b/deploy/helm/openshell/values.yaml index 8a193b71af..829926892c 100644 --- a/deploy/helm/openshell/values.yaml +++ b/deploy/helm/openshell/values.yaml @@ -270,6 +270,19 @@ server: endpoint: "" # -- Gateway OpenTelemetry service name. Empty uses openshell-gateway. serviceName: "" + # Authentication for a hosted OTLP collector. + # + # The gateway authenticates through the standard OpenTelemetry header + # variables -- there is no `headers` field in the gateway TOML -- so this + # has to reach the process as an environment variable. Reference a Secret + # holding the full header string, for example + # `authorization=Bearer `, rather than putting a token in values. + headersSecret: + # -- Name of an existing Secret holding the OTLP header string. Empty + # disables the env var entirely. + name: "" + # -- Key within that Secret. Defaults to OTEL_EXPORTER_OTLP_HEADERS. + key: "" # -- Also export gateway and sandbox logs (including OCSF events) as OTLP # log records to the same endpoint. Drops are reported downstream as # telemetry_gap records.