Anubhav Jindal has posted comments on this change. ( http://gerrit.cloudera.org:8080/24448 )
Change subject: IMPALA-14799: Add oauth_servers support and tests ...................................................................... Patch Set 10: (33 comments) http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/runtime/exec-env.h File be/src/runtime/exec-env.h: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/runtime/exec-env.h@110 PS8, Line 110: ~ExecEnv(); > Nit: The original names GetJWTHelperInstance() and GetOAuthHelperInstance() Done. I renamed and relocated the getter as oauth_servers_mgr() alongside the other getters and changed the return type to std::shared_ptr<OAuthServersManager> http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/runtime/exec-env.h@299 PS8, Line 299: > Make this a std::shared_ptr to avoid use-after-free issues. Done. ExecEnv::oauth_servers_mgr_ is now a std::shared_ptr<OAuthServersManager> http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/runtime/exec-env.cc File be/src/runtime/exec-env.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/runtime/exec-env.cc@578 PS8, Line 578: > oauth_servers_mgr_ should be initialized as part of the constructor definit Done. I moved oauth_servers_mgr_ initialization into the ExecEnv constructor initializer list and removed the allocation from ExecEnv::Init() http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/service/impala-server.cc File be/src/service/impala-server.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/service/impala-server.cc@3240 PS8, Line 3240: RETURN_IF_ERROR(ExecEnv::GetInstance()->oauth_servers_mgr()->Init()); : } : : // Initialize the client servers. > This coding structure is sub-optimal since it requires initializing a throw Done. I moved config construction into OAuthServersManager::Init() and now call ExecEnv::GetInstance()->oauth_servers_mgr()->Init() directly from ImpalaServer::Start(). Configs are moved into manager storage. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/jwt-util.cc File be/src/util/jwt-util.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/jwt-util.cc@771 PS8, Line 771: DCHECK_GT(jwks_pull_timeout_secs_, 0); : DCHECK(is_local_file || jwks_update_frequency_secs_ > 0); : std::shared_ptr<JWKSSnapshot> new_jwks = std::make_shared<JWKSSnapshot>(); : if (is_local_file) { : > The flag validators for FLAGS_jwks_pulling_timeout_s take care of ensuring Done. I removed the warning/default fallback path and now rely on validated values; the code path now uses resolved values with DCHECKs. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/jwt-util.cc@785 PS8, Line 785: if (!status.ok()) { : LOG(ERROR) << "Failed to load JWKS: " << status; : return status; : } : D > The flag validators for FLAGS_jwks_update_frequency_s take care of ensuring Done. I removed the warning/default fallback for update frequency and use resolved validated values directly. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/jwt-util.cc@812 PS8, Line 812: new_jwks = std::make_shared<JWKSSnapshot>(); : bool is_changed = false; : Status status = : new_jwks->LoadKeysFromUrl(jwks_uri_, jwks_verify_server_certificate_, : jwks_ca_certificate_, current_jwks_checksum_, &is_changed, : jwks_pull_timeout_secs_); : if (!status.ok()) { > The logic in JWKSMgr::Init should take care of ensuring jwks_update_frequen Done. JWKSMgr::Init() now resolves these values once and UpdateJWKSThread() uses those resolved members with DCHECKs. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/jwt-util.cc@869 PS8, Line 869: jwks_mgr_.reset(new JWKSMgr()); : RETURN_IF_ERROR(jwks_mgr_->Init(jwks_uri, jwks_verify_server_certificate, : jwks_ca_certificate, is_local_file, jwks_pull_timeout_secs, : jwks_update_frequency_secs)); : if (!initialized_) initialized_ = true; : return Status::OK(); : } : > These functions are not needed. Done. I removed CreateJWTHelper() / DestroyJWTHelper() and switched manager storage/ownership accordingly. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config-test.cc File be/src/util/oauth-server-config-test.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config-test.cc@164 PS8, Line 164: FLAGS_jwks_url = "https://example.com/jwks.json"; > Please add another test that combines all three sets of flags (oauth_server Done. Added BuildOAuthServerConfigsCombinesJsonLegacyJwtAndLegacyOAuth. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h File be/src/util/oauth-server-config.h: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@17 PS8, Line 17: : #pragma once : > Use the newer #pragma once directive instead of macro guards. Done. Converted oauth-server-config.h to #pragma once. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@37 PS8, Line 37: bool is_local_jwks = false; : int32_t jwks_pull_tim > Instead of having separate fields for jwks file path and url, please consid Done. Replaced separate jwks_file_path / jwks_url with jwks_uri plus is_local_jwks. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@35 PS8, Line 35: bool verify_server_cert = true; : std::string jwks_uri; : bool is_local_jwks = false; : int32_t jwks_pull_timeout_secs = DEFAULT_JWKS_PULL_TIMEOUT_SECS; : int32_t jwks_update_frequency_secs = DEFAULT_JWKS_UPDATE_FREQUENCY_SECS; : std::string username_claim = "username"; : > Since this is security related, I would prefer for all these fields to be d I did not convert OAuthServerConfig to fully constructor-only immutable fields in this patch because it would require a larger parser/build refactor across legacy migration and tests. I can do that in a follow-up if you want this tightened further. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@48 PS8, Line 48: /// Builds the full list of OAuth server configs from --oauth_servers plus any legacy : /// jwks_* / oauth_* startup flags. : Status BuildOAuthServerConfigs(std::vector<OAuthServerConfig>* configs > Since defining both the JWKS file path and url is legacy behavior, let's ke Done. Legacy file-vs-url preference behavior is now contained in legacy builders; the struct no longer carries both fields. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@53 PS8, Line 53: : : > It's a design smell if a function is exposed only for testing purposes. C+ Done. I removed ParseOAuthServersJson() from the header and updated tests to validate through BuildOAuthServerConfigs(). http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.h@62 PS8, Line 62: > I don't think this function needs to be in the global namespace but rather Done. Deprecated-flag warning helper path is now kept internal (anonymous namespace scope). http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.cc File be/src/util/oauth-server-config.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-server-config.cc@31 PS8, Line 31: DECLARE_string(jwks_file_path); > Remove, no need to DECLARE_ in the same file where the flag is defined. Done. Removed redundant DECLARE_string(oauth_servers) http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager-test.cc File be/src/util/oauth-servers-manager-test.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager-test.cc@120 PS8, Line 120: google::FlagSaver flag_saver; > Please add a test that asserts token validation fails when only the testdat Done. Added VerifyFailsWhenOnlyWrongJwksConfigured. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.h File be/src/util/oauth-servers-manager.h: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.h@17 PS8, Line 17: : #pragma once : > Use the newer #pragma once directive instead of macro guards. Done. Converted oauth-servers-manager.h to #pragma once. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.h@40 PS8, Line 40: > Remove this function parameter since it is `true` in all the main code wher Done. Removed require_jwks parameter from manager init and adjusted tests to use real config-driven init. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.h@41 PS8, Line 41: } : : size_t size() const { : DCHECK(impl_); : return impl_->size(); > Nit: these simple one-line functions can have their function bodies placed Done. Inlined one-line methods (empty(), size(), config()) in the header. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.h@53 PS8, Line 53: /// Ver > Why is this function declared static instead of being a class member functi Done. Converted GetUsername() from static helper to class member method. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc File be/src/util/oauth-servers-manager.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@35 PS8, Line 35: > No need to use JWTHelper*, use JWTHelper instead. Done. Manager now stores JWTHelper objects, not pointers. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@32 PS8, Line 32: RETURN_IF_ERROR(BuildOAuthServerConfigs(&configs)); : return InitWithConfigs(std::move(configs)); : } : : Status OAuthServersManager::InitWithConfigs(vector<OAuthServerConfig>&& configs) { : impl_ = std::make_shared<OAuthServersImpl>(); : impl_->reserve(configs.size()); : > This struct is not necessary. Instead, in the private section of the OAuth Done (adapted with comment 18). I removed the extra struct and now use a private alias in the header: std::vector<std::pair<OAuthServerConfig, JWTHelper>>. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@41 PS8, Line 41: for (OAuthServerConfig& config : configs) { : if (!config.HasJwksSource()) con > Delete this constructor implementation, and, in the Init() function, do thi Done (using shared ownership from related comments). I removed the constructor-based init path and initialize impl_ inside manager init flow. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@50 PS8, Line 50: impl_->emplace_back(std::move(config), std::move(jwt_helper)); > No need to reset impl_, it will be automatically reset when it goes out of Done. Removed manual reset/destructor cleanup path. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@55 PS8, Line 55: } > Add DCHECK(impl_) to ensure that Init() has been called. Done. Added DCHECK(impl_) checks in manager accessors/paths. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@59 PS8, Line 59: Status OAuthServersManager::Verify(const JWTHelper::JWTDecodedToken* decoded_token, > Add DCHECK(impl_) to ensure that Init() has been called. Done. Added corresponding DCHECK(impl_). http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@63 PS8, Line 63: DCHECK(matched_server_idx_out != nullptr); > Add DCHECK(impl_) to ensure that Init() has been called. Done. Added corresponding DCHECK(impl_). http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@88 PS8, Line 88: ername_cla > This function duplicates the validation performed in HasJwksSource(). Done. Removed duplicate validation path and rely on HasJwksSource() flow. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/oauth-servers-manager.cc@93 PS8, Line 93: > Is this sleep necessary? If so, add a comment explaining why or remove the Done. Removed the test-only sleep from manager initialization. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/webserver.cc File be/src/util/webserver.cc: http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/webserver.cc@1167 PS8, Line 1167: > Needs to be changed to std::shared_ptr<OAuthServersManager> Done. Updated Webserver auth paths to use std::shared_ptr<OAuthServersManager> from ExecEnv. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/webserver.cc@1177 PS8, Line 1177: } : } > Useless condition, matched_server_idx will already be 0 here. Done. Removed redundant matched_server_idx reset/condition in JWT web auth path. http://gerrit.cloudera.org:8080/#/c/24448/8/be/src/util/webserver.cc@1219 PS8, Line 1219: : string username; > Useless condition, matched_server_idx will already be 0 here. Done. Removed redundant matched_server_idx reset/condition in OAuth web auth path. -- To view, visit http://gerrit.cloudera.org:8080/24448 To unsubscribe, visit http://gerrit.cloudera.org:8080/settings Gerrit-Project: Impala-ASF Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: Ib29ff36600406ba59c10f29d79cc632020f4a3f7 Gerrit-Change-Number: 24448 Gerrit-PatchSet: 10 Gerrit-Owner: Anubhav Jindal <[email protected]> Gerrit-Reviewer: Anubhav Jindal <[email protected]> Gerrit-Reviewer: Impala Public Jenkins <[email protected]> Gerrit-Reviewer: Jason Fehr <[email protected]> Gerrit-Comment-Date: Thu, 18 Jun 2026 09:36:26 +0000 Gerrit-HasComments: Yes
