From f52b09cb43e21565c747e58af7d28da39a80e596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Kosztyu?= Date: Sat, 7 Dec 2024 11:10:53 +0100 Subject: [PATCH 1/3] grpc: implement service account functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tamás Kosztyu --- .../credentials/grpc-credentials-builder.cpp | 45 +++++++++++++++++++ .../credentials/grpc-credentials-builder.h | 5 +++ .../credentials/grpc-credentials-builder.hpp | 11 +++++ 3 files changed, 61 insertions(+) diff --git a/modules/grpc/common/credentials/grpc-credentials-builder.cpp b/modules/grpc/common/credentials/grpc-credentials-builder.cpp index e7786e19d0..b1b83fa9e7 100644 --- a/modules/grpc/common/credentials/grpc-credentials-builder.cpp +++ b/modules/grpc/common/credentials/grpc-credentials-builder.cpp @@ -219,6 +219,18 @@ ClientCredentialsBuilder::add_alts_target_service_account(const char *target_ser alts_credentials_options.target_service_accounts.push_back(target_service_account); } +bool +ClientCredentialsBuilder::set_service_account_key_path(const char *key_path) +{ + return _get_file_content(key_path, service_account.key); +} + +void +ClientCredentialsBuilder::set_service_account_validity_duration(guint64 validity_duration) +{ + service_account.validity_duration = validity_duration; +} + bool ClientCredentialsBuilder::validate() const { @@ -232,6 +244,14 @@ ClientCredentialsBuilder::validate() const break; case GCAM_ADC: break; + case GCAM_SERVICE_ACCOUNT: + if (service_account.key.empty()) + { + msg_error("gRPC: Service account configuration requires the path to the " + "json file containing the service account key"); + return false; + } + break; default: g_assert_not_reached(); } @@ -252,6 +272,18 @@ ClientCredentialsBuilder::build() const return ::grpc::experimental::AltsCredentials(alts_credentials_options); case GCAM_ADC: return ::grpc::GoogleDefaultCredentials(); + case GCAM_SERVICE_ACCOUNT: + { + auto channel_creds = ::grpc::SslCredentials(::grpc::SslCredentialsOptions()); + auto call_creds = ::grpc::ServiceAccountJWTAccessCredentials(service_account.key, + service_account.validity_duration); + if (!call_creds) + { + msg_error("gRPC: The specified file doesn't contain a service account key"); + return nullptr; + } + return ::grpc::CompositeChannelCredentials(channel_creds, call_creds); + } default: g_assert_not_reached(); } @@ -288,3 +320,16 @@ grpc_client_credentials_builder_add_alts_target_service_account(GrpcClientCreden { return s->self->add_alts_target_service_account(target_service_acount); } + +gboolean +grpc_client_credentials_builder_service_account_set_key(GrpcClientCredentialsBuilderW *s, const gchar *key_path) +{ + return s->self->set_service_account_key_path(key_path); +} + +void +grpc_client_credentials_builder_service_account_set_validity_duration(GrpcClientCredentialsBuilderW *s, + guint64 validity_duration) +{ + s->self->set_service_account_validity_duration(validity_duration); +} diff --git a/modules/grpc/common/credentials/grpc-credentials-builder.h b/modules/grpc/common/credentials/grpc-credentials-builder.h index e4ae4f3d16..85aaf6c97d 100644 --- a/modules/grpc/common/credentials/grpc-credentials-builder.h +++ b/modules/grpc/common/credentials/grpc-credentials-builder.h @@ -61,6 +61,7 @@ typedef enum GCAM_TLS, GCAM_ALTS, GCAM_ADC, + GCAM_SERVICE_ACCOUNT, } GrpcClientAuthMode; typedef struct GrpcClientCredentialsBuilderW_ GrpcClientCredentialsBuilderW; // Wrapper struct @@ -71,6 +72,10 @@ gboolean grpc_client_credentials_builder_set_tls_key_path(GrpcClientCredentialsB gboolean grpc_client_credentials_builder_set_tls_cert_path(GrpcClientCredentialsBuilderW *s, const gchar *cert_path); void grpc_client_credentials_builder_add_alts_target_service_account(GrpcClientCredentialsBuilderW *s, const gchar *target_service_account); +gboolean grpc_client_credentials_builder_service_account_set_key(GrpcClientCredentialsBuilderW *s, + const gchar *key_path); +void grpc_client_credentials_builder_service_account_set_validity_duration(GrpcClientCredentialsBuilderW *s, + guint64 validity_duration); #include "compat/cpp-end.h" diff --git a/modules/grpc/common/credentials/grpc-credentials-builder.hpp b/modules/grpc/common/credentials/grpc-credentials-builder.hpp index d1fbc9e459..8223c8cff4 100644 --- a/modules/grpc/common/credentials/grpc-credentials-builder.hpp +++ b/modules/grpc/common/credentials/grpc-credentials-builder.hpp @@ -73,6 +73,10 @@ class ClientCredentialsBuilder /* ALTS */ void add_alts_target_service_account(const char *target_service_account); + /*SERVICE ACCOUNTS*/ + bool set_service_account_key_path(const char *key_path); + void set_service_account_validity_duration(guint64 validity_duration); + private: ClientAuthMode mode = GCAM_INSECURE; @@ -81,6 +85,13 @@ class ClientCredentialsBuilder /* ALTS */ ::grpc::experimental::AltsCredentialsOptions alts_credentials_options; + + /* SERVICE ACCOUNT */ + struct + { + std::string key; + guint64 validity_duration = 3600L; + } service_account; }; } From bf586777b392832f76f295b38e26c3f384e1e36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Kosztyu?= Date: Sat, 7 Dec 2024 11:12:24 +0100 Subject: [PATCH 2/3] grpc: add service account configuring to the grammar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tamás Kosztyu --- modules/grpc/common/grpc-grammar.ym | 14 ++++++++++++++ modules/grpc/common/grpc-parser.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/modules/grpc/common/grpc-grammar.ym b/modules/grpc/common/grpc-grammar.ym index 53b8a81d6b..da91f572ba 100644 --- a/modules/grpc/common/grpc-grammar.ym +++ b/modules/grpc/common/grpc-grammar.ym @@ -52,6 +52,9 @@ GrpcClientCredentialsBuilderW *last_grpc_client_credentials_builder; %token KW_TARGET_SERVICE_ACCOUNTS %token KW_URL %token KW_ADC +%token KW_SERVICE_ACCOUNT +%token KW_TOKEN_VALIDITY_DURATION +%token KW_KEY %token KW_COMPRESSION %token KW_BATCH_BYTES %token KW_CONCURRENT_REQUESTS @@ -211,6 +214,7 @@ grpc_client_credentials_option | KW_TLS { grpc_client_credentials_builder_set_mode(last_grpc_client_credentials_builder, GCAM_TLS); } '(' grpc_client_credentials_builder_tls_options ')' | KW_ALTS { grpc_client_credentials_builder_set_mode(last_grpc_client_credentials_builder, GCAM_ALTS); } '(' grpc_client_credentials_builder_alts_options ')' | KW_ADC { grpc_client_credentials_builder_set_mode(last_grpc_client_credentials_builder, GCAM_ADC); } '(' ')' + | KW_SERVICE_ACCOUNT { grpc_client_credentials_builder_set_mode(last_grpc_client_credentials_builder, GCAM_SERVICE_ACCOUNT); } '(' grpc_client_credentials_builder_service_account_options ')' ; grpc_client_credentials_builder_tls_options @@ -255,6 +259,16 @@ grpc_client_credentials_builder_alts_target_service_accounts | ; +grpc_client_credentials_builder_service_account_options + : grpc_client_credentials_builder_service_account_option grpc_client_credentials_builder_service_account_options + | + ; + +grpc_client_credentials_builder_service_account_option + : KW_KEY '(' path_secret ')' { grpc_client_credentials_builder_service_account_set_key(last_grpc_client_credentials_builder, $3); free($3); } + | KW_TOKEN_VALIDITY_DURATION '(' nonnegative_integer64 ')' { grpc_client_credentials_builder_service_account_set_validity_duration(last_grpc_client_credentials_builder, $3); } + ; + /* END_RULES */ %% diff --git a/modules/grpc/common/grpc-parser.h b/modules/grpc/common/grpc-parser.h index 12b00dde3f..4b9123fdae 100644 --- a/modules/grpc/common/grpc-parser.h +++ b/modules/grpc/common/grpc-parser.h @@ -35,6 +35,9 @@ { "url", KW_URL }, \ { "target_service_accounts", KW_TARGET_SERVICE_ACCOUNTS }, \ { "adc", KW_ADC }, \ + { "service_account", KW_SERVICE_ACCOUNT }, \ + { "key", KW_KEY }, \ + { "token_validity_duration", KW_TOKEN_VALIDITY_DURATION }, \ { "compression", KW_COMPRESSION }, \ { "batch_bytes", KW_BATCH_BYTES }, \ { "channel_args", KW_CHANNEL_ARGS }, \ From 9734e52b448bcd3ffc60143a5fa6bac881f4781c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Kosztyu?= Date: Sat, 7 Dec 2024 11:29:11 +0100 Subject: [PATCH 3/3] NEWS: Add entry for #412 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tamás Kosztyu --- news/feature-412.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 news/feature-412.md diff --git a/news/feature-412.md b/news/feature-412.md new file mode 100644 index 0000000000..573cb1489b --- /dev/null +++ b/news/feature-412.md @@ -0,0 +1,16 @@ +bigquery(), google-pubsub-grpc(): Added service-account() authentication option. + +Example usage: +``` +destination { + google-pubsub-grpc( + project("test") + topic("test") + auth(service-account(key ("path_to_service_account_key.json"))) + ); +}; +``` + +Note: In contrary to the `http()` destination's similar option, +we do not need to manually set the audience here as it is +automatically recognized by the underlying gRPC API.