From 7665635114079cec1f8ed4d2daee8fc306ee4f9c Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Tue, 8 Sep 2026 08:33:54 -0400 Subject: [PATCH 1/4] fix(feature-flags): constrain direct EVP intake origin (#12299) Add proxy-aware feature flag intake authentication Route direct feature flag intake through standard HTTPS proxy settings and attach the canonical fixed-width API key fingerprint. Environment: Datadog workspace Separate direct intake proxying from API key fingerprinting Keep this PR focused on proxy-aware direct Event Platform intake and leave fingerprinting to an independent change. Environment: Datadog workspace Merge live Java master after EVP split Restore Java formatting after the fingerprint split Keep the direct-intake diff free of fingerprint-only formatting artifacts. Environment: Datadog workspace Update direct-intake tests after fingerprint removal Use the original two-argument direct intake factory now that the unrelated fingerprint header plumbing has moved out of this PR. Environment: Datadog workspace Remove unnecessary Groovy imports fix(feature-flags): handle ambiguous EVP failures safely fix(feature-flags): validate direct EVP intake site Reject URL authority confusion before adding DD-API-KEY. Environment: Datadog workspace fix(config): align proxy configuration validation Read standard proxy environment variables without registering them as Datadog configuration aliases, and use the existing non-regex parser for no-proxy hosts. Environment: Datadog workspace fix(feature-flags): reject direct intake redirects Disable HTTP and HTTPS redirects for Feature Flags direct EVP intake so DD-API-KEY remains bound to the configured origin. Environment: Datadog workspace fix(feature-flags): harden proxy configuration Preserve one-character NO_PROXY entries and prevent HTTPS proxy URLs from exposing credentials through configuration telemetry. Environment: Datadog workspace Merge remote-tracking branch 'origin/master' into leo.romanovsky/ffe-agentless-evp-java-hardening # Conflicts: # utils/config-utils/src/main/java/datadog/trace/api/ConfigSetting.java # utils/config-utils/src/test/java/datadog/trace/api/ConfigSettingTest.java refactor(feature-flags): narrow direct intake hardening Keep direct intake origin and redirect protections while removing proxy and runtime failover changes. Environment: Datadog workspace Merge branch 'master' into leo.romanovsky/ffe-agentless-evp-java-hardening\n\nEnvironment: Datadog workspace Co-authored-by: devflow.devflow-routing-intake From 874d5bc6dfcbc9dae57929c8413c19856700c1b7 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 26 Aug 2026 15:50:22 -0400 Subject: [PATCH 2/4] Enable Pekko HTTP forked tests --- .../pekko/pekko-http-1.0/build.gradle | 4 ++++ .../PekkoHttpClientInstrumentationTest.groovy | 13 +++++++++++-- .../PekkoHttpSingleRequestInstrumentation.java | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle index d1e796ba315..b28db74e6a3 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle @@ -45,6 +45,10 @@ sourceSets { latestPekko10Test.scala.srcDir sourceSets.baseTest.scala } +['baseTest', 'latestPekko10Test', 'latestDepTest'].each { + addForkedTestTask(it) +} + dependencies { compileOnly libs.scala212 compileOnly group: 'org.apache.pekko', name: 'pekko-http-core_2.12', version: '1.0.0' diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy index 628ccbd366b..98ed9cfe388 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy @@ -10,6 +10,7 @@ import datadog.trace.agent.test.naming.TestingGenericHttpNamingConventions import datadog.trace.api.DDSpanTypes import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.instrumentation.pekkohttp.PekkoHttpClientDecorator +import datadog.trace.instrumentation.pekkohttp.PekkoHttpSingleRequestInstrumentation.SingleRequestContextPropagationAdvice import scala.compat.java8.FutureConverters import scala.concurrent.Future import spock.lang.Shared @@ -61,6 +62,14 @@ abstract class PekkoHttpClientInstrumentationTest extends HttpClientTest { return false } + def "does not inject context into a null request"() { + when: + SingleRequestContextPropagationAdvice.methodEnter(null) + + then: + noExceptionThrown() + } + def "singleRequest exception trace"() { when: // Passing null causes NPE in singleRequest @@ -73,14 +82,14 @@ abstract class PekkoHttpClientInstrumentationTest extends HttpClientTest { span { parent() operationName operation() - resourceName "pekko-http.client.request" + resourceName operation() // resource name is not set so defaults to operationName spanType DDSpanTypes.HTTP_CLIENT errored true tags { "$Tags.COMPONENT" "pekko-http-client" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT errorTags(exception) - defaultTags() + defaultTags(false, false) } } } diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java index 4625cdfe955..1c85e382736 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/main/java/datadog/trace/instrumentation/pekkohttp/PekkoHttpSingleRequestInstrumentation.java @@ -115,6 +115,9 @@ public static class SingleRequestContextPropagationAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter( @Advice.Argument(value = 0, readOnly = false) HttpRequest request) { + if (request == null) { + return; + } final PekkoHttpHeaders headers = new PekkoHttpHeaders(request); DECORATE.injectContext(currentContext(), request, headers); request = headers.getRequest(); From 8adad42b4068f17ebde62b54f4b571a5562f8a39 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 8 Sep 2026 09:50:54 -0400 Subject: [PATCH 3/4] Minor reshuffle. --- .../pekko/pekko-http-1.0/build.gradle | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle index b28db74e6a3..a68a645badb 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/build.gradle @@ -8,10 +8,16 @@ plugins { // we put the test classes in the baseTest test set so that the scala // version is not inherited addTestSuite('baseTest') +addForkedTestTask('baseTest') + addTestSuite('latestDepTest') +addForkedTestTask('latestDepTest') + addTestSuiteForDir('latestPekko10Test', 'latestDepTest') +addForkedTestTask('latestPekko10Test') + addTestSuite('iastTest') -addTestSuiteForDir 'latestDepIastTest', 'iastTest' +addTestSuiteForDir('latestDepIastTest', 'iastTest') muzzle { pass { @@ -45,10 +51,6 @@ sourceSets { latestPekko10Test.scala.srcDir sourceSets.baseTest.scala } -['baseTest', 'latestPekko10Test', 'latestDepTest'].each { - addForkedTestTask(it) -} - dependencies { compileOnly libs.scala212 compileOnly group: 'org.apache.pekko', name: 'pekko-http-core_2.12', version: '1.0.0' From 9f6fb65b2ed8564b05d57d4d332df70429ba6d0b Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Tue, 8 Sep 2026 14:15:40 -0400 Subject: [PATCH 4/4] Remove direct Pekko advice test --- .../groovy/PekkoHttpClientInstrumentationTest.groovy | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy index 98ed9cfe388..6d661d7e682 100644 --- a/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/pekko/pekko-http-1.0/src/baseTest/groovy/PekkoHttpClientInstrumentationTest.groovy @@ -10,7 +10,6 @@ import datadog.trace.agent.test.naming.TestingGenericHttpNamingConventions import datadog.trace.api.DDSpanTypes import datadog.trace.bootstrap.instrumentation.api.Tags import datadog.trace.instrumentation.pekkohttp.PekkoHttpClientDecorator -import datadog.trace.instrumentation.pekkohttp.PekkoHttpSingleRequestInstrumentation.SingleRequestContextPropagationAdvice import scala.compat.java8.FutureConverters import scala.concurrent.Future import spock.lang.Shared @@ -62,14 +61,6 @@ abstract class PekkoHttpClientInstrumentationTest extends HttpClientTest { return false } - def "does not inject context into a null request"() { - when: - SingleRequestContextPropagationAdvice.methodEnter(null) - - then: - noExceptionThrown() - } - def "singleRequest exception trace"() { when: // Passing null causes NPE in singleRequest