Skip to content

feat(rest): implement OAuth2 token auto-refresh for REST catalog#646

Open
lishuxu wants to merge 5 commits into
apache:mainfrom
lishuxu:feature/oauth_2
Open

feat(rest): implement OAuth2 token auto-refresh for REST catalog#646
lishuxu wants to merge 5 commits into
apache:mainfrom
lishuxu:feature/oauth_2

Conversation

@lishuxu
Copy link
Copy Markdown
Contributor

@lishuxu lishuxu commented May 9, 2026

Replace the MakeOAuth2 stub with a full OAuth2AuthSession that automatically refreshes tokens before expiration using the client_credentials grant.

shuxu.li added 2 commits May 9, 2026 09:46
    Replace the MakeOAuth2 stub with a full OAuth2AuthSession that
    automatically refreshes tokens before expiration using the
    client_credentials grant.

    Key components:
    - OAuth2AuthSession: manages token lifecycle with shared_mutex for
      concurrent read access and background refresh via scheduler
    - TokenRefreshScheduler: process-global singleton with a single worker
      thread that fires delayed refresh callbacks
    - ExpiresAtMillis: JWT exp claim parser for determining token expiry
      when expires_in is not provided in the token response
    - Base64Decode/Base64UrlDecode added to TransformUtil as public utilities
Replace the MakeOAuth2 stub with a full OAuth2AuthSession that
automatically refreshes tokens before expiration using the
client_credentials grant.

Key components:
- OAuth2AuthSession: manages token lifecycle with shared_mutex for concurrent read access and background refresh via scheduler
- TokenRefreshScheduler: process-global singleton with a single worker thread that fires delayed refresh callbacks
- ExpiresAtMillis: JWT exp claim parser for determining token expiry when expires_in is not provided in the token response
- Base64Decode/Base64UrlDecode added to TransformUtil as public utilities
Comment thread src/iceberg/test/meson.build Outdated
Comment thread src/iceberg/util/transform_util.cc Outdated
Comment thread src/iceberg/util/transform_util.cc Outdated
shuxu.li added 3 commits May 11, 2026 18:05
Replace the MakeOAuth2 stub with a full OAuth2AuthSession that automatically refreshes tokens before expiration using the client_credentials grant.
Replace the MakeOAuth2 stub with a full OAuth2AuthSession that automatically refreshes tokens before expiration using the client_credentials grant.
Replace the MakeOAuth2 stub with a full OAuth2AuthSession that automatically refreshes tokens before expiration using the client_credentials grant.
Status Authenticate(std::unordered_map<std::string, std::string>& headers) override {
std::shared_lock lock(mutex_);
for (const auto& [key, value] : headers_) {
headers.insert_or_assign(key, value);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use try_emplace here so a request-specific Authorization header can win, matching DefaultAuthSession and Java’s putIfAbsent behavior.

// avoids circular dependency of using an expired token to refresh itself)
auto empty_session = AuthSession::MakeDefault({});

AuthProperties props;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Carry audience and resource through to refresh requests too. Some OAuth servers require the same optional params on every token request.

{std::string(kAuthorizationHeader), std::string(kBearerPrefix) + token_}};

// Update expiration
if (response.expires_in_secs.has_value()) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reset expires_at_ before deriving the new expiry, and skip scheduling when the refreshed token has neither expires_in nor JWT exp.

.client_id = client_id,
.client_secret = client_secret,
.scope = scope,
.keep_refreshed = true,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pass the parsed token-refresh-enabled value into this config instead of forcing refresh on. Users who disable refresh should not get background token requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants