Skip to content

oauth2: harden configuration, JWKS refresh, and token lifetimes#12106

Open
edsiper wants to merge 11 commits into
masterfrom
oauth2-end-to-end-audit-noissue
Open

oauth2: harden configuration, JWKS refresh, and token lifetimes#12106
edsiper wants to merge 11 commits into
masterfrom
oauth2-end-to-end-audit-noissue

Conversation

@edsiper

@edsiper edsiper commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • reject generic OAuth2 properties on input and output plugins that do not implement OAuth2
  • preserve the active JWKS cache until a refreshed response is parsed and cached successfully
  • continue validating with cached JWKS keys when a scheduled refresh fails
  • honor the token endpoint's full expires_in value, accept short-lived tokens, and use a 300-second default when the field is omitted
  • add internal and end-to-end regression coverage

Root cause

OAuth2 properties were collected by shared input/output configuration code without checking whether the selected plugin consumed them. JWKS refresh cleared the existing cache before validating the replacement response. Token parsing also reduced expires_in by 10%, rejected lifetimes shorter than the configured refresh skew, and treated an omitted expires_in as an error.

User impact

Misconfigured OAuth2 settings now fail at startup instead of being silently ignored. Temporary or malformed JWKS refresh responses no longer discard usable cached keys. Standards-compliant token responses with short or omitted lifetimes are accepted without immediate refresh loops.

Validation

  • cmake --build build -j8 --target fluent-bit-bin
  • cmake --build build -j8 --target flb-it-oauth2 && ./build/bin/flb-it-oauth2 — 12 passed
  • cmake --build build -j8 --target flb-it-oauth2_jwt && ./build/bin/flb-it-oauth2_jwt — 9 passed
  • out_http focused OAuth2 regressions — 4 passed normally and 4 passed with strict Valgrind
  • in_http malformed JWKS refresh regression — passed normally and with strict Valgrind
  • OpenTelemetry OAuth2 coverage — 22 passed normally
  • representative OpenTelemetry OAuth2 coverage — 6 passed with strict Valgrind
  • full PR-range commit-prefix validation passed

Summary by CodeRabbit

  • New Features
    • Added OAuth2 JWT validation support for HTTP and OpenTelemetry inputs.
    • Added OAuth2 client authentication support for HTTP and OpenTelemetry outputs.
  • Bug Fixes
    • Improved handling of token lifetimes, including missing or short expiration values.
    • Preserved cached signing keys when a JWKS refresh fails, allowing continued validation.
    • Rejected OAuth2 settings on plugins that do not support them with clearer errors.
    • Prevented duplicate signing keys from being accepted.
  • Tests
    • Expanded coverage for token refresh, JWKS failures, and unsupported OAuth2 configurations.

edsiper added 11 commits July 15, 2026 18:07
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
Signed-off-by: Eduardo Silva <eduardo@chronosphere.io>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7ab351db-e279-4522-8a3c-3a4c2ac9777f

📥 Commits

Reviewing files that changed from the base of the PR and between 064e90b and a3f5814.

📒 Files selected for processing (17)
  • include/fluent-bit/flb_input.h
  • include/fluent-bit/flb_output.h
  • plugins/in_http/http.c
  • plugins/in_opentelemetry/opentelemetry.c
  • plugins/out_http/http.c
  • plugins/out_opentelemetry/opentelemetry.c
  • src/flb_input.c
  • src/flb_oauth2.c
  • src/flb_oauth2_jwt.c
  • src/flb_output.c
  • tests/integration/scenarios/in_http/config/in_http_oauth2_refresh.yaml
  • tests/integration/scenarios/in_http/tests/test_in_http_001.py
  • tests/integration/scenarios/out_http/config/unsupported_oauth2_input.yaml
  • tests/integration/scenarios/out_http/config/unsupported_oauth2_output.yaml
  • tests/integration/scenarios/out_http/tests/test_out_http_001.py
  • tests/integration/src/server/http_server.py
  • tests/internal/oauth2.c

📝 Walkthrough

Walkthrough

OAuth2 capability flags and plugin checks were added, token expiration handling was adjusted, JWKS refreshes now preserve valid cached keys on failure, and integration/internal tests cover these behaviors.

Changes

OAuth2 validation and refresh behavior

Layer / File(s) Summary
OAuth2 capability declarations and property gates
include/fluent-bit/*, plugins/in_*/..., plugins/out_*/..., src/flb_input.c, src/flb_output.c
Supported plugins advertise OAuth2 capabilities, while unsupported plugins reject OAuth2 properties.
Token expiry parsing and refresh decisions
src/flb_oauth2.c, tests/internal/oauth2.c
Missing expires_in values use a default, short lifetimes adjust refresh skew, and parsing tests were updated.
Transactional JWKS cache refresh
src/flb_oauth2_jwt.c, tests/integration/scenarios/in_http/..., tests/integration/src/server/http_server.py
JWKS duplicate keys are rejected, refreshed caches are staged before replacement, and existing keys remain usable after failed refreshes.
OAuth2 integration coverage
tests/integration/scenarios/out_http/...
Integration tests cover short or missing token lifetimes and startup failures for unsupported OAuth2 plugins.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HTTPInput
  participant JWKSFetcher
  participant JWKSCache
  HTTPInput->>JWKSFetcher: request JWKS during token validation
  JWKSFetcher->>JWKSCache: build temporary cache
  JWKSFetcher->>JWKSCache: replace active cache after success
  JWKSFetcher-->>HTTPInput: return refresh failure
  HTTPInput->>JWKSCache: validate with existing cached keys
Loading

Possibly related PRs

Suggested reviewers: cosmo0920

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main OAuth2 hardening changes across configuration, JWKS refresh, and token lifetime handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch oauth2-end-to-end-audit-noissue

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3f5814add

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

Comment thread src/flb_oauth2.c
Comment on lines +1221 to +1224
refresh_skew = ctx->refresh_skew;
if (ctx->expires_in <= (uint64_t) refresh_skew) {
refresh_skew = ctx->expires_in / 10;
}

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 refresh skew to token_expired callers

This skew adjustment only affects the flb_oauth2_get_access_token() path, but several existing plugins still decide whether to refresh with flb_oauth2_token_expired() and then reuse ctx->o->access_token directly (for example BigQuery, Chronicle, Stackdriver, and Azure outputs). Since this commit now stores the full expires_in instead of the old 10% shortened lifetime, those callers lose their only early-refresh margin and can send a token right up to its exact expiry under normal output traffic; please apply the same skew logic in flb_oauth2_token_expired() or migrate those callers to the skew-aware path.

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.

1 participant