Skip to content

Add OAuth2 HTTP request timeouts - #606

Draft
RobertIndie wants to merge 3 commits into
mainfrom
oauth2-http-timeouts
Draft

Add OAuth2 HTTP request timeouts#606
RobertIndie wants to merge 3 commits into
mainfrom
oauth2-http-timeouts

Conversation

@RobertIndie

@RobertIndie RobertIndie commented Aug 10, 2026

Copy link
Copy Markdown
Member

Motivation

OAuth2 issuer discovery and token requests previously used libcurl without application-level connection or total request deadlines. An unavailable or stalled issuer could therefore delay client startup and recovery for several minutes.

Modifications

Add a distinct CurlWrapper connection timeout and configurable OAuth2 connect_timeout_seconds and request_timeout_seconds parameters, defaulting to 10 and 30 seconds. Validate both parameters as positive integers, apply them to discovery, token acquisition, and refresh for both OAuth2 flows, document the public configuration, and add black-box regression coverage.

Verifying this change

Built the modified production and AuthPluginTest objects with -Werror. Ran three new timeout and validation tests plus four existing OAuth TLS tests; all 7 passed. The complete pulsar-tests target remains blocked by the pre-existing DagWatchSession incompatibility with the installed Boost.Asio API.

Usage

Configure the OAuth2 HTTP timeouts through the authentication parameters:

pulsar::ParamMap params;
params["issuer_url"] = "https://auth.example.com";
params["private_key"] = "file:///path/to/oauth-credentials.json";
params["audience"] = "https://pulsar.example.com";
params["connect_timeout_seconds"] = "5";
params["request_timeout_seconds"] = "15";

pulsar::ClientConfiguration config;
config.setAuth(pulsar::AuthOauth2::create(params));

pulsar::Client client("pulsar+ssl://broker.example.com:6651", config);

The parameters can also be supplied as JSON:

const std::string authParams = R"({
  "issuer_url": "https://auth.example.com",
  "private_key": "file:///path/to/oauth-credentials.json",
  "audience": "https://pulsar.example.com",
  "connect_timeout_seconds": "5",
  "request_timeout_seconds": "15"
})";

pulsar::ClientConfiguration config;
config.setAuth(pulsar::AuthOauth2::create(authParams));

pulsar::Client client("pulsar+ssl://broker.example.com:6651", config);
  • connect_timeout_seconds controls the OAuth HTTP connection timeout and defaults to 10 seconds.
  • request_timeout_seconds controls the total OAuth HTTP request timeout and defaults to 30 seconds.
  • Both values must be positive integers.
  • The timeouts apply to issuer discovery, initial token acquisition, and token refresh.

Python client users can pass the same JSON parameters:

import json
import pulsar

auth = pulsar.AuthenticationOauth2(json.dumps({
    "issuer_url": "https://auth.example.com",
    "private_key": "file:///path/to/oauth-credentials.json",
    "audience": "https://pulsar.example.com",
    "connect_timeout_seconds": "5",
    "request_timeout_seconds": "15",
}))

client = pulsar.Client(
    "pulsar+ssl://broker.example.com:6651",
    authentication=auth,
)

Documentation

  • doc-required
    (Your PR needs to update docs and you will update later)

  • doc-not-needed
    (Please explain why)

  • doc
    (Your PR contains doc changes)

  • doc-complete
    (Docs have been already added)

@RobertIndie RobertIndie self-assigned this Aug 10, 2026
@RobertIndie RobertIndie added the enhancement New feature or request label Aug 10, 2026
@RobertIndie RobertIndie added this to the 4.3.0 milestone Aug 10, 2026
@RobertIndie
RobertIndie requested a lite review from Copilot August 10, 2026 08:36
Motivation:
OAuth2 issuer discovery and token requests previously used libcurl without application-level connection or total request deadlines. An unavailable or stalled issuer could therefore delay client startup and recovery for several minutes.

Modification:
Add a distinct CurlWrapper connection timeout and configurable OAuth2 connect_timeout_seconds and request_timeout_seconds parameters, defaulting to 10 and 30 seconds. Validate both parameters as positive integers, apply them to discovery, token acquisition, and refresh for both OAuth2 flows, document the public configuration, and add black-box regression coverage.

Testing:
Built the modified production and AuthPluginTest objects with -Werror. Ran three new timeout and validation tests plus four existing OAuth TLS tests; all 7 passed. The complete pulsar-tests target remains blocked by the pre-existing DagWatchSession incompatibility with the installed Boost.Asio API.

Usage:
Set connect_timeout_seconds and request_timeout_seconds as positive integer strings in the AuthOauth2 parameter map or JSON passed to AuthOauth2::create. If omitted, the client uses 10-second connection and 30-second total-request timeouts.
@RobertIndie
RobertIndie force-pushed the oauth2-http-timeouts branch from 039e22c to be0ac6a Compare August 10, 2026 08:37

Copilot AI 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.

Pull request overview

Adds configurable OAuth2 HTTP connection and total-request timeouts to prevent issuer discovery / token requests from stalling client startup and token refresh.

Changes:

  • Introduces connect_timeout_seconds and request_timeout_seconds OAuth2 parameters (defaults 10s/30s) with positive-integer validation.
  • Extends CurlWrapper::Options with a connection timeout and applies it via CURLOPT_CONNECTTIMEOUT.
  • Adds black-box tests covering issuer discovery timeout, token request timeout, and parameter validation; updates public header docs.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/AuthPluginTest.cc Adds mock-server delay support and new OAuth2 timeout/validation regression tests.
oauth2-http-timeout-analysis.md Adds an in-repo analysis/design write-up for the OAuth2 timeout change.
lib/CurlWrapper.h Adds connectTimeoutInSeconds and applies CURLOPT_CONNECTTIMEOUT.
lib/auth/AuthOauth2.h Introduces Oauth2HttpTimeouts and stores it in OAuth2 flows.
lib/auth/AuthOauth2.cc Parses/validates timeout params and applies them to issuer discovery + token requests (incl. timeout logging).
include/pulsar/Authentication.h Documents new OAuth2 timeout parameters in the public API header.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/AuthPluginTest.cc
Comment on lines +718 to +721
wellKnownServer.stop();
tokenServer.stop();
wellKnownThread.join();
tokenThread.join();
Make the OAuth2 mock server poll accept in non-blocking mode so stop can terminate a server that never receives a connection. Replace the unconditional response delay with an interruptible condition-variable wait to keep test cleanup bounded across platforms.

Verified the test object with Boost.Asio and standalone Asio, ran the 7 focused OAuth tests, and repeated both timeout tests 10 times.
Read builtin-baseline from vcpkg.json and check out that revision during Alpine packaging instead of building against the moving vcpkg master branch. This keeps the packaging toolchain reproducible and avoids requiring CMake 4.3 features on Alpine 3.19.
@RobertIndie
RobertIndie force-pushed the oauth2-http-timeouts branch from ddea2cc to 547257f Compare August 11, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants