WIF-48: wire credential providers into forwarder, trace, and logs - #55480
WIF-48: wire credential providers into forwarder, trace, and logs#55480wynbennett wants to merge 14 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6259bb758b
ℹ️ 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".
| if errors.Is(err, ErrCredentialNotReady) { | ||
| return err |
There was a problem hiding this comment.
Delay completion when requeuing credential waits
When a provider credential is unavailable for a non-retryable transaction, such as SubmitRTContainerChecks, this new return sends the transaction back to Worker.process for requeueing even though Process has already invoked CompletionHandler because Retryable is false. The caller therefore receives a failed completion immediately, and the same transaction can later invoke the handler again and send stale data after the credential arrives. If this sentinel is returned for requeueing, suppress completion until the transaction actually finishes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit cc694e6. The ErrCredentialNotReady check now runs before the completion handler, so CompletionHandler is suppressed for credential-wait requeues. It will only fire when the retried transaction actually finishes (success or real failure).
| if s.awaitingCredential.Load() { | ||
| _ = s.statsd.Count("datadog.trace_agent.sender.payload_dropped_awaiting_credential", 1, nil, 1) | ||
| return |
There was a problem hiding this comment.
Release payloads dropped while awaiting credentials
When a delegated-auth sender's queue is full, this path abandons p without returning it to ppool or recording an eventTypeDropped event through the writer recorder. While a credential remains unavailable, every subsequent trace or stats flush hitting the full queue therefore allocates and discards another potentially large buffer, increasing GC pressure while the trace-writer status telemetry underreports the loss. Perform the normal drop bookkeeping and return the payload to the pool without underflowing inflight.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in commit cc694e6. The drop path now calls recordEvent(eventTypeDropped, ...) and returns the payload to ppool, matching the normal drop bookkeeping. This fixes both the GC pressure from leaked buffers and the telemetry underreporting.
6259bb7 to
1c70b30
Compare
Go Package Import DifferencesBaseline: d725d90
|
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
This comment has been minimized.
This comment has been minimized.
Files inventory check summaryFile checks results against ancestor c35c49a9: Results for datadog-agent_7.84.0~devel.git.604.9b9a9e2.pipeline.134054590-1_amd64.deb:Detected file changes:
|
Static quality checks❌ Please find below the results from static quality gates Error
Gate failure full details
Static quality gate failures prevent this PR from merging! Successful checksInfo
|
Regression DetectorRegression Detector ResultsMetrics dashboard Baseline: d725d90 Optimization Goals: ✅ No significant changes detected
|
| perf | experiment | goal | Δ mean % | Δ mean % CI | trials | links |
|---|---|---|---|---|---|---|
| ➖ | dsd_uds_10mb_3k_timestamped_contexts_memory | memory utilization | +1.30 | [+1.09, +1.50] | 1 | Logs |
| ➖ | quality_gate_private_action_runner | memory utilization | +0.80 | [+0.68, +0.91] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_idle | memory utilization | +0.68 | [+0.64, +0.72] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_security_mean_fs_load | memory utilization | +0.60 | [+0.57, +0.64] | 1 | Logs bounds checks dashboard |
| ➖ | dsd_uds_10mb_3k_timestamped_contexts_cpu | % cpu utilization | +0.60 | [+0.36, +0.84] | 1 | Logs |
| ➖ | quality_gate_security_idle | memory utilization | +0.43 | [+0.38, +0.49] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_security_no_fs_load | memory utilization | +0.42 | [+0.35, +0.50] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_idle_all_features | memory utilization | +0.26 | [+0.23, +0.30] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_metrics_logs | memory utilization | -0.39 | [-0.62, -0.17] | 1 | Logs bounds checks dashboard |
| ➖ | quality_gate_logs | % cpu utilization | -1.61 | [-2.48, -0.73] | 1 | Logs bounds checks dashboard |
Bounds Checks: ✅ Passed
| perf | experiment | bounds_check_name | replicates_passed | observed_value | links |
|---|---|---|---|---|---|
| ✅ | quality_gate_idle | intake_connections | 10/10 | 4 = 4 | bounds checks dashboard |
| ✅ | quality_gate_idle | memory_usage | 10/10 | 173.03MiB ≤ 179MiB | bounds checks dashboard |
| ✅ | quality_gate_idle | total_bytes_received | 10/10 | 751.30KiB ≤ 819.20KiB | bounds checks dashboard |
| ✅ | quality_gate_idle_all_features | intake_connections | 10/10 | 4 = 4 | bounds checks dashboard |
| ✅ | quality_gate_idle_all_features | memory_usage | 10/10 | 526.42MiB ≤ 537MiB | bounds checks dashboard |
| ✅ | quality_gate_idle_all_features | total_bytes_received | 10/10 | 1.15MiB ≤ 1.25MiB | bounds checks dashboard |
| ✅ | quality_gate_logs | intake_connections | 10/10 | 19 ≤ 40 | bounds checks dashboard |
| ✅ | quality_gate_logs | memory_usage | 10/10 | 215.07MiB ≤ 228MiB | bounds checks dashboard |
| ✅ | quality_gate_logs | missed_bytes | 10/10 | 0B = 0B | bounds checks dashboard |
| ✅ | quality_gate_logs | total_bytes_received | 10/10 | 263.50MiB ≤ 292MiB | bounds checks dashboard |
| ✅ | quality_gate_metrics_logs | cpu_usage | 10/10 | 376.98 ≤ 2000 | bounds checks dashboard |
| ✅ | quality_gate_metrics_logs | intake_connections | 10/10 | 21 ≤ 40 | bounds checks dashboard |
| ✅ | quality_gate_metrics_logs | memory_usage | 10/10 | 394.36MiB ≤ 455MiB | bounds checks dashboard |
| ✅ | quality_gate_metrics_logs | missed_bytes | 10/10 | 0B = 0B | bounds checks dashboard |
| ✅ | quality_gate_metrics_logs | total_bytes_received | 10/10 | 0.94GiB ≤ 1.04GiB | bounds checks dashboard |
| ✅ | quality_gate_private_action_runner | memory_usage | 10/10 | 72.79MiB ≤ 75MiB | bounds checks dashboard |
| ✅ | quality_gate_security_idle | cpu_usage | 10/10 | 28.92 ≤ 100 | bounds checks dashboard |
| ✅ | quality_gate_security_idle | memory_usage | 10/10 | 329.22MiB ≤ 355MiB | bounds checks dashboard |
| ✅ | quality_gate_security_mean_fs_load | cpu_usage | 10/10 | 61.28 ≤ 200 | bounds checks dashboard |
| ✅ | quality_gate_security_mean_fs_load | memory_usage | 10/10 | 307.59MiB ≤ 335MiB | bounds checks dashboard |
| ✅ | quality_gate_security_no_fs_load | cpu_usage | 10/10 | 23.15 ≤ 100 | bounds checks dashboard |
| ✅ | quality_gate_security_no_fs_load | memory_usage | 10/10 | 310.81MiB ≤ 345MiB | bounds checks dashboard |
Explanation
Confidence level: 90.00%
Effect size tolerance: |Δ mean %| ≥ 5.00%
Performance changes are noted in the perf column of each table:
- ✅ = significantly better comparison variant performance
- ❌ = significantly worse comparison variant performance
- ➖ = no significant change in performance
A regression test is an A/B test of target performance in a repeatable rig, where "performance" is measured as "comparison variant minus baseline variant" for an optimization goal (e.g., ingress throughput). Due to intrinsic variability in measuring that goal, we can only estimate its mean value for each experiment; we report uncertainty in that value as a 90.00% confidence interval denoted "Δ mean % CI".
For each experiment, we decide whether a change in performance is a "regression" -- a change worth investigating further -- if all of the following criteria are true:
-
Its estimated |Δ mean %| ≥ 5.00%, indicating the change is big enough to merit a closer look.
-
Its 90.00% confidence interval "Δ mean % CI" does not contain zero, indicating that if our statistical model is accurate, there is at least a 90.00% chance there is a difference in performance between baseline and comparison variants.
-
Its configuration does not mark it "erratic".
CI Pass/Fail Decision
✅ Passed. All Quality Gates passed.
- quality_gate_idle_all_features, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
- quality_gate_idle_all_features, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_idle_all_features, bounds check intake_connections: 10/10 replicas passed. Gate passed.
- quality_gate_security_mean_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_security_mean_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
- quality_gate_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
- quality_gate_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
- quality_gate_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
- quality_gate_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_metrics_logs, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_metrics_logs, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
- quality_gate_metrics_logs, bounds check missed_bytes: 10/10 replicas passed. Gate passed.
- quality_gate_metrics_logs, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
- quality_gate_metrics_logs, bounds check intake_connections: 10/10 replicas passed. Gate passed.
- quality_gate_security_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_security_idle, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
- quality_gate_private_action_runner, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_idle, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_idle, bounds check total_bytes_received: 10/10 replicas passed. Gate passed.
- quality_gate_idle, bounds check intake_connections: 10/10 replicas passed. Gate passed.
- quality_gate_security_no_fs_load, bounds check memory_usage: 10/10 replicas passed. Gate passed.
- quality_gate_security_no_fs_load, bounds check cpu_usage: 10/10 replicas passed. Gate passed.
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
da969c8 to
515bae2
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
515bae2 to
20afbc1
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
9b9a9e2 to
9d1ca50
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
9d1ca50 to
afb8e42
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
afb8e42 to
44acba4
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
44acba4 to
82c87aa
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
…logs agent This PR wires the credential Provider interface from delegatedauth into the three data-plane consumers: Forwarder: - Forwarder takes credentials from providers, buffering until they resolve - Resolver discovers credential providers for each endpoint - Transactions carry credential context - OTel sync forwarder accepts a delegated auth component - HTTP transactions serializer hardened for credential backpressure Trace writers: - Trace writers take credentials from providers, holding payloads until resolve - Sender resolves credentials before forwarding - Pipeline stats skips delegated-auth endpoints (no API key) - Trace agent impl and config wiring for credential providers Logs agent: - Logs endpoints take their credential from a provider - Wire delegated auth into the logs agent end to end - Stop logs TCP from leaking the directive on the wire - Harden Authorize, fix serverless build - Logs library HTTP destination supports credential providers
Fix two findings from the Codex/Autotest review: 1. (P2) Delay completion when requeuing credential waits For a non-retryable transaction with ErrCredentialNotReady, the CompletionHandler was called before the requeue, and again when the retried transaction finished. Now the credential-not-ready check runs before the completion handler, so completion is suppressed until the transaction actually finishes. 2. (P2) Release payloads dropped while awaiting credentials When a delegated-auth sender's queue was full, the payload was abandoned without returning it to ppool or recording an eventTypeDropped event. Now the drop bookkeeping runs and the payload is returned to the pool, reducing GC pressure and fixing telemetry underreporting.
The NewOTelSyncForwarder signature gained a delegatedauth.Component parameter in this PR, but two callers in serializerexporter were not updated: - serializer.go: fx.Provide now accepts delegatedauth.Component and passes it to NewOTelSyncForwarder - exporter_test.go: passes nil for the delegated auth component - BUILD.bazel: added dep on delegatedauth/def
The NewOTelSyncForwarder signature gained a delegatedauth.Component parameter, but the call in commonAgentFxOptions was not updated. The fx.Provide now accepts delegatedauth.Component (still the noop at this point) and passes it through. PR3 replaces the noop with the real component.
Add tests to each consumer's credential provider test file verifying that an ENC[...] key resolved by the secrets backend behaves as a normal static key — the provider path does not interfere with it. Forwarder: TestResolvedEncKeyUnaffectedByProvider Trace writer: TestAuthorizeStampsResolvedEncKeyWhenThereIsNoProvider Logs: TestAuthorizeStampsResolvedEncKey
Rebase onto foundation which added Refresh() to the Provider interface. Update stubProvider implementations in resolver, logs, and trace writer tests to satisfy the updated interface. WIF-48
…ests Replace the per-package stubProvider copies in resolver, logs, and trace writer tests with the shared StubProvider from comp/core/delegatedauth/mock. WIF-48
_test.go files are only visible within their own package. Move StubProvider to a regular .go file so consumer test packages (resolver, logs, trace writer, trace API) can import it from delegatedauth/mock. WIF-48
- Resolver: CredentialProvider alias points to credential.Provider - Logs: CredentialProvider alias, CredentialProviderLookup → credential.Lookup, isDelaDirective → credential.IsDirective - Trace config: remove redeclared CredentialProvider interface, use credential.Provider alias; CredentialProviderFn → credential.Lookup - Trace writer: apiKeyManager.Authorize → credential.StampAuth, remove headerAPIKey const - Fix gofmt and test reference to removed headerAPIKey const - Update go.mod replace directives for pkg/credential WIF-48
…oint.Authorize
- Remove the isDelaDirective one-liner wrapper; call credential.IsDirective
directly at all 4 call sites in endpoints.go and in the test
- Rewrite Endpoint.Authorize to use credential.StampAuth instead of the
inline h.Set("DD-API-KEY", ...) pattern, keeping the credentialDirective
guard as a logs-specific pre-check
WIF-48
82c87aa to
735c243
Compare
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
BenchmarksBenchmark execution time: 2026-08-31 19:23:29 Comparing candidate commit 35d25a7 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 3 metrics, 0 unstable metrics.
|
Gazelle requires this because credential_provider_test.go imports pkg/credential for credential.IsDirective. WIF-48
…rders Process and orchestrator forwarders create their own resolvers via NewSingleDomainResolvers, which don't go through the main forwarder's provider-wired resolver. This PR threads delegatedauth.Component into both forwarders and calls ProvidersFor + SetCredentialProviders on their resolvers, matching the pattern from PR #55480. Process: comp/process/forwarders/impl/forwarders.go Orchestrator: comp/forwarder/orchestrator/impl/forwarder_orchestrator.go
Summary
This PR wires the credential
Providerinterface from PR #55479 into the three data-plane consumers: the core agent forwarder, the APM trace writers, and the logs agent. Each consumer discovers the providers registered for its endpoints and callsAuthorizeon every outbound request — buffering payloads while a credential is still resolving, then sending once it is available.Data flow
Forwarder (metrics, events, service checks)
The forwarder resolver (
domain_resolver.go) callsProvidersForto discover credential providers for each endpoint domain. Transactions carry the resolved credential context through to the HTTP transaction serializer, which stamps theDD-Api-Keyheader viaAuthorizebefore sending. If no provider is available for an endpoint, the forwarder falls back to the configured static API key, so existing behavior is unchanged for endpoints without a DELA directive. A newcredential_backpressure_test.goverifies that the forwarder buffers transactions until the provider resolves.Trace writers (traces, APM stats)
The trace agent (
comp/trace/agent/impl/agent.go) receives the delegated auth component and passes it through to the trace writers. The sender (pkg/trace/writer/sender.go) resolves credentials per endpoint before forwarding, holding payloads in a buffer until the provider reports a usable credential. Pipeline stats (pkg/trace/api/pipeline_stats.go) skips delegated-auth endpoints entirely, since that proxy path has no provider wiring and would otherwise forward with an empty API key. A newcredential_provider_test.gocovers the buffering and resolution lifecycle.Logs agent (logs HTTP destination)
The logs config (
comp/logs/agent/config/endpoints.go) partitions additional endpoints into real API keys and pending (DELA directive) keys, associating each directive with its credential provider. The logs agent impl (comp/logs/agent/impl/agent.go) receives the delegated auth component and passes it through to the HTTP destination (comp/logs-library/client/http/destination.go), which callsAuthorizeon each request. The serverless init path was updated to avoid leaking the directive on the wire for TCP connections. Newconfig_keys.goentries expose the credential provider settings.go.mod changes
comp/forwarder/defaultforwarder/go.mod:delegatedauthmoved from indirect to direct require.comp/logs/agent/config/go.mod:delegatedauthandpkg/config/mockmoved from indirect to direct require.Architecture doc
See Delegated Authentication in the Agent: Architecture and Path Forward for the full design, including the previous approach vs. the new Provider interface, locking, and future work.
Stacked PRs
WIF-48