Self-hosted n8n 2.32.5 on GCP Cloud Run, multi-tenant. Exporting traces to Datadog. Setting headers via env var loaded from Secret Manager:
N8N_OTEL_EXPORTER_OTLP_HEADERS=dd-api-key=<key>,dd-otlp-source=serverless,compute_stats=true
Settings > OpenTelemetry correctly greys out the field (envManagedFields works).
But the value itself is returned in full plain text to every user who have access to settings, thus we expose secret data.
Is there any way to hide that data somehow?
I already created a feature request to hide whole OTEL page, but without any response OpenTelemetry visible UI
Hi @rgrzesk
To securely solve this in a multi-tenant Cloud Run environment without waiting for an upstream UI patch, you should decouple the secret from n8n by using an OpenTelemetry (OTel) Collector Sidecar.
By running an OTel collector as a sidecar container in your Cloud Run service, n8n can send telemetry unauthenticated to localhost, and the sidecar will securely append your Datadog API key and forward it. This completely removes the secret from n8n’s environment variables.
Create a file named otel-collector-config.yaml. This configures the sidecar to receive unauthenticated traces from n8n and forward them to Datadog with the injected API key.
receivers:
otlp:
protocols:
http:
endpoint: "0.0.0.0:4318"
exporters:
otlphttp/datadog:
endpoint: "https://trace.agent.datadoghq.com" # Datadog OTLP ingest endpoint
headers:
"DD-API-KEY": "${env:DD_API_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp/datadog]
Update your Cloud Run service to include the otelcol-contrib image as a sidecar.
Provide the Datadog API key only to the sidecar container, not the n8n container.
# Example Cloud Run service YAML snippet
spec:
template:
spec:
containers:
# --- n8n Container ---
- image: docker.n8n.io/n8nio/n8n:2.32.5
name: n8n-main
ports:
- containerPort: 5678
env:
# Send traces to the local sidecar instead of Datadog directly
- name: N8N_OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://localhost:4318/v1/traces"
# Remove N8N_OTEL_EXPORTER_OTLP_HEADERS completely from this container
# --- OTel Collector Sidecar ---
- image: otel/opentelemetry-collector-contrib:latest
name: otel-collector
args:
- "--config=/etc/otelcol-contrib/otel-collector-config.yaml"
env:
# Load the Datadog API key into the sidecar from Secret Manager
- name: DD_API_KEY
valueFrom:
secretKeyRef:
name: your-datadog-secret
key: latest
volumeMounts:
- name: otel-config-vol
mountPath: /etc/otelcol-contrib/
(Note: You will need to mount the otel-collector-config.yaml into the sidecar, typically via a GCP Secret or ConfigMap equivalent in Cloud Run).
Hi @rgrzesk
The UI is not the only surface. GET /api/v1/settings/otel returns exporterHeaders with its effective env value to any caller holding the otel:manage scope, so hiding the OpenTelemetry page on its own would not close this.
Pin the endpoint declaratively too, not just the headers:
N8N_OTEL_EXPORTER_OTLP_ENDPOINT=https://trace.agent.datadoghq.com
POST /settings/otel/test-trace overrides env-managed fields with their effective values before it sends, so as long as the endpoint stays UI-editable an admin can aim a test trace at a collector they control and have your dd-api-key delivered to it.
Send this to security@n8n.io rather than the feature request board, a secret readable by a lower-trust role is triaged as a vulnerability and not as a UI request.