Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grpc service accounts #412

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Loading