Skip to content

feat(sidecar): forward FFE exposures to EVP proxy#2026

Open
leoromanovsky wants to merge 13 commits into
mainfrom
leo.romanovsky/ffe-sidecar-exposures
Open

feat(sidecar): forward FFE exposures to EVP proxy#2026
leoromanovsky wants to merge 13 commits into
mainfrom
leo.romanovsky/ffe-sidecar-exposures

Conversation

@leoromanovsky
Copy link
Copy Markdown
Contributor

@leoromanovsky leoromanovsky commented May 22, 2026

Motivation

The PHP FFE / OpenFeature runtime needs to flush EVP exposures and OTLP evaluation metrics through the libdatadog sidecar. The tracer extension must not open its own HTTP sockets.

This PR adds the sidecar FFIs used by dd-trace-php#3910 and dd-trace-php#3911, and fixes dispatch so short-lived PHP processes do not drop FFE batches before application registration.

Reference planning doc: https://docs.google.com/document/d/1NvMfTpZWLBlFmEFNjdnlMyeVpy5l7KD8qujGFco6w2w/edit?tab=t.0

Where this fits

This PR is the libdatadog sidecar layer for the PHP FFE stack. PHP evaluates flags, decides whether to emit an exposure or metric, and encodes the payload. This PR accepts those already-built payloads over sidecar FFI and performs the outbound HTTP delivery from the sidecar.

flowchart TD
  subgraph PHP["dd-trace-php PRs"]
    App["PHP app<br/>OpenFeature or dd-trace FFE"] --> Eval["Evaluation hook"]

    Eval --> ExposureBatch["Exposure JSON batch<br/>PR 3910"]
    Eval --> MetricBatch["feature_flag.evaluations<br/>OTLP/protobuf bytes<br/>PR 3911"]
  end

  subgraph Sidecar["libdatadog PR 2026"]
    ExposureFFI["ddog_sidecar_send_ffe_exposures"] --> IPC["tarpc enqueue_actions"]
    MetricFFI["ddog_sidecar_send_ffe_metrics"] --> IPC

    IPC --> Dispatch["sidecar enqueue_actions<br/>dispatch FFE actions before<br/>application registration gate"]

    Dispatch --> ExposureFlusher["ffe_exposures_flusher"]
    Dispatch --> MetricFlusher["ffe_metrics_flusher"]
  end

  subgraph Delivery["Outbound delivery"]
    Agent["Datadog Agent EVP proxy<br/>/evp_proxy/v2/api/v2/exposures"] --> EventPlatform["Event Platform intake<br/>/api/v2/exposures"]
    Collector["OTLP collector<br/>/v1/metrics"]
  end

  ExposureBatch --> ExposureFFI
  MetricBatch --> MetricFFI
  ExposureFlusher --> Agent
  MetricFlusher --> Collector
Loading

Reviewer shortcut: the important sidecar contract is the middle of the diagram. FFE actions are session-scoped, so this PR dispatches them before the per-application telemetry attribution gate.

Decisions

  • FFE sidecar actions are session-scoped, not application-scoped. They dispatch from session state and must not wait for applications.entry(queue_id) to exist.
  • EVP exposures are Agent-only. The sidecar derives the Agent EVP proxy endpoint from the session trace endpoint and POSTs to /evp_proxy/v2/api/v2/exposures with the X-Datadog-EVP-Subdomain: event-platform-intake header.
  • OTLP metrics use a caller-supplied OTLP HTTP endpoint and application/x-protobuf payload bytes.
  • Delivery is fire-and-forget: enqueue success is not HTTP delivery success. Non-2xx responses and network errors are logged and dropped.
  • Delivery failures are not surfaced back to PHP after enqueue and are not counted in sidecar self-telemetry yet.
  • PHP encodes OTLP/protobuf; the sidecar metrics flusher only POSTs the bytes.

Changes

  • Adds SidecarAction::FfeExposures(payload) and ddog_sidecar_send_ffe_exposures for EVP exposure batches.
  • Adds SidecarAction::FfeMetrics { endpoint, payload } and ddog_sidecar_send_ffe_metrics for OTLP/protobuf metric batches.
  • Wires both action arms into enqueue_actions so tracers can publish either FFE payload type through the existing tarpc IPC channel.
  • Lifts FFE actions out of the application-registration gate that guards telemetry attribution. Without this, short-lived PHP processes can silently drop FFE batches that arrive before the first set_remote_config_data / set_request_config call registers the application.
  • Adds a sidecar regression test proving FfeExposures and FfeMetrics dispatch even when no application entry exists for the queue.
  • Renames ffe_flusher to ffe_exposures_flusher so the EVP module name parallels its OTLP-metrics sibling.
  • Adds CODEOWNERS coverage for both flusher files.

Validation

  • cargo test -p datadog-sidecar ffe_: 8/8 passed, including the new ffe_actions_dispatch_without_registered_application regression test.
  • cargo check -p datadog-sidecar-ffi
  • dd-trace-php parametric FFE system-tests integration branch (exposures plus metrics): 27/27 pass.
  • dd-trace-php full PARAMETRIC scenario on each branch: no FFE regressions; only pre-existing Test_Stable_Config_Default env failures consistent across branches.

Questions for reviewers

  • Does the new regression test capture the desired contract that FFE actions are session-scoped and must dispatch before application registration, or do you want the contract asserted at a different layer?

Adds SidecarAction::FfeExposures variant so the PHP tracer can hand a
batched exposure payload to the sidecar, and adds an ffe_flusher module
that POSTs the payload to the agent's EVP proxy at
/evp_proxy/v2/api/v2/exposures with X-Datadog-EVP-Subdomain:
event-platform-intake. Matches dd-trace-go / ruby / python / js /
dotnet wire protocol. Fire-and-forget; non-2xx is logged and dropped
(no agent_info gating, consistent with other tracers).

Also exposes ddog_sidecar_send_ffe_exposures FFI in datadog-sidecar-ffi
for the PHP extension to call from its RSHUTDOWN / MSHUTDOWN hooks.

Tests: 3 httpmock-backed cases cover POST method + path + subdomain
header + body, non-2xx drop, and endpoint-path override while
preserving authority / scheme / auth / timeout.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

📚 Documentation Check Results

⚠️ 5400 documentation warning(s) found

📦 datadog-sidecar-ffi - 2826 warning(s)

📦 datadog-sidecar - 2574 warning(s)


Updated: 2026-05-24 04:33:11 UTC | Commit: 26e220d | missing-docs job results

@github-actions
Copy link
Copy Markdown
Contributor

Clippy Allow Annotation Report

Comparing clippy allow annotations between branches:

  • Base Branch: origin/main
  • PR Branch: origin/leo.romanovsky/ffe-sidecar-exposures

Summary by Rule

Rule Base Branch PR Branch Change
expect_used 2 2 No change (0%)
unwrap_used 7 7 No change (0%)
Total 9 9 No change (0%)

Annotation Counts by File

File Base Branch PR Branch Change
datadog-sidecar/src/service/sidecar_server.rs 6 6 No change (0%)
datadog-sidecar/src/service/telemetry.rs 3 3 No change (0%)

Annotation Stats by Crate

Crate Base Branch PR Branch Change
clippy-annotation-reporter 5 5 No change (0%)
datadog-ffe-ffi 1 1 No change (0%)
datadog-ipc 21 21 No change (0%)
datadog-live-debugger 6 6 No change (0%)
datadog-live-debugger-ffi 10 10 No change (0%)
datadog-profiling-replayer 4 4 No change (0%)
datadog-remote-config 3 3 No change (0%)
datadog-sidecar 57 57 No change (0%)
libdd-common 13 13 No change (0%)
libdd-common-ffi 12 12 No change (0%)
libdd-data-pipeline 5 5 No change (0%)
libdd-ddsketch 2 2 No change (0%)
libdd-dogstatsd-client 1 1 No change (0%)
libdd-profiling 13 13 No change (0%)
libdd-telemetry 20 20 No change (0%)
libdd-tinybytes 4 4 No change (0%)
libdd-trace-normalization 2 2 No change (0%)
libdd-trace-obfuscation 3 3 No change (0%)
libdd-trace-stats 1 1 No change (0%)
libdd-trace-utils 15 15 No change (0%)
Total 198 198 No change (0%)

About This Report

This report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

🔒 Cargo Deny Results

⚠️ 13 issue(s) found, showing only errors (advisories, bans, sources)

📦 datadog-sidecar-ffi - 7 error(s)

Show output
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:37:1
   │
37 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     ├── datadog-ipc v0.1.0
     │   ├── datadog-sidecar v0.0.1
     │   │   └── datadog-sidecar-ffi v0.0.1
     │   └── datadog-sidecar-ffi v0.0.1 (*)
     └── datadog-sidecar v0.0.1 (*)

error[unmaintained]: paste - no longer maintained
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:262:1
    │
262 │ paste 1.0.15 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
    │
    ├ ID: RUSTSEC-2024-0436
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2024-0436
    ├ The creator of the crate `paste` has stated in the [`README.md`](https://github.com/dtolnay/paste/blob/master/README.md) 
      that this project is not longer maintained as well as archived the repository
      
      ## Possible Alternative(s)
      
      - [`pastey`]: a fork of paste and is aimed to be a drop-in replacement with additional features for paste crate
      - [`with_builtin_macros`]: crate providing a [superset of `paste`'s functionality including general `macro_rules!` eager expansions](https://docs.rs/with_builtin_macros/0.1.0/with_builtin_macros/macro.with_eager_expansions.html)  and `concat!`/`concat_idents!` macros
      
      [`pastey`]: https://crates.io/crates/pastey
      [`with_builtin_macros`]: https://crates.io/crates/with_builtin_macros
    ├ Announcement: https://github.com/dtolnay/paste
    ├ Solution: No safe upgrade is available!
    ├ paste v1.0.15
      ├── datadog-sidecar-ffi v0.0.1
      ├── libdd-libunwind-sys v1.0.2
      │   └── libdd-crashtracker v1.0.0
      │       ├── datadog-sidecar v0.0.1
      │       │   └── datadog-sidecar-ffi v0.0.1 (*)
      │       └── libdd-crashtracker-ffi v34.0.0
      │           ├── datadog-sidecar v0.0.1 (*)
      │           └── datadog-sidecar-ffi v0.0.1 (*)
      ├── libdd-telemetry-ffi v34.0.0
      │   └── datadog-sidecar-ffi v0.0.1 (*)
      └── rmp v0.8.14
          ├── libdd-trace-utils v4.0.0
          │   ├── (dev) datadog-sidecar v0.0.1 (*)
          │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │   ├── libdd-data-pipeline v4.0.0
          │   │   ├── datadog-live-debugger v0.0.1
          │   │   │   ├── datadog-remote-config v0.0.1
          │   │   │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │   │   │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
          │   │   │   │   └── datadog-sidecar-ffi v0.0.1 (*)
          │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │   │   │   └── datadog-sidecar-ffi v0.0.1 (*)
          │   │   └── datadog-sidecar v0.0.1 (*)
          │   ├── libdd-trace-obfuscation v3.0.0
          │   │   └── libdd-trace-stats v3.0.0
          │   │       ├── datadog-ipc v0.1.0
          │   │       │   ├── datadog-sidecar v0.0.1 (*)
          │   │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │   │       ├── datadog-sidecar v0.0.1 (*)
          │   │       └── libdd-data-pipeline v4.0.0 (*)
          │   ├── libdd-trace-stats v3.0.0 (*)
          │   └── (dev) libdd-trace-utils v4.0.0 (*)
          ├── rmp-serde v1.3.0
          │   ├── datadog-sidecar v0.0.1 (*)
          │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │   ├── libdd-data-pipeline v4.0.0 (*)
          │   ├── (dev) libdd-tinybytes v1.1.1
          │   │   ├── datadog-ipc v0.1.0 (*)
          │   │   ├── datadog-sidecar v0.0.1 (*)
          │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │   │   ├── (dev) libdd-tinybytes v1.1.1 (*)
          │   │   └── libdd-trace-utils v4.0.0 (*)
          │   ├── libdd-trace-stats v3.0.0 (*)
          │   └── libdd-trace-utils v4.0.0 (*)
          └── rmpv v1.3.0
              └── libdd-trace-utils v4.0.0 (*)

error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:292:1
    │
292 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── datadog-sidecar v0.0.1
      │   └── datadog-sidecar-ffi v0.0.1
      ├── libdd-common v4.1.0
      │   ├── datadog-ipc v0.1.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   └── datadog-sidecar-ffi v0.0.1 (*)
      │   ├── datadog-live-debugger v0.0.1
      │   │   ├── datadog-remote-config v0.0.1
      │   │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
      │   │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │   │   └── datadog-sidecar-ffi v0.0.1 (*)
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   └── datadog-sidecar-ffi v0.0.1 (*)
      │   ├── datadog-remote-config v0.0.1 (*)
      │   ├── datadog-sidecar v0.0.1 (*)
      │   ├── datadog-sidecar-ffi v0.0.1 (*)
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   ├── libdd-data-pipeline v4.0.0
      │   │   │   ├── datadog-live-debugger v0.0.1 (*)
      │   │   │   └── datadog-sidecar v0.0.1 (*)
      │   │   ├── libdd-shared-runtime v1.0.0
      │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
      │   │   │   ├── libdd-telemetry v5.0.0
      │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
      │   │   │   │   ├── libdd-crashtracker v1.0.0
      │   │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
      │   │   │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
      │   │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
      │   │   │   │   └── libdd-telemetry-ffi v34.0.0
      │   │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
      │   │   │   └── libdd-trace-stats v3.0.0
      │   │   │       ├── datadog-ipc v0.1.0 (*)
      │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │   │   │       └── libdd-data-pipeline v4.0.0 (*)
      │   │   ├── libdd-trace-stats v3.0.0 (*)
      │   │   └── libdd-trace-utils v4.0.0
      │   │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │       ├── datadog-sidecar-ffi v0.0.1 (*)
      │   │       ├── libdd-data-pipeline v4.0.0 (*)
      │   │       ├── libdd-trace-obfuscation v3.0.0
      │   │       │   └── libdd-trace-stats v3.0.0 (*)
      │   │       ├── libdd-trace-stats v3.0.0 (*)
      │   │       └── (dev) libdd-trace-utils v4.0.0 (*)
      │   ├── libdd-common-ffi v34.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
      │   │   ├── libdd-crashtracker-ffi v34.0.0 (*)
      │   │   └── libdd-telemetry-ffi v34.0.0 (*)
      │   ├── (build) libdd-crashtracker v1.0.0 (*)
      │   ├── libdd-crashtracker-ffi v34.0.0 (*)
      │   ├── libdd-data-pipeline v4.0.0 (*)
      │   ├── libdd-dogstatsd-client v3.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
      │   │   └── libdd-data-pipeline v4.0.0 (*)
      │   ├── libdd-shared-runtime v1.0.0 (*)
      │   ├── libdd-telemetry v5.0.0 (*)
      │   ├── libdd-telemetry-ffi v34.0.0 (*)
      │   ├── libdd-trace-obfuscation v3.0.0 (*)
      │   ├── libdd-trace-stats v3.0.0 (*)
      │   └── libdd-trace-utils v4.0.0 (*)
      ├── libdd-crashtracker v1.0.0 (*)
      ├── (dev) libdd-data-pipeline v4.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   └── libdd-trace-utils v4.0.0 (*)
      ├── (dev) libdd-trace-stats v3.0.0 (*)
      ├── libdd-trace-utils v4.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── datadog-ipc v0.1.0 (*)
              ├── datadog-sidecar v0.0.1 (*)
              ├── datadog-sidecar-ffi v0.0.1 (*)
              ├── libdd-data-pipeline v4.0.0 (*)
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v4.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:318:1
    │
318 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   ├── datadog-sidecar v0.0.1
          │       │   │   └── datadog-sidecar-ffi v0.0.1
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │   │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   │   └── libdd-telemetry-ffi v34.0.0
          │       │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       │   └── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:318:1
    │
318 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   ├── datadog-sidecar v0.0.1
          │       │   │   └── datadog-sidecar-ffi v0.0.1
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │   │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   │   └── libdd-telemetry-ffi v34.0.0
          │       │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       │   └── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:318:1
    │
318 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   ├── datadog-sidecar v0.0.1
          │       │   │   └── datadog-sidecar-ffi v0.0.1
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │   │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   │   └── libdd-telemetry-ffi v34.0.0
          │       │   │   │       └── datadog-sidecar-ffi v0.0.1 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       │   └── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── datadog-sidecar-ffi v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-telemetry-ffi v34.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Denial of Service via Stack Exhaustion
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:373:1
    │
373 │ time 0.3.41 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0009
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0009
    ├ ## Impact
      
      When user-provided input is provided to any type that parses with the RFC 2822 format, a denial of
      service attack via stack exhaustion is possible. The attack relies on formally deprecated and
      rarely-used features that are part of the RFC 2822 format used in a malicious manner. Ordinary,
      non-malicious input will never encounter this scenario.
      
      ## Patches
      
      A limit to the depth of recursion was added in v0.3.47. From this version, an error will be returned
      rather than exhausting the stack.
      
      ## Workarounds
      
      Limiting the length of user input is the simplest way to avoid stack exhaustion, as the amount of
      the stack consumed would be at most a factor of the length of the input.
    ├ Announcement: https://github.com/time-rs/time/blob/main/CHANGELOG.md#0347-2026-02-05
    ├ Solution: Upgrade to >=0.3.47 (try `cargo update -p time`)
    ├ time v0.3.41
      ├── datadog-remote-config v0.0.1
      │   ├── (dev) datadog-remote-config v0.0.1 (*)
      │   ├── (dev) datadog-sidecar v0.0.1
      │   │   └── datadog-sidecar-ffi v0.0.1
      │   └── datadog-sidecar-ffi v0.0.1 (*)
      └── tracing-appender v0.2.3
          └── libdd-log v1.0.0
              └── (dev) libdd-data-pipeline v4.0.0
                  ├── datadog-live-debugger v0.0.1
                  │   ├── datadog-remote-config v0.0.1 (*)
                  │   ├── datadog-sidecar v0.0.1 (*)
                  │   └── datadog-sidecar-ffi v0.0.1 (*)
                  └── datadog-sidecar v0.0.1 (*)

advisories FAILED, bans ok, sources ok

📦 datadog-sidecar - 6 error(s)

Show output
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:37:1
   │
37 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     ├── datadog-ipc v0.1.0
     │   └── datadog-sidecar v0.0.1
     └── datadog-sidecar v0.0.1 (*)

error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:290:1
    │
290 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── datadog-sidecar v0.0.1
      ├── libdd-common v4.1.0
      │   ├── datadog-ipc v0.1.0
      │   │   └── datadog-sidecar v0.0.1 (*)
      │   ├── datadog-live-debugger v0.0.1
      │   │   ├── datadog-remote-config v0.0.1
      │   │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
      │   │   │   └── (dev) datadog-sidecar v0.0.1 (*)
      │   │   └── datadog-sidecar v0.0.1 (*)
      │   ├── datadog-remote-config v0.0.1 (*)
      │   ├── datadog-sidecar v0.0.1 (*)
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   ├── libdd-data-pipeline v4.0.0
      │   │   │   ├── datadog-live-debugger v0.0.1 (*)
      │   │   │   └── datadog-sidecar v0.0.1 (*)
      │   │   ├── libdd-shared-runtime v1.0.0
      │   │   │   ├── libdd-data-pipeline v4.0.0 (*)
      │   │   │   ├── libdd-telemetry v5.0.0
      │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   ├── libdd-crashtracker v1.0.0
      │   │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
      │   │   │   │   │       └── datadog-sidecar v0.0.1 (*)
      │   │   │   │   └── libdd-data-pipeline v4.0.0 (*)
      │   │   │   └── libdd-trace-stats v3.0.0
      │   │   │       ├── datadog-ipc v0.1.0 (*)
      │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │   │   │       └── libdd-data-pipeline v4.0.0 (*)
      │   │   ├── libdd-trace-stats v3.0.0 (*)
      │   │   └── libdd-trace-utils v4.0.0
      │   │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │       ├── libdd-data-pipeline v4.0.0 (*)
      │   │       ├── libdd-trace-obfuscation v3.0.0
      │   │       │   └── libdd-trace-stats v3.0.0 (*)
      │   │       ├── libdd-trace-stats v3.0.0 (*)
      │   │       └── (dev) libdd-trace-utils v4.0.0 (*)
      │   ├── libdd-common-ffi v34.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   └── libdd-crashtracker-ffi v34.0.0 (*)
      │   ├── (build) libdd-crashtracker v1.0.0 (*)
      │   ├── libdd-crashtracker-ffi v34.0.0 (*)
      │   ├── libdd-data-pipeline v4.0.0 (*)
      │   ├── libdd-dogstatsd-client v3.0.0
      │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   └── libdd-data-pipeline v4.0.0 (*)
      │   ├── libdd-shared-runtime v1.0.0 (*)
      │   ├── libdd-telemetry v5.0.0 (*)
      │   ├── libdd-trace-obfuscation v3.0.0 (*)
      │   ├── libdd-trace-stats v3.0.0 (*)
      │   └── libdd-trace-utils v4.0.0 (*)
      ├── libdd-crashtracker v1.0.0 (*)
      ├── (dev) libdd-data-pipeline v4.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   └── libdd-trace-utils v4.0.0 (*)
      ├── (dev) libdd-trace-stats v3.0.0 (*)
      ├── libdd-trace-utils v4.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── datadog-ipc v0.1.0 (*)
              ├── datadog-sidecar v0.0.1 (*)
              ├── libdd-data-pipeline v4.0.0 (*)
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v4.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:316:1
    │
316 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   └── datadog-sidecar v0.0.1
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   └── (dev) datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       └── datadog-sidecar v0.0.1 (*)
          │       │   │   │   └── libdd-data-pipeline v4.0.0 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:316:1
    │
316 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   └── datadog-sidecar v0.0.1
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   └── (dev) datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       └── datadog-sidecar v0.0.1 (*)
          │       │   │   │   └── libdd-data-pipeline v4.0.0 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:316:1
    │
316 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.1.0
          │       ├── datadog-ipc v0.1.0
          │       │   └── datadog-sidecar v0.0.1
          │       ├── datadog-live-debugger v0.0.1
          │       │   ├── datadog-remote-config v0.0.1
          │       │   │   ├── (dev) datadog-remote-config v0.0.1 (*)
          │       │   │   └── (dev) datadog-sidecar v0.0.1 (*)
          │       │   └── datadog-sidecar v0.0.1 (*)
          │       ├── datadog-remote-config v0.0.1 (*)
          │       ├── datadog-sidecar v0.0.1 (*)
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-data-pipeline v4.0.0
          │       │   │   ├── datadog-live-debugger v0.0.1 (*)
          │       │   │   └── datadog-sidecar v0.0.1 (*)
          │       │   ├── libdd-shared-runtime v1.0.0
          │       │   │   ├── libdd-data-pipeline v4.0.0 (*)
          │       │   │   ├── libdd-telemetry v5.0.0
          │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   ├── libdd-crashtracker v1.0.0
          │       │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
          │       │   │   │   │   └── libdd-crashtracker-ffi v34.0.0
          │       │   │   │   │       └── datadog-sidecar v0.0.1 (*)
          │       │   │   │   └── libdd-data-pipeline v4.0.0 (*)
          │       │   │   └── libdd-trace-stats v3.0.0
          │       │   │       ├── datadog-ipc v0.1.0 (*)
          │       │   │       ├── datadog-sidecar v0.0.1 (*)
          │       │   │       └── libdd-data-pipeline v4.0.0 (*)
          │       │   ├── libdd-trace-stats v3.0.0 (*)
          │       │   └── libdd-trace-utils v4.0.0
          │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
          │       │       ├── libdd-data-pipeline v4.0.0 (*)
          │       │       ├── libdd-trace-obfuscation v3.0.0
          │       │       │   └── libdd-trace-stats v3.0.0 (*)
          │       │       ├── libdd-trace-stats v3.0.0 (*)
          │       │       └── (dev) libdd-trace-utils v4.0.0 (*)
          │       ├── libdd-common-ffi v34.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── (build) libdd-crashtracker v1.0.0 (*)
          │       ├── libdd-crashtracker-ffi v34.0.0 (*)
          │       ├── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-dogstatsd-client v3.0.0
          │       │   ├── datadog-sidecar v0.0.1 (*)
          │       │   └── libdd-data-pipeline v4.0.0 (*)
          │       ├── libdd-shared-runtime v1.0.0 (*)
          │       ├── libdd-telemetry v5.0.0 (*)
          │       ├── libdd-trace-obfuscation v3.0.0 (*)
          │       ├── libdd-trace-stats v3.0.0 (*)
          │       └── libdd-trace-utils v4.0.0 (*)
          ├── libdd-common v4.1.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.1.0 (*)

error[vulnerability]: Denial of Service via Stack Exhaustion
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:371:1
    │
371 │ time 0.3.41 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0009
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0009
    ├ ## Impact
      
      When user-provided input is provided to any type that parses with the RFC 2822 format, a denial of
      service attack via stack exhaustion is possible. The attack relies on formally deprecated and
      rarely-used features that are part of the RFC 2822 format used in a malicious manner. Ordinary,
      non-malicious input will never encounter this scenario.
      
      ## Patches
      
      A limit to the depth of recursion was added in v0.3.47. From this version, an error will be returned
      rather than exhausting the stack.
      
      ## Workarounds
      
      Limiting the length of user input is the simplest way to avoid stack exhaustion, as the amount of
      the stack consumed would be at most a factor of the length of the input.
    ├ Announcement: https://github.com/time-rs/time/blob/main/CHANGELOG.md#0347-2026-02-05
    ├ Solution: Upgrade to >=0.3.47 (try `cargo update -p time`)
    ├ time v0.3.41
      ├── datadog-remote-config v0.0.1
      │   ├── (dev) datadog-remote-config v0.0.1 (*)
      │   └── (dev) datadog-sidecar v0.0.1
      └── tracing-appender v0.2.3
          └── libdd-log v1.0.0
              └── (dev) libdd-data-pipeline v4.0.0
                  ├── datadog-live-debugger v0.0.1
                  │   ├── datadog-remote-config v0.0.1 (*)
                  │   └── datadog-sidecar v0.0.1 (*)
                  └── datadog-sidecar v0.0.1 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-05-24 04:32:01 UTC | Commit: 26e220d | dependency-check job results

@datadog-official
Copy link
Copy Markdown

datadog-official Bot commented May 22, 2026

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 79.39%
Overall Coverage: 73.00% (+0.14%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a16e7cc | Docs | Datadog PR Page | Give us feedback!

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 22, 2026

Codecov Report

❌ Patch coverage is 79.39189% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.00%. Comparing base (cea1e44) to head (a16e7cc).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2026      +/-   ##
==========================================
+ Coverage   72.71%   73.00%   +0.28%     
==========================================
  Files         453      460       +7     
  Lines       74934    76085    +1151     
==========================================
+ Hits        54486    55543    +1057     
- Misses      20448    20542      +94     
Components Coverage Δ
libdd-crashtracker 65.21% <ø> (-0.10%) ⬇️
libdd-crashtracker-ffi 36.82% <ø> (-0.74%) ⬇️
libdd-alloc 98.77% <ø> (ø)
libdd-data-pipeline 86.69% <ø> (+0.78%) ⬆️
libdd-data-pipeline-ffi 78.63% <ø> (+4.70%) ⬆️
libdd-common 79.81% <ø> (ø)
libdd-common-ffi 74.41% <ø> (ø)
libdd-telemetry 73.34% <ø> (ø)
libdd-telemetry-ffi 31.36% <ø> (ø)
libdd-dogstatsd-client 82.64% <ø> (ø)
datadog-ipc 76.22% <ø> (ø)
libdd-profiling 81.70% <ø> (-0.02%) ⬇️
libdd-profiling-ffi 64.79% <ø> (ø)
libdd-sampling 97.46% <ø> (+<0.01%) ⬆️
datadog-sidecar 32.65% <79.39%> (+3.78%) ⬆️
datdog-sidecar-ffi 9.26% <0.00%> (+0.69%) ⬆️
spawn-worker 48.86% <ø> (ø)
libdd-tinybytes 93.16% <ø> (ø)
libdd-trace-normalization 81.71% <ø> (ø)
libdd-trace-obfuscation 87.30% <ø> (ø)
libdd-trace-protobuf 68.25% <ø> (ø)
libdd-trace-utils 88.86% <ø> (-0.73%) ⬇️
libdd-tracer-flare 86.88% <ø> (ø)
libdd-log 74.83% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Adds a parallel pathway for PHP feature-flag evaluation metrics
mirroring the FfeExposures forwarder. dd-trace-php encodes
`feature_flag.evaluations` counters as OTLP/protobuf in PHP
(via its existing PHP 7-safe `OtlpMetricEncoder`) and ships the
encoded bytes to the sidecar, which POSTs them to the user-configured
OTLP HTTP metrics intake.

Why a sibling action instead of reusing FfeExposures:

- The OTLP collector is not the Datadog Agent. It's user-configurable
  via OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (default
  http://localhost:4318/v1/metrics), so the endpoint travels with the
  payload rather than being derived from the sidecar session's agent
  base URL.
- Content type differs (application/x-protobuf vs application/json).
- No EVP subdomain header.
- The payload is binary protobuf, not a JSON string.

dd-trace-php side (PR DataDog/dd-trace-php#3911) will refactor its
existing `OtlpHttpMetricTransport` (which currently does PHP-side
HTTP I/O, violating the architectural rule "no I/O outside the
sidecar") to call this new FFI.

Validation:

- `cargo test -p datadog-sidecar ffe` passes 7 tests
  (3 exposures + 4 metrics).
- `cargo check -p datadog-sidecar-ffi` clean.
leoromanovsky added a commit to DataDog/dd-trace-php that referenced this pull request May 23, 2026
Adds Mermaid sources and rendered PNGs for the hook (this) PR plus a
README documenting the regeneration workflow.

- `docs/php-ffe-stack/stack-pr3909.mmd` + `.png` — 4-PR stack with this
  PR highlighted (M1 done; EVP and metrics as siblings to come).
- `docs/php-ffe-stack/system-pr3909.mmd` + `.png` — target system
  architecture; this PR contributes the EvaluationCompletedHook +
  OpenFeature provider hook surface. All downstream nodes (writers,
  sidecar FFI, sidecar process, backends) marked future.
- `docs/php-ffe-stack/README.md` — npx invocation for regenerating
  PNGs locally; PR-by-PR diagram table; architectural rule note.

The architectural rule encoded in the system diagram (all I/O via the
libdatadog sidecar) is the same rule Bob applied to PR #3910. See
DataDog/libdatadog#2026 for the sidecar-side support.
leoromanovsky added a commit to DataDog/dd-trace-php that referenced this pull request May 23, 2026
Per Bob's PR review (2026-05-22), the tracer extension must perform no
I/O outside the sidecar. Replaces the raw-socket `AgentExposureTransport`
with `SidecarExposureTransport`, which forwards exposure batches to the
libdatadog sidecar via a new native PHP function `\DDTrace\send_ffe_exposures`
that calls the `ddog_sidecar_send_ffe_exposures` FFI added in
DataDog/libdatadog#2026.

PHP side:

- Delete `Internal/Exposure/AgentExposureTransport.php` (raw socket
  POST to the Agent EVP proxy).
- Add `Internal/Exposure/SidecarExposureTransport.php` that JSON-encodes
  the batch and calls `\DDTrace\send_ffe_exposures()`. Fire-and-forget;
  the sidecar handles retries.
- Update `ExposureWriter::createDefault()` to instantiate the sidecar
  transport.
- Drop the obsolete `testAgentTransportBuildsAgentEvpRequest` PHPUnit
  test (HTTP construction now lives in libdatadog, covered by
  `cargo test -p datadog-sidecar ffe_flusher`).
- Add `Internal/DefaultEvaluationCompletedHook` and
  `Internal/CompositeEvaluationCompletedHook` so production callers go
  through a composite hook factory. In this PR the composite contains
  only `ExposureHook`; the metrics PR (#3911) contributes
  `EvaluationMetricHook` and the file conflict at merge resolves by
  combining both. Update `Client::create()` to call
  `DefaultEvaluationCompletedHook::create()`.

C/Rust bridge:

- Declare `ddog_ByteSlice` (and underlying `ddog_Slice_U8`) in
  `components-rs/common.h` for the metrics path; declare both
  `ddog_sidecar_send_ffe_exposures` and `ddog_sidecar_send_ffe_metrics`
  in `components-rs/sidecar.h`.
- Add C wrappers `ddtrace_sidecar_send_ffe_exposures(zend_string *)`
  and `ddtrace_sidecar_send_ffe_metrics(zend_string *endpoint,
  zend_string *payload_bytes)` in `ext/sidecar.{h,c}` that call the FFI
  with the current sidecar transport + instance id + queue id.
- Declare native PHP functions `\DDTrace\send_ffe_exposures(string): bool`
  and `\DDTrace\send_ffe_metrics(string, string): bool` in
  `ext/ddtrace.stub.php`; add corresponding arginfo entries and
  `ZEND_FUNCTION` registrations in `ext/ddtrace_arginfo.h`; implement
  `PHP_FUNCTION(DDTrace_send_ffe_exposures)` and
  `PHP_FUNCTION(DDTrace_send_ffe_metrics)` in `ext/ddtrace.c`.
- Bump `libdatadog` submodule to FFE branch tip `29762335c` (which
  provides both FFIs). The submodule will be bumped to the libdatadog
  main commit once #2026 merges.

Docs:

- Add `docs/php-ffe-stack/{stack,system}-pr3910.{mmd,png}` for this PR.

Validation:

- `php vendor/bin/phpunit --config phpunit.xml tests/api/Unit/FeatureFlags`
  → 41 tests, 174 assertions, OK.
- libdatadog sidecar tests (`cargo test -p datadog-sidecar ffe_flusher`)
  → 3 passed, on the pinned submodule commit.
- Mermaid PNGs regenerate via `npx @mermaid-js/mermaid-cli`.

`make test_featureflags` and `make test_c TESTS=tests/ext/ffe/...` will
run in CI; running them locally requires rebuilding the extension which
is gated behind libdatadog #2026 merging.
leoromanovsky added a commit to DataDog/dd-trace-php that referenced this pull request May 23, 2026
Adds the M3 evaluation-metrics layer on top of the hook PR (#3909) as a
sibling of the EVP exposures PR (#3910). Records `feature_flag.evaluations`
for both PHP 7 (DD Client hook) and PHP 8 (OpenFeature SDK hook); both
paths share `EvaluationMetricHook::sharedWriter()` for unified
aggregation. OTLP/protobuf payloads are encoded in PHP via the existing
`OtlpMetricEncoder` and delivered to the user-configured OTLP HTTP
metrics intake through the libdatadog sidecar (`ddog_sidecar_send_ffe_metrics`
FFI added in DataDog/libdatadog#2026).

This branch is force-pushed (user-authorized one-time exception to the
no-force-push rule, 2026-05-23) to restructure history away from being
linearly stacked on the M2 exposures PR (#3910). The PR now stacks
directly on the hook PR (#3909) as a sibling of the EVP PR.

PHP side:

- Add `Internal/Metric/EvaluationMetricWriter` with bounded series
  aggregation, drop accounting, and shutdown flush.
- Add `Internal/Metric/EvaluationMetricHook` (DD Client hook) and
  `OtlpMetricEncoder` (PHP 7-safe protobuf encoding).
- Add `Internal/Metric/SidecarOtlpMetricsTransport` that calls
  `\DDTrace\send_ffe_metrics()` (FFI declared in #3910). Endpoint
  resolution: `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, falling back to
  `OTEL_EXPORTER_OTLP_ENDPOINT + /v1/metrics`, default
  `http://localhost:4318/v1/metrics`.
- Add `DDTrace\OpenFeature\EvalMetricsHook` implementing
  `OpenFeature\interfaces\hooks\Hook` (after + error stages), registered
  on `DataDogProvider` via `setHooks()`.
- `DataDogProvider` constructs its internal DD `Client` with
  `DefaultEvaluationCompletedHook::createWithoutMetric()` so the
  OpenFeature path records the metric via the OpenFeature hook (PR 3911
  scope) and NOT via the DD Client hook — preventing double-counting.
  PHP 7 path keeps recording via the DD Client hook.
- Add `Internal/CompositeEvaluationCompletedHook` and
  `Internal/DefaultEvaluationCompletedHook` (metric-only composite).
  This is the merge-conflict point with PR #3910's `[ExposureHook]`
  composite — second merge resolves by combining both hooks.
- Update `Client::create()` to call `DefaultEvaluationCompletedHook::create()`.
- Drop the obsolete `testOtlpTransportBuildsHttpProtobufRequest` PHPUnit
  test (HTTP construction now lives in libdatadog, covered by
  `cargo test -p datadog-sidecar ffe_metrics_flusher`).
- Add `_files_openfeature.php` entry for `EvalMetricsHook.php`.

C/Rust bridge: the `\DDTrace\send_ffe_metrics()` native function, its C
wrapper `ddtrace_sidecar_send_ffe_metrics()`, and the
`ddog_sidecar_send_ffe_metrics` FFI declaration in `components-rs/sidecar.h`
were already added in #3910. This PR's branch picks up those changes
once #3910 merges (or via the same libdatadog submodule pin during
review). For development locally the libdatadog submodule is pinned to
the FFE branch tip (`29762335c`).

Docs:

- Add `docs/php-ffe-stack/{stack,system}-pr3911.{mmd,png}` per the
  4-PR documentation convention.

Validation:

- `php vendor/bin/phpunit --config phpunit.xml tests/api/Unit/FeatureFlags`
  → 40 tests, 160 assertions, OK.
- Mermaid PNGs regenerate via `npx @mermaid-js/mermaid-cli`.

`make test_featureflags`, OpenFeature PHPUnit, and ffe-dogfooding
end-to-end validation will run in CI / are validated separately by
FOLLOW-05 Steps 4–5.
The PHP FFE writers (`SidecarExposureTransport`,
`SidecarOtlpMetricsTransport`) can fire as soon as evaluations begin —
which is often earlier than the first remote-config metadata call that
registers the application against a `QueueId`.

Previously, FFE dispatch lived inside the
`if let Entry::Occupied(entry) = applications.entry(queue_id) { ... }`
block in `enqueue_actions`. That block is only entered after the PHP
runtime has called `set_remote_config_data` or `set_request_config` for
this queue. For shorter-lived PHP processes (parametric test client,
CLI tools, eager evaluators) the FFE batch arrives before the app
registration call lands, so the entire batch was silently dropped.

This change filters `FfeExposures` and `FfeMetrics` actions out of
the action vec before the application-entry gate and dispatches them
directly: both only need session-level state (the trace endpoint /
the user-supplied OTLP endpoint), not per-application telemetry context.

Validated locally with dd-trace-php system-tests parametric
`Test_Feature_Flag_Parametric_Evaluation_Metrics::test_php_ffe_evaluation_metric`,
which now passes (26/27 FFE-scoped tests; remaining failure is the
exposure_event test on a branch that lacks the exposure code path).
Pair the EVP-exposure forwarder name with its sibling `ffe_metrics_flusher`.
The unqualified `ffe_flusher` predates the OTLP-metrics forwarder and the
asymmetry was leaving readers wondering whether `ffe_flusher` was a
parent/umbrella module or a sibling.

Renames the file via `git mv` (preserving blame history) and updates all
references (mod.rs, sidecar_server.rs dispatch arm, ffe_metrics_flusher.rs
cross-reference in the module doc, and the CODEOWNERS entry).

No functional change.
The renamed identifier pushed one debug! line past rustfmt's column
limit. Apply `cargo fmt -p datadog-sidecar -p datadog-sidecar-ffi` to
break the macro across three lines, matching CI's nightly-2026-02-08
rustfmt.
Single architecture diagram showing the end-to-end FFE delivery path
through the sidecar:

  tracer payload → ddog_sidecar_send_ffe_{exposures,metrics} FFI
                 → tarpc enqueue_actions IPC
                 → sidecar_server.rs enqueue_actions handler
                 → FFE filter (lifted out of applications.entry gate, this PR)
                 → ffe_exposures_flusher / ffe_metrics_flusher
                 → NativeCapabilities HTTP client
                 → Agent EVP proxy / OTLP HTTP intake

Uses `flowchart TD` and a quoted YAML title (Mermaid's frontmatter
parser eats unquoted `#` as comments). PNG rendered at 2400×2400
`--scale 3 -b white` for legible PR-page thumbnails.
@leoromanovsky leoromanovsky marked this pull request as ready for review May 24, 2026 13:05
@leoromanovsky leoromanovsky requested review from a team as code owners May 24, 2026 13:05
Copy link
Copy Markdown

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

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: a16e7cc147

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

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
};

match client.request(req).await {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply endpoint timeouts when forwarding FFE batches

This awaits HttpClientCapability::request directly, so the new FFE metric forwarder never applies the Endpoint::timeout_ms deadline used by the existing trace path (send_with_retry races the request against the endpoint timeout). When the configured OTLP collector accepts a connection but stops responding, each flush task spawned from enqueue_actions can remain alive indefinitely and accumulate sockets/tasks instead of being dropped as fire-and-forget; the exposure flusher has the same pattern. Please wrap the request with the endpoint timeout or route through the common send helper.

Useful? React with 👍 / 👎.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants