From ae735369cb3886290b71e2f971e55479011734d4 Mon Sep 17 00:00:00 2001 From: lupuletic Date: Wed, 29 Oct 2025 15:52:45 +0000 Subject: [PATCH] Use ServiceAccountJWTAccessCredentials for thread-safe credential loading Replace environment variable manipulation with direct use of gRPC's ServiceAccountJWTAccessCredentials API. This eliminates race conditions from concurrent credential initialization and avoids global state pollution. Changes: - Add ReadFileContents() helper with path validation - Read service account JSON directly and create JWT credentials - Compose SSL and call credentials using CompositeChannelCredentials - Preserve ADC fallback when flag not specified - Remove all setenv/unsetenv/getenv calls This ensures thread-safe credential initialization and follows gRPC best practices for service account authentication. --- src/throttler_api.cc | 52 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/throttler_api.cc b/src/throttler_api.cc index 80f70ce9..b69639c7 100644 --- a/src/throttler_api.cc +++ b/src/throttler_api.cc @@ -26,7 +26,9 @@ #include // NOLINT #include #include +#include #include +#include #include #include #include @@ -58,6 +60,9 @@ DEFINE_string(cprof_profile_labels, "", "names must be in dns-label-like-format"); DEFINE_bool(cprof_use_insecure_creds_for_testing, false, "use insecure channel creds, for testing only"); +DEFINE_string(cprof_service_account_json_file, "", + "path to service account JSON file for authentication; " + "if not set, uses Application Default Credentials"); namespace cloud { namespace profiler { @@ -111,6 +116,20 @@ grpc_ssl_roots_override_result OverrideSSLRoots(char** pem_root_certs) { return GRPC_SSL_ROOTS_OVERRIDE_OK; } +bool ReadFileContents(const std::string& path, std::string* out) { + if (path.empty()) { + return false; + } + std::ifstream file(path, std::ios::in | std::ios::binary); + if (!file) { + return false; + } + std::ostringstream buffer; + buffer << file.rdbuf(); + *out = buffer.str(); + return true; +} + // Creates the profiler gRPC API stub. Returns nullptr on error. std::unique_ptr NewProfilerServiceStub(const std::string& addr, const std::string& language) { @@ -119,9 +138,38 @@ NewProfilerServiceStub(const std::string& addr, const std::string& language) { creds = grpc::InsecureChannelCredentials(); } else { grpc_set_ssl_roots_override_callback(&OverrideSSLRoots); - creds = grpc::GoogleDefaultCredentials(); + + if (!FLAGS_cprof_service_account_json_file.empty()) { + + std::string service_account_contents; + if (!ReadFileContents(FLAGS_cprof_service_account_json_file, + &service_account_contents)) { + LOG(ERROR) << "Failed to read service account JSON file from " + << FLAGS_cprof_service_account_json_file; + return nullptr; + } + + auto call_creds = grpc::ServiceAccountJWTAccessCredentials( + service_account_contents); + if (call_creds == nullptr) { + LOG(ERROR) << "Failed to create service account call credentials"; + return nullptr; + } + + grpc::SslCredentialsOptions ssl_options; + auto ssl_creds = grpc::SslCredentials(ssl_options); + if (ssl_creds == nullptr) { + LOG(ERROR) << "Failed to create SSL credentials"; + return nullptr; + } + + creds = grpc::CompositeChannelCredentials(ssl_creds, call_creds); + } else { + creds = grpc::GoogleDefaultCredentials(); + } + if (creds == nullptr) { - LOG(ERROR) << "Failed to get Google default credentials"; + LOG(ERROR) << "Failed to initialize channel credentials"; return nullptr; } }