Skip to content

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

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

feat(rest): implement OAuth2 token auto-refresh for REST catalog#646
lishuxu wants to merge 12 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.

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
Comment thread src/iceberg/catalog/rest/auth/auth_session.cc Outdated
Comment thread src/iceberg/catalog/rest/auth/auth_session.cc
Comment thread src/iceberg/catalog/rest/auth/auth_session.cc
Comment thread src/iceberg/catalog/rest/auth/auth_session.cc Outdated
@lishuxu lishuxu force-pushed the feature/oauth_2 branch from ab7d3a9 to 60e8584 Compare May 22, 2026 13:10
Comment thread src/iceberg/catalog/rest/auth/auth_session.cc Outdated
/// (a single HTTP POST to refresh a token), so one thread is sufficient.
///
/// Thread safety: All public methods are thread-safe.
class ICEBERG_REST_EXPORT TokenRefreshScheduler {
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.

@HuaHuaY is working on the adding a thread pool abstraction and it would be good to reuse that once available. The main issue of current design is that only a single thread is working on token refresh and a slow request would starve all other tasks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Added a TODO referencing this discussion to migrate to the shared thread pool once it lands. Agreed the single-thread design can let a slow request starve other refreshes; will switch over in a follow-up.

props.mutable_configs().insert_or_assign(key, value);
}

auto result = FetchToken(client_, *empty_session, 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.

Java refreshes through token exchange by default and only falls back to client credentials in specific cases. This path always uses client_credentials and ignores token-exchange-enabled, which breaks parity for exchange-based refresh.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. This path always uses client_credentials and ignores token-exchange-enabled, unlike Java which refreshes via token exchange by default. I'll address this in a dedicated follow-up PR (exchange request builder + refresh flow rework), and link it here. Keeping this PR scoped to client_credentials auto-refresh.

config.optional_oauth_params(), client);
}

// If token is provided, use it directly.
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.

Java wraps configured access tokens in fromAccessToken() so expiring tokens can be refreshed. Returning a static session here means JWT or token-expires-in-ms based tokens never refresh.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. This is tightly coupled to the token-exchange work (a configured token has no credential, so Java refreshes it via exchange), so I'll bundle it into the same follow-up PR: add token-expires-in-ms, populate expires_at_millis_, and wrap configured tokens in a refreshable session. Will link the PR here.

Comment thread src/iceberg/util/transform_util.h Outdated
Comment thread src/iceberg/util/transform_util.h Outdated
shuxu.li added 10 commits May 30, 2026 19:29
    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
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.
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.
Replace the MakeOAuth2 stub with a full OAuth2AuthSession that automatically refreshes tokens before expiration using the client_credentials grant.
@lishuxu lishuxu force-pushed the feature/oauth_2 branch from 60e8584 to 7ebc88f Compare May 30, 2026 11:40
shuxu.li added 2 commits May 30, 2026 21:32
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.
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