fix(agent): stop light-action 401s for unconfigured proxy datasources - #474
Merged
Conversation
The agent only registered a datasource's actions (handler + light-action
allowlist entry) when its URL was set at startup. But the backend dispatches
these actions from per-account integration config, independent of the agent's
env — so any datasource the backend selects but the chart doesn't wire is
rejected with `auth: action "..." not in light-action allowlist` (401).
This surfaced as ~all light-action failures being jaeger_query_traces /
jaeger_query_services: the chart wires no jaeger URL, yet accounts configured
for traces=jaeger-via-agent still dispatch those actions.
Fix the whole class, not just jaeger:
- registerProxy() now always adds a read-only proxy datasource's action names
to the allowlist (sourced from the package's own Handlers() map, so no
drift). URL set -> real handler; URL unset -> a stub returning a clear
"<datasource> not configured" error instead of an auth rejection. Applied to
jaeger, chronosphere, pinot, signoz, elasticsearch, gcp, http-proxy. Mirrors
the existing query_data / api_traces_enricher_v2 unconditional-register
precedent. Prometheus/Loki are left as-is (wired by default + auto-discovered).
- config: JAEGER_URL falls back to JAEGER_QUERY_URL, aligning handler
registration with the var the telemetry heartbeat already reports.
- chart: first-class values for the optional trace datasources
(runner.jaeger.queryUrl, runner.chronosphere.{url,apiKey},
runner.pinot.{url,authToken,username,password}), surfaced as env in the
runner ConfigMap. This is what makes jaeger actually return traces; the stub
only stops the auth failure.
Contributor
|
📦 Image Tags Updated |
There was a problem hiding this comment.
Code Review
This pull request introduces a registerProxy helper function in the agent to register read-only proxy datasources unconditionally, returning a clear 'not configured' error when disabled instead of failing authorization. It also updates the Helm chart and agent configuration to support Jaeger, Chronosphere, and Pinot. The feedback suggests using the | quote filter for the newly added environment variables in the Helm template to prevent potential YAML parsing errors or unexpected type coercion.
blue4209211
previously approved these changes
Jun 11, 2026
Tokens/passwords/URLs with special chars (#, leading symbols, bool/number- looking values) can break YAML parsing or get type-coerced when unquoted. Apply | quote to the jaeger/chronosphere/pinot env, matching GRAFANA_URL.
Contributor
|
📦 Image Tags Updated |
RamanKharchee
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Loki showed ~all light-action failures over the last 3 days were jaeger:
jaeger_query_traces(368) andjaeger_query_services(190), rejected with:Root cause is a class of bug, not just jaeger. The agent only registers a
datasource's actions — both the handler and the light-action allowlist
entry — when that datasource's URL is set at startup (
main.go). But thebackend decides what to dispatch from each account's integration config
(e.g.
traces=jaeger-via-agent), independent of the agent's env. So anydatasource the backend can select but the chart doesn't wire gets a 401.
The
nudgebee-agentchart wires no jaeger URL at all, yet accounts configuredfor jaeger-via-agent still dispatch
jaeger_query_*→ every one rejected.Same latent risk for chronosphere, pinot, gke — they just aren't in use yet.
Fix (whole class, not just jaeger)
registerProxy()always adds a read-only proxy datasource's action namesto the allowlist (sourced from the package's own
Handlers()map, so namescan't drift). URL set → real handler; URL unset → a stub returning a clear
"<datasource> not configured"error instead of an auth rejection. Applied tojaeger, chronosphere, pinot, signoz, elasticsearch, gcp, http-proxy. Mirrors
the existing
query_data/api_traces_enricher_v2unconditional-registerprecedent. Prometheus/Loki left as-is (wired by default + auto-discovered).
JAEGER_URLfalls back toJAEGER_QUERY_URL, aligning handlerregistration with the var the telemetry heartbeat already reports.
(
runner.jaeger.queryUrl,runner.chronosphere.{url,apiKey},runner.pinot.{url,authToken,username,password}), surfaced as env in therunner ConfigMap. This is what makes jaeger actually return traces — the
stub only stops the auth failure.
Behavior change
Dispatcher path for a dispatched-but-unconfigured datasource action goes from
401 "not in light-action allowlist" (auth reject) to 200 when
configured, or 500 with an actionable "not configured" message when not.
To resolve the affected tenant
Set
runner.jaeger.queryUrlto the in-cluster jaeger-query endpoint andrestart the pod. Without it, jaeger goes 401 → "not configured" 500 — better,
but no traces until the URL is provided.
Validation
gofmt/go vetclean,go build ./...OK, agent test suites pass.helm lintpasses;helm templaterenders the new env when set and omits it by default.