Skip to content

Prepare the mocked backend to receive agentless FFE traffic - #8186

Open
cbeauchesne wants to merge 15 commits into
mainfrom
cbeauchesne/backend-v2-with-api-key
Open

cbeauchesne wants to merge 15 commits into
mainfrom
cbeauchesne/backend-v2-with-api-key

Conversation

@cbeauchesne

@cbeauchesne cbeauchesne commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

First step to remove the datadog_sidecar and datadog_direct interfaces: FFE agentless traffic will go to the mocked backend, and the sender will be identified by its API key.

Changes

  • interfaces.backend_v2 methods accept with_api_key, to only get requests sent with this key
  • serverless-init uses its own fake API key
  • the mocked backend serves either HTTP (default) or HTTPS: MockedBackendContainer(tls=True) serves the mock intake hostnames (*.mock-intake.invalid) on 443, with a committed certificate signed by the mitmproxy CA

No behavior change yet: no scenario uses tls=True.

🤖 Generated with Claude Code

cbeauchesne and others added 2 commits October 26, 2026 18:48
…erverless-init

Each sender uses its own API key, so with_api_key tells where a request comes from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ainer

Agentless senders only speak HTTPS to the hostnames derived from DD_SITE. The mocked backend
container gets network aliases for them, and serves them over TLS with a certificate signed by
the mitmproxy CA, sharing its routes and records with the HTTP port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

CODEOWNERS have been resolved as:

utils/mocked_backend/tls/README.md                                      @DataDog/system-tests-core
utils/mocked_backend/tls/mocked-backend.pem                             @DataDog/system-tests-core
tests/test_the_test/test_mock_backend_v2.py                             @DataDog/system-tests-reviewers
utils/_context/containers.py                                            @DataDog/system-tests-core
utils/interfaces/_backend_v2.py                                         @DataDog/system-tests-core
utils/mocked_backend/__main__.py                                        @DataDog/system-tests-core
utils/mocked_backend/_backend.py                                        @DataDog/system-tests-core
utils/mocked_backend/_backend_ffe.py                                    @DataDog/feature-flagging-and-experimentation-sdk @DataDog/system-tests-core
utils/mocked_backend/_client.py                                         @DataDog/system-tests-core
utils/mocked_backend/_request_handler.py                                @DataDog/system-tests-core

@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Pipelines  Tests

✨ Unblock PR with BitsAI

❌ Errors

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 22 Pipeline jobs failed

Testing the test | System Tests (php, dev) / End-to-end #1 / apache-mod-7.1-zts 1 — ❌ 2 tests failed · 🔧 Needs a code fix, caused by this PR

View more details · View in GitHub Actions

❌ tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language.test_expression_language_access_variables[apache-mod-7.1-zts] from system_tests_suite
AssertionError: assert &#39;Probes did not reach INSTALLED status&#39; is None
 &#43;  where &#39;Probes did not reach INSTALLED status&#39; = &lt;built-in method join of str object at 0x7f60fa62b720&gt;([&#39;Probes did not reach INSTALLED status&#39;])
 &#43;    where &lt;built-in method join of str object at 0x7f60fa62b720&gt; = &#39;\n&#39;.join
 &#43;    and   [&#39;Probes did not reach INSTALLED status&#39;] = &lt;tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language object at 0x7f60f073c650&gt;.setup_failures

self = &lt;tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language object at 0x7f60f073c650&gt;

    def test_expression_language_access_variables(self):
&gt;       self._assert(expected_response=200)

...
❌ tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM.test_log_method_snapshot[apache-mod-7.1-zts] from system_tests_suite
AssertionError: assert &#39;Probes did not reach INSTALLED status&#39; is None
 &#43;  where &#39;Probes did not reach INSTALLED status&#39; = &lt;built-in method join of str object at 0x7ff24ce2b720&gt;([&#39;Probes did not reach INSTALLED status&#39;])
 &#43;    where &lt;built-in method join of str object at 0x7ff24ce2b720&gt; = &#39;\n&#39;.join
 &#43;    and   [&#39;Probes did not reach INSTALLED status&#39;] = &lt;tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM object at 0x7ff2440bd400&gt;.setup_failures

self = &lt;tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM object at 0x7ff2440bd400&gt;

    def test_log_method_snapshot(self):
&gt;       self._assert()

...
Testing the test | System Tests (php, dev) / End-to-end #1 / apache-mod-7.2-zts 1 — ❌ 1 test failed · 🔧 Needs a code fix, caused by this PR

View more details · View in GitHub Actions

❌ tests.debugger.test_debugger_capture_expressions.Test_Debugger_Method_Capture_Expressions.test_method_parameter_capture_expressions[apache-mod-7.2-zts] from system_tests_suite
AssertionError: assert &#39;Probes did not reach INSTALLED status&#39; is None
 &#43;  where &#39;Probes did not reach INSTALLED status&#39; = &lt;built-in method join of str object at 0x7fcc6882b720&gt;([&#39;Probes did not reach INSTALLED status&#39;])
 &#43;    where &lt;built-in method join of str object at 0x7fcc6882b720&gt; = &#39;\n&#39;.join
 &#43;    and   [&#39;Probes did not reach INSTALLED status&#39;] = &lt;tests.debugger.test_debugger_capture_expressions.Test_Debugger_Method_Capture_Expressions object at 0x7fcc59f75670&gt;.setup_failures

self = &lt;tests.debugger.test_debugger_capture_expressions.Test_Debugger_Method_Capture_Expressions object at 0x7fcc59f75670&gt;

    def test_method_parameter_capture_expressions(self):
&gt;       self._assert()

...
Testing the test | System Tests (php, dev) / End-to-end #1 / apache-mod-7.3-zts 1 — ❌ 2 tests failed · 🔧 Needs a code fix, caused by this PR

View more details · View in GitHub Actions

❌ tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language.test_expression_language_access_variables[apache-mod-7.3-zts] from system_tests_suite
AssertionError: assert &#39;Probes did not reach INSTALLED status&#39; is None
 &#43;  where &#39;Probes did not reach INSTALLED status&#39; = &lt;built-in method join of str object at 0x7fb45482b720&gt;([&#39;Probes did not reach INSTALLED status&#39;])
 &#43;    where &lt;built-in method join of str object at 0x7fb45482b720&gt; = &#39;\n&#39;.join
 &#43;    and   [&#39;Probes did not reach INSTALLED status&#39;] = &lt;tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language object at 0x7fb445eba5d0&gt;.setup_failures

self = &lt;tests.debugger.test_debugger_expression_language.Test_Debugger_Expression_Language object at 0x7fb445eba5d0&gt;

    def test_expression_language_access_variables(self):
&gt;       self._assert(expected_response=200)

...
❌ tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM.test_log_method_snapshot[apache-mod-7.3-zts] from system_tests_suite
AssertionError: assert &#39;Probes did not reach INSTALLED status&#39; is None
 &#43;  where &#39;Probes did not reach INSTALLED status&#39; = &lt;built-in method join of str object at 0x7fdb4f42b720&gt;([&#39;Probes did not reach INSTALLED status&#39;])
 &#43;    where &lt;built-in method join of str object at 0x7fdb4f42b720&gt; = &#39;\n&#39;.join
 &#43;    and   [&#39;Probes did not reach INSTALLED status&#39;] = &lt;tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM object at 0x7fdb449cca40&gt;.setup_failures

self = &lt;tests.debugger.test_debugger_probe_snapshot.Test_Debugger_Method_Probe_Snaphots_With_SCM object at 0x7fdb449cca40&gt;

    def test_log_method_snapshot(self):
&gt;       self._assert()

...

View all 22 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 0a12ffb | Docs | View more details | Give us feedback!

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Failed TLS initialization leaves the HTTP listener and background thread running, potentially blocking subsequent startup attempts.

1 open issue
What changed in this PR

Prepares the mocked backend to receive agentless feature-flag evaluation traffic and identify senders by API key, without redirecting traffic yet.

Changes:

  • Adds optional API-key filtering to backend interface methods.
  • Adds HTTPS support for mock intake hostnames using the mitmproxy CA.
  • Gives serverless-init a distinct fake API key and adds filtering and TLS tests.
File Description
utils/​mocked_backend/​_tls.py Adds certificate generation and a shared-backend HTTPS listener.
utils/​mocked_backend/​_backend.py Integrates optional TLS startup and shutdown.
utils/​mocked_backend/​__main__.py Exposes TLS configuration through CLI options.
utils/​interfaces/​_backend_v2.py Adds API-key filtering to retrieval methods.
utils/​_context/​containers.py Configures intake aliases, HTTPS, and a distinct serverless-init key.
tests/​test_the_test/​test_mock_backend_v2.py Tests API-key filtering, HTTPS recording, and hostname validation.

Review effort: Balanced

Comment thread utils/mocked_backend/_backend.py Outdated
cbeauchesne and others added 4 commits October 26, 2026 19:13
Instead of generating one at startup. A test checks it covers the container hostnames, and is
not about to expire.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No scenario needs both: the container gets a tls option (off by default), and scenarios will
turn it on when they move their HTTPS senders to the mocked backend. The TLS listener is gone;
the certificate also covers the container name and localhost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cbeauchesne
cbeauchesne requested a balanced review from Copilot October 27, 2026 00:28
@cbeauchesne

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T14:02:32.774787Z d312c79 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved TLS handshake blocking, bridge-network alias incompatibility, and HTTP-only URL helpers prevent reliable use of the new HTTPS mode.

3 open issues
1 resolved since last review

Review effort: Balanced

Comment thread utils/_context/containers.py
Comment thread utils/mocked_backend/_backend.py Outdated
Comment thread utils/mocked_backend/_backend.py
cbeauchesne and others added 4 commits October 27, 2026 10:32
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An idle connection no longer blocks the other requests, nor close().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cbeauchesne

Copy link
Copy Markdown
Collaborator Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The committed certificate does not cover host.docker.internal, so verified HTTPS connections to the server’s advertised host-based URLs fail.

1 open issue
3 resolved since last review

Review effort: Balanced

Comment thread utils/mocked_backend/tls/mocked-backend.pem
@cbeauchesne
cbeauchesne marked this pull request as ready for review October 27, 2026 13:56
@cbeauchesne
cbeauchesne requested review from a team as code owners October 27, 2026 13:56
@cbeauchesne
cbeauchesne requested a review from a team as a code owner October 27, 2026 13:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d312c796bb

ℹ️ 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".

Comment thread utils/_context/containers.py

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants