Skip to content

Commit

Permalink
Merge pull request #412 from sodomelle/grpc-service-accounts
Browse files Browse the repository at this point in the history
Grpc service accounts
  • Loading branch information
alltilla authored Dec 13, 2024
2 parents 56b134d + 9734e52 commit 567b37a
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 0 deletions.
45 changes: 45 additions & 0 deletions modules/grpc/common/credentials/grpc-credentials-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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();
}
Expand All @@ -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();
}
Expand Down Expand Up @@ -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);
}
5 changes: 5 additions & 0 deletions modules/grpc/common/credentials/grpc-credentials-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef enum
GCAM_TLS,
GCAM_ALTS,
GCAM_ADC,
GCAM_SERVICE_ACCOUNT,
} GrpcClientAuthMode;

typedef struct GrpcClientCredentialsBuilderW_ GrpcClientCredentialsBuilderW; // Wrapper struct
Expand All @@ -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"

Expand Down
11 changes: 11 additions & 0 deletions modules/grpc/common/credentials/grpc-credentials-builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
};

}
Expand Down
14 changes: 14 additions & 0 deletions modules/grpc/common/grpc-grammar.ym
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */

%%
3 changes: 3 additions & 0 deletions modules/grpc/common/grpc-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 }, \
Expand Down
16 changes: 16 additions & 0 deletions news/feature-412.md
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit 567b37a

Please sign in to comment.