out_opentelemetry: add metadata token authentication#11721
out_opentelemetry: add metadata token authentication#11721evgfitil wants to merge 1 commit intofluent:masterfrom
Conversation
Signed-off-by: Evgenii Akhmetzianov <evgfitil@gmail.com>
📝 WalkthroughWalkthroughThis pull request adds cloud metadata endpoint token authentication to the OpenTelemetry output plugin. It introduces new configuration options ( Changes
Sequence DiagramssequenceDiagram
participant Flush as Flush Operation
participant Metadata as Metadata Token Module
participant HTTP as HTTP Client
participant Endpoint as Metadata Endpoint
participant OAuth2 as OAuth2 Context
participant Request as OTLP Request
Flush->>Metadata: flb_otel_metadata_token_refresh()
Metadata->>OAuth2: Lock oauth2_mutex
alt Token Valid (within skew)
Metadata->>OAuth2: Unlock, skip refresh
else Token Expired
Metadata->>OAuth2: Unlock temporarily
Metadata->>HTTP: GET metadata_token_url
HTTP->>Endpoint: HTTP GET request
Endpoint-->>HTTP: 200 + {access_token, expires_in}
HTTP-->>Metadata: Response body
Metadata->>Metadata: Parse JSON, compute TTL
Metadata->>OAuth2: Lock oauth2_mutex
Metadata->>OAuth2: Update access_token, expires_at
Metadata->>OAuth2: Unlock
end
Flush->>Request: Dispatch OTLP data
Request->>Request: Inject Bearer token from OAuth2
sequenceDiagram
participant Plugin as Plugin
participant HTTP as HTTP Client
participant Metadata as Metadata Module
participant Server as OTLP Server
Plugin->>Metadata: Token acquire (HTTP/2 path)
Metadata->>Metadata: Lock metadata_mutex
Metadata->>HTTP: Fetch access_token from OAuth2
Metadata->>Metadata: Copy token to owned SDS
Metadata->>Metadata: Unlock metadata_mutex
Metadata-->>Plugin: Bearer token
Plugin->>HTTP: Construct request + Bearer header
HTTP->>Server: POST with Authorization header
Server-->>HTTP: 200 OK
HTTP-->>Plugin: Success
Plugin->>Metadata: Free copied token
sequenceDiagram
participant OTLP as OTLP Request
participant Server as OTLP Server
participant Plugin as Plugin
participant Metadata as Metadata Module
OTLP->>Server: POST with Bearer token
Server-->>OTLP: 401 Unauthorized
OTLP->>Plugin: Handle 401 response
Plugin->>Plugin: Invalidate oauth2_ctx->access_token
Plugin->>Metadata: flb_otel_metadata_token_refresh()
Metadata->>Metadata: Fetch fresh token from metadata endpoint
Metadata-->>Plugin: New Bearer token
Plugin->>Server: Retry POST with new Bearer token
Server-->>Plugin: 200 OK
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/runtime/CMakeLists.txt (1)
263-263: Consider adding port serialization for this test.The test file uses several mock server ports (18901, 18902, 18903, 18904). While these ports don't conflict with the existing serialized tests (2020, 4318, 5170), if other tests start using similar high ports, there could be conflicts. Consider adding a
flb_runtime_lock_testsentry if port conflicts arise in CI.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/runtime/CMakeLists.txt` at line 263, The test registered with FLB_RT_TEST for FLB_OUT_OPENTELEMETRY uses hardcoded mock ports and should be serialized to avoid CI port conflicts; update the test registration by either replacing FLB_RT_TEST(FLB_OUT_OPENTELEMETRY "out_opentelemetry.c") with the serialized variant (e.g., FLB_RT_TEST_SERIALIZED or your repo's equivalent) or add FLB_OUT_OPENTELEMETRY to the flb_runtime_lock_tests list so the runtime test harness runs it under the test lock/serialization mechanism.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/runtime/CMakeLists.txt`:
- Line 263: The test registered with FLB_RT_TEST for FLB_OUT_OPENTELEMETRY uses
hardcoded mock ports and should be serialized to avoid CI port conflicts; update
the test registration by either replacing FLB_RT_TEST(FLB_OUT_OPENTELEMETRY
"out_opentelemetry.c") with the serialized variant (e.g., FLB_RT_TEST_SERIALIZED
or your repo's equivalent) or add FLB_OUT_OPENTELEMETRY to the
flb_runtime_lock_tests list so the runtime test harness runs it under the test
lock/serialization mechanism.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ac41ace1-7fb5-4569-8888-35916cd02409
📒 Files selected for processing (8)
plugins/out_opentelemetry/CMakeLists.txtplugins/out_opentelemetry/opentelemetry.cplugins/out_opentelemetry/opentelemetry.hplugins/out_opentelemetry/opentelemetry_conf.cplugins/out_opentelemetry/opentelemetry_metadata.cplugins/out_opentelemetry/opentelemetry_metadata.htests/runtime/CMakeLists.txttests/runtime/out_opentelemetry.c
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 50d4814712
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| sep = strstr(ctx->metadata_token_header, ": "); | ||
| if (sep) { | ||
| name_len = (size_t)(sep - ctx->metadata_token_header); |
There was a problem hiding this comment.
Accept header syntax without mandatory space after ':'
The metadata header parser only accepts values containing the exact ": " separator, so a valid header like Metadata-Flavor:Google is silently dropped. For metadata endpoints that require this header (for example, GCP), token fetches will fail and every flush will retry even though the user supplied a syntactically valid HTTP header. Split on ':' and trim optional whitespace instead of requiring a literal colon-space sequence.
Useful? React with 👍 / 👎.
| tmp = flb_sds_cat(ctx->metadata_token_path, | ||
| ctx->metadata_token_scope, | ||
| strlen(ctx->metadata_token_scope)); |
There was a problem hiding this comment.
URL-encode metadata query parameters before appending
The scope/audience values are concatenated into the request URI without percent-encoding. If a value contains reserved characters (e.g., spaces in multi-scope strings, &, or =), the generated query string is malformed or semantically altered, which can break token retrieval or send unintended parameters. Encode user-provided query values before appending them to metadata_token_path.
Useful? React with 👍 / 👎.
|
hi @evgfitil , thanks for contributing this. The feature makes sense, but Those names describe the implementation detail instead of the auth model. This is still OAuth2/Bearer auth with a different token source, so it would be cleaner to keep it under A cleaner shape would be something like:
and then reuse the existing generic fields for the rest, such as |
Closes #11675
The OTel output plugin supports OAuth2 client-credentials authentication but has no way to fetch Bearer tokens from cloud instance metadata endpoints - the standard mechanism on platforms where a VM has a linked service account.
Today the only options are a sidecar proxy or a custom build. The
out_stackdriverplugin already solves this for GCP viagce_metadata.c; this PR brings the same capability to the OTel plugin in a cloud-neutral way - no vendor-specific naming, no new dependencies.New configuration options
metadata_token_urlmetadata_token_headerMetadata-Flavor: Google)metadata_token_refresh3600metadata_token_scope?scopes=<value>query parametermetadata_token_audience?audience=<value>query parameterToken caching, periodic refresh, and 401 retry reuse the existing oauth2 code paths - no new token injection mechanism is introduced
Testing
Config and logs - token fetch with metadata_token_scope
Config and logs - token fetch without scope
[OUTPUT] Name opentelemetry Match * Host 127.0.0.1 Port 4318 Logs_uri /v1/logs metadata_token_url http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token metadata_token_header Metadata-Flavor: Google metadata_token_refresh 3600Config and logs - token refresh cycle (metadata_token_refresh=90)
Valgrind - 25 tests, 0 leaks, 0 errors
Build:
cmake -DFLB_DEV=On -DFLB_VALGRIND=On -DFLB_TESTS_RUNTIME=Onok-package-testlabel (requires maintainer)Documentation
Backporting
Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.
Summary by CodeRabbit
New Features
metadata_token_url,metadata_token_header,metadata_token_refresh,metadata_token_scope, andmetadata_token_audience.Tests