Add system-tests for API Security Testing - Headers collection RFC#6915
Merged
christophe-papazian merged 6 commits intoMay 15, 2026
Merged
Conversation
Verify that tracers tag x-datadog-endpoint-scan and x-datadog-security-test on service entry spans as http.request.headers.<name> unconditionally, and do not propagate them to downstream services. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
|
Merged
2 tasks
🎉 All green!❄️ No new flaky tests detected 🔗 Commit SHA: 8c8d327 | Docs | Datadog PR Page | Give us feedback! |
Mark Test_SecurityTestingHeaders as irrelevant in cpp_nginx, envoy and haproxy manifests. These proxy manifests don't have a tests/appsec/ catch-all (unlike cpp_httpd and cpp_kong), so the test class was being collected on cpp_nginx. The RFC targets tracer libraries, not proxies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
cbeauchesne
approved these changes
May 15, 2026
claponcet
approved these changes
May 15, 2026
gh-worker-dd-mergequeue-cf854d Bot
pushed a commit
to DataDog/dd-trace-py
that referenced
this pull request
May 15, 2026
#18049) APPSEC-62412 ## Summary Tags two new Datadog markers — `x-datadog-endpoint-scan` and `x-datadog-security-test` — on every span that goes through `set_http_meta`, as `http.request.headers.<name>`. Collection is unconditional: it happens regardless of `DD_TRACE_HEADER_TAGS` or AppSec being enabled. Scope intentionally matches the existing user-agent/referrer extraction. These let the API endpoint reducer distinguish Datadog scan/test traffic from real user traffic and keep it out of the API inventory. The dd-style tag name (`http.request.headers.<name>`) is what dd-trace-py emits; the OTel-style variant (`http.request.header.<name>`) is handled by the reducer, not by tracers. RFC: [Security Testing: Trace Attribution for Inventory Enrichment and Pollution Prevention](https://docs.google.com/document/d/1uR4QQvU8pItEV2zFqr3-L6jO2jxzmvLrFTX_yyvqIOA) ## Test plan - [x] Unit tests in `tests/tracer/test_trace_utils.py::TestHeaders` (5 new): unconditional collection, absent, case-sensitive lookup, empty-value, non-propagation via `HTTPPropagator.inject` - [x] System tests: DataDog/system-tests#6915 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: christophe.papazian <christophe.papazian@datadoghq.com>
Member
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef71ab9685
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
e-n-0
approved these changes
May 15, 2026
Member
e-n-0
left a comment
There was a problem hiding this comment.
LGTM, but please look at the Codex comment!
…pi-security-testing-headers-collection
The previous `or {}` defensive guard converted a null request_headers
(serialized by some weblogs on inner-request errors) into an empty
header set, which trivially passes the absence assertions. Assert the
inner /make_distant_call status_code is 200 and request_headers is
non-null before checking the security testing headers are absent.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 15, 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.
APPSEC-63235
Summary
System-tests for the API Security Testing — Headers collection RFC. Tracers must tag the
x-datadog-endpoint-scanandx-datadog-security-testrequest headers on service entry spans ashttp.request.headers.<name>unconditionally (regardless ofDD_TRACE_HEADER_TAGSor AppSec being enabled), and must not propagate them to downstream services.Reference tracer implementation (Python): DataDog/dd-trace-py#18049.
Tests added
tests/appsec/api_security_testing/test_headers_collection.py::Test_SecurityTestingHeaders, three test methods:test_collected_when_present— both headers tagged on the entry span.test_absent_when_not_in_request— no tags set when the headers are not in the request.test_not_propagated_downstream—/make_distant_callis used to assert the headers do not appear in the outbound request (inspects therequest_headersreturned in the JSON response).Every test starts with a positive-collection check on the request under test, so the class fails entirely when a tracer has not implemented the RFC (no absence/non-propagation test silently passing).
Scenarios
The class is stacked on three scenarios to cover the unconditional contract on three orthogonal axes:
@scenarios.default— AppSec on.@scenarios.everything_disabled— AppSec off.@scenarios.library_conf_custom_header_tags— AppSec on,DD_TRACE_HEADER_TAGSset to unrelated headers.Other changes
@features.api_security_testing_headers_collectiondecorator (feature-parity id556, ownerasm).missing_featuremanifest entries added forjava,python,nodejs,php,golang,ruby,dotnet,rust.cpp.ymlis intentionally skipped (only parametric tests run there per its own header comment); proxy/lambda/otel manifests are not in scope (the test runs only in the three scenarios above).