[AGENTCFG-35] Trigger a secret refresh on expired api key - #41589
Merged
dd-mergequeue[bot] merged 140 commits intoNov 24, 2025
Conversation
…guration to take in secret_refresh_on_api_key_failure and
git-thuerk-done
approved these changes
Oct 7, 2025
aureleoules
approved these changes
Nov 20, 2025
dustmop
approved these changes
Nov 20, 2025
dustmop
left a comment
Contributor
There was a problem hiding this comment.
Thanks for all the fixes, LGTM!
1 task
vickenty
approved these changes
Nov 24, 2025
vickenty
left a comment
Contributor
There was a problem hiding this comment.
Left a small nit, but otherwise LGTM.
Member
Author
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in
|
dd-mergequeue
Bot
deleted the
saad/expired-apikey-trigger-secret-refresh
branch
November 24, 2025 21:42
gh-worker-dd-mergequeue-cf854d Bot
pushed a commit
that referenced
this pull request
Apr 7, 2026
…key refresh (#46704) Instead of dropping log payloads on 403 Forbidden responses, treat them as retryable errors and trigger a throttled secrets refresh so the next retry attempt uses the updated API key. This new behavior only takes effect if a viable (non-nil) secrets component is supplied to Logs Pipeline, indicating a key refresh is possible to perform. ### What does this PR do? **Core 403 retry logic** - **`pkg/logs/client/http/destination.go`**: On HTTP 403, if a `secrets.Component` is present, call `secrets.Refresh(false)` (throttled async refresh) and return `RetryableError` instead of dropping the payload. Without secrets (`nil`), the existing drop behavior is preserved. - **`pkg/logs/pipeline/provider.go`**: Add `NewProviderWithSecrets` constructor that accepts an optional `secrets.Component` and threads it down to `NewDestination`. The existing `NewProvider` delegates to this with `nil` for backward compatibility. **Wiring secrets to callers** - **Core logs agent** (`comp/logs/agent/agentimpl/`): Inject `secrets.Component` via fx and pass it through `NewProviderWithSecrets`. - **Event platform forwarder** (`comp/forwarder/eventplatform/eventplatformimpl/`): Inject `secrets.Component` via fx and pass it through `NewHTTPSender` to `NewDestination`. The noop forwarder passes `nil`. - **CWS and compliance reporters** (`pkg/security/reporter/`, `pkg/compliance/`): Accept `secrets.Component` and call `NewProviderWithSecrets`. Intermediate call chains in `pkg/security/module/` and `pkg/compliance/` updated to thread it through. **Behavior on other Agent binaries** - **security-agent** and **cluster-agent** already have a real `secrets.Component` in their fx graphs; updated their FX providers and call sites to pass it through to `StartRuntimeSecurity`, `StartCompliance`, and `runCompliance`. - **system-probe** uses `secretsnoopfx` (no-op secrets); added `Secrets secrets.Component` to `FactoryDependencies` and passed it through to `NewCWSConsumer` and `StartCompliance` so the plumbing is consistent, but no actual refresh occurs. **Test fixes** - **`comp/networkpath/npcollector/npcollectorimpl/npcollector_testutils.go`**: Switched from `eventplatformimpl.Module` to `MockModule()` to avoid the real EP forwarder's new secrets dependency and a shutdown timeout caused by 403 retries during test teardown. - New `TestForbiddenTriggersSecretsRefreshAndRetry` unit test in `destination_test.go`. Remaining test files updated to provide `secretsnoopfx.Module()` or pass `nil` for the new `secrets.Component` parameter. ### Motivation This is the logs-agent counterpart to PR #41589, which added API key refresh on 403 to the core forwarder. The core forwarder's health check already handles 403s from its own HTTP calls, but the logs pipeline and event platform forwarder use a separate `pkg/logs/client/http/Destination` that previously dropped payloads on 403. This PR extends the same secret-refresh-on-403 pattern to those codepaths. The secrets component is threaded into every process that has access to it via fx (core agent, security-agent, cluster-agent, system-probe), so that 403 retry + key refresh is available wherever the logs HTTP destination is used. Callers without the secrets component (serverless, OTel) retain the original drop behavior. ### Describe how you validated your changes - **Unit tests**: New `TestForbiddenTriggersSecretsRefreshAndRetry` in `destination_test.go` using a mock secrets component that tracks `Refresh` calls. - **Manual test**: Configured agent with a throwaway API key (`ENC[datadog_api_key]` + `secret_backend_command`), verified 403 retry + secret refresh + successful log delivery after key update via `dda inv agent.exec -- status`. ### Additional Notes - Callers without the secrets component (connectivity checks, noop forwarder, sync destinations for serverless/OTel) pass `nil`, preserving the existing 403-drops-payload behavior. - The EP forwarder has a pre-existing shutdown ordering issue (context canceled after pipeline stop) that becomes visible when 403s are retried. This is tracked by the existing TODO at `epforwarder.go:459` and is out of scope for this PR. Co-authored-by: ryan.hall <ryan.hall@datadoghq.com>
gh-worker-devtools-f43747
Bot
deleted the
saad/expired-apikey-trigger-secret-refresh
branch
May 27, 2026 03:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Triggers a secret refresh whenever an API key expires. (whenver we get a 403 or the routine health probe checks for the api key validity)
Motivation
Allows for a more seamless way to refresh secrets and api-key without requiring manual editing
Describe how you validated your changes
manual testing
secret_backend_command: <somepath>/secret.shsecret_refresh_on_api_key_failure_intervalconfig to a value greater than 0secret_refresh_on_api_key_failure_interval: 1forwarder_apikey_validation_interval: 1example output from logging
Additional Notes
NewDefaultForwarderandNewDefaultForwarderWithSecrets. Ideally there would only be one functionNewDefaultForwarderwhich needs a secret component, howevergithub.com/open-telemetry/opentelemetry-collector-contrib/pkg/datadog/agentcomponentsdepends on aNewDefaultForwarderthat does not take in secrets so to maintain compatability,NewDefaultForwardernow callsNewDefaultForwarderWithSecretswith noop secrets.Refresh()function now implements a rate-limit and takes in a boolean to disable the rate-limit