Skip to content

jwt_authn: set sampled=nullopt on JWKS fetch span to honor parent sampling decision#45452

Open
zheng460 wants to merge 2 commits into
envoyproxy:mainfrom
zheng460:jira/szheng/envoy-44431
Open

jwt_authn: set sampled=nullopt on JWKS fetch span to honor parent sampling decision#45452
zheng460 wants to merge 2 commits into
envoyproxy:mainfrom
zheng460:jira/szheng/envoy-44431

Conversation

@zheng460

@zheng460 zheng460 commented Jun 5, 2026

Copy link
Copy Markdown

Commit Message:
jwt_authn: set sampled=nullopt on JWKS fetch span to honor parent sampling decision

The JWKS fetcher built AsyncClient::RequestOptions without setting the sampled
flag, so the "JWT Remote PubKey Fetch" span was always sampled regardless of the
parent span's sampling decision (RequestOptions::sampled_ defaults to true).
Set sampled to absl::nullopt so the fetch span inherits the parent's decision.

Fixes #44431

Additional Description:
The same fix was previously applied to ext_authz spans in #19343 and to lua
httpCall spans in #33200. This applies the equivalent fix to the JWKS fetcher's
async HTTP client.

Generative AI disclosure: this change was prepared with the assistance of
generative AI (Claude). The author understands the code being submitted.

Risk Level: Low

Testing: Added a unit test case in TestSpanPassedDown asserting the JWKS fetch
span leaves the sampling decision unset (RequestOptions::sampled_ is
absl::nullopt); the assertion fails without this change (the field defaults to
true) and passes with it. Also built Envoy and ran it against a Datadog Agent
ingestion rule, confirming the "JWT Remote PubKey Fetch" span now honors the
parent span's sampling decision instead of always being sampled. ingestion_reason
is set to rule correctly instead of manual.

Example span (Some information is hidden for security reasons. I can add more details if needed):

{
  "trace": {
    "span": {
      "11426711619662375027": {
        "ingestion_reason": "rule",
        "metrics": {
          "_sampling_priority_v1": 2
        }
      },
      "4609224114461176922": {
        "resource": "JWT Remote PubKey Fetch"
      }
    }
  }
}

Docs Changes: N/A

Release Notes: N/A

Platform Specific Features: N/A

…pling decision

The JWKS fetcher built AsyncClient::RequestOptions without setting the
sampled flag, so the "JWT Remote PubKey Fetch" span was always sampled
regardless of the parent span's sampling decision. Set sampled to
absl::nullopt so the fetch span inherits the parent's decision.

Fixes envoyproxy#44431

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Shirong Zheng <szheng@indeed.com>
@zheng460 zheng460 had a problem deploying to external-contributors June 5, 2026 01:06 — with GitHub Actions Error
@repokitteh-read-only

Copy link
Copy Markdown

Hi @zheng460, welcome and thank you for your contribution.

We will try to review your Pull Request as quickly as possible.

In the meantime, please take a look at the contribution guidelines if you have not done so already.

🐱

Caused by: #45452 was opened by zheng460.

see: more, trace.

Assert that RequestOptions::sampled_ is left unset (absl::nullopt) in
TestSpanPassedDown, guarding the JWKS fetch span against regressing back
to always-sampled behavior.

Fixes envoyproxy#44431

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Shirong Zheng <szheng@indeed.com>
@zheng460 zheng460 temporarily deployed to external-contributors June 5, 2026 01:38 — with GitHub Actions Inactive
@KBaichoo

Copy link
Copy Markdown
Contributor

PTAL @TAOXUY

@botengyao

Copy link
Copy Markdown
Member

/retest

@botengyao botengyao left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the fix, lgtm module a test.

/wait

@@ -64,6 +64,9 @@ class JwksFetcherImpl : public JwksFetcher,
.setTimeout(std::chrono::milliseconds(
DurationUtil::durationToMilliseconds(remote_jwks_.http_uri().timeout())))
.setParentSpan(parent_span)
// Leave sampled unset so the JWKS fetch span honors the parent span's
// sampling decision instead of always being sampled.
.setSampled(absl::nullopt)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add a test for the Inheritance?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated TestSpanPassedDown now asserts the fetcher leaves the sampling decision unset:

EXPECT_FALSE(options.sampled_.has_value());

That assertion is the full extent of what's testable at this layer: the fetcher's only role in inheritance is to pass sampled_ = absl::nullopt to the async client — it never spawns a span or sets sampling itself, and the async client is mocked in this test. The actual "unset ⇒ parent's decision is honored" semantics are owned and already covered one layer down by AsyncClientImplTracingTest.BasicNamedChildSpanKeepParentSampling (asserts the async client doesn't override the child span's sampling when sampled_ is empty), and the tracer-level propagation by ZipkinTracerTest.SpanSampledPropagatedToChild. Happy to add an OTel equivalent of that propagation test if useful, since OTel didn't have one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JWKS fetcher overrides trace sampling decisions

5 participants