[core/security] Add Custom Token Lifetime - Service Acc Impersonation (#33351)

Adds access token lifetime configuration for workload identity
federation with service account impersonation for both explicit and
implicit flows.

Changes: 
1. Adds a new member "service_account_impersonation" to the
ExternalAccountCredentials class. "token_lifetime_seconds" is a member
of "service_account_impersonation".
2. Adds validation checks, like token_lifetime_seconds should be between
the minimum and maximum accepted value, during the creation of an
ExternalAccountCredentials object.
3. Appends "lifetime" to the body of the service account impersonation
request.

Tests:
1. Modifies a test to check if the default value is passed when
"service_account_impersonation" is empty.
2. Adds tests to check if the token_lifetime_seconds value is propagated
to the request body.
3. Adds tests to verify that an error is thrown when
token_lifetime_seconds is invalid.
pull/33691/head
Mario Jones Vimal 1 year ago committed by GitHub
parent af257b8a39
commit a934848de5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      src/core/lib/security/credentials/external/external_account_credentials.cc
  2. 6
      src/core/lib/security/credentials/external/external_account_credentials.h
  3. 337
      test/core/security/credentials_test.cc

@ -29,6 +29,7 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
@ -63,6 +64,9 @@
"urn:ietf:params:oauth:token-type:access_token"
#define GOOGLE_CLOUD_PLATFORM_DEFAULT_SCOPE \
"https://www.googleapis.com/auth/cloud-platform"
#define IMPERSONATED_CRED_DEFAULT_LIFETIME_IN_SECONDS 3600 // 1 hour
#define IMPERSONATED_CRED_MIN_LIFETIME_IN_SECONDS 600 // 10 mins
#define IMPERSONATED_CRED_MAX_LIFETIME_IN_SECONDS 43200 // 12 hours
namespace grpc_core {
@ -197,6 +201,36 @@ RefCountedPtr<ExternalAccountCredentials> ExternalAccountCredentials::Create(
return nullptr;
}
}
it = json.object().find("service_account_impersonation");
options.service_account_impersonation.token_lifetime_seconds =
IMPERSONATED_CRED_DEFAULT_LIFETIME_IN_SECONDS;
if (it != json.object().end() && it->second.type() == Json::Type::kObject) {
auto service_acc_imp_json = it->second;
auto service_acc_imp_obj_it =
service_acc_imp_json.object().find("token_lifetime_seconds");
if (service_acc_imp_obj_it != service_acc_imp_json.object().end()) {
if (!absl::SimpleAtoi(
service_acc_imp_obj_it->second.string(),
&options.service_account_impersonation.token_lifetime_seconds)) {
*error = GRPC_ERROR_CREATE("token_lifetime_seconds must be a number");
return nullptr;
}
if (options.service_account_impersonation.token_lifetime_seconds >
IMPERSONATED_CRED_MAX_LIFETIME_IN_SECONDS) {
*error = GRPC_ERROR_CREATE(
absl::StrFormat("token_lifetime_seconds must be less than %ds",
IMPERSONATED_CRED_MAX_LIFETIME_IN_SECONDS));
return nullptr;
}
if (options.service_account_impersonation.token_lifetime_seconds <
IMPERSONATED_CRED_MIN_LIFETIME_IN_SECONDS) {
*error = GRPC_ERROR_CREATE(
absl::StrFormat("token_lifetime_seconds must be more than %ds",
IMPERSONATED_CRED_MIN_LIFETIME_IN_SECONDS));
return nullptr;
}
}
}
RefCountedPtr<ExternalAccountCredentials> creds;
if (options.credential_source.object().find("environment_id") !=
options.credential_source.object().end()) {
@ -430,8 +464,13 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() {
headers[1].key = gpr_strdup("Authorization");
headers[1].value = gpr_strdup(str.c_str());
request.hdrs = headers;
std::vector<std::string> body_members;
std::string scope = absl::StrJoin(scopes_, " ");
std::string body = absl::StrFormat("scope=%s", scope);
body_members.push_back(absl::StrFormat("scope=%s", UrlEncode(scope).c_str()));
body_members.push_back(absl::StrFormat(
"lifetime=%ds",
options_.service_account_impersonation.token_lifetime_seconds));
std::string body = absl::StrJoin(body_members, "&");
request.body = const_cast<char*>(body.c_str());
request.body_length = body.size();
grpc_http_response_destroy(&ctx_->response);

@ -19,6 +19,8 @@
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <functional>
#include <string>
#include <vector>
@ -45,12 +47,16 @@ namespace grpc_core {
class ExternalAccountCredentials
: public grpc_oauth2_token_fetcher_credentials {
public:
struct ServiceAccountImpersonation {
int32_t token_lifetime_seconds;
};
// External account credentials json interface.
struct Options {
std::string type;
std::string audience;
std::string subject_token_type;
std::string service_account_impersonation_url;
ServiceAccountImpersonation service_account_impersonation;
std::string token_url;
std::string token_info_url;
Json credential_source;

@ -2164,7 +2164,7 @@ void validate_external_account_creds_service_account_impersonation_request(
// Check that the body is constructed properly.
GPR_ASSERT(body != nullptr);
GPR_ASSERT(body_size != 0);
GPR_ASSERT(strcmp(body, "scope=scope_1 scope_2") == 0);
GPR_ASSERT(strcmp(body, "scope=scope_1%20scope_2&lifetime=3600s") == 0);
// Check the rest of the request.
GPR_ASSERT(strcmp(host, "foo.com:5555") == 0);
GPR_ASSERT(strcmp(path, "/service_account_impersonation") == 0);
@ -2177,6 +2177,45 @@ void validate_external_account_creds_service_account_impersonation_request(
"Bearer token_exchange_access_token") == 0);
}
void validate_external_account_creds_serv_acc_imp_custom_lifetime_request(
const grpc_http_request* request, const char* host, const char* path,
const char* body, size_t body_size, bool /*expect_actor_token*/) {
// Check that the body is constructed properly.
GPR_ASSERT(body != nullptr);
GPR_ASSERT(body_size != 0);
GPR_ASSERT(strcmp(body, "scope=scope_1%20scope_2&lifetime=1800s") == 0);
// Check the rest of the request.
GPR_ASSERT(strcmp(host, "foo.com:5555") == 0);
GPR_ASSERT(strcmp(path, "/service_account_impersonation") == 0);
GPR_ASSERT(request->hdr_count == 2);
GPR_ASSERT(strcmp(request->hdrs[0].key, "Content-Type") == 0);
GPR_ASSERT(
strcmp(request->hdrs[0].value, "application/x-www-form-urlencoded") == 0);
GPR_ASSERT(strcmp(request->hdrs[1].key, "Authorization") == 0);
GPR_ASSERT(strcmp(request->hdrs[1].value,
"Bearer token_exchange_access_token") == 0);
}
int external_acc_creds_serv_acc_imp_custom_lifetime_httpcli_post_success(
const grpc_http_request* request, const char* host, const char* path,
const char* body, size_t body_size, Timestamp /*deadline*/,
grpc_closure* on_done, grpc_http_response* response) {
if (strcmp(path, "/token") == 0) {
validate_external_account_creds_token_exchage_request(
request, host, path, body, body_size, true);
*response = http_response(
200, valid_external_account_creds_token_exchange_response);
} else if (strcmp(path, "/service_account_impersonation") == 0) {
validate_external_account_creds_serv_acc_imp_custom_lifetime_request(
request, host, path, body, body_size, true);
*response = http_response(
200,
valid_external_account_creds_service_account_impersonation_response);
}
ExecCtx::Run(DEBUG_LOCATION, on_done, absl::OkStatus());
return 1;
}
int external_account_creds_httpcli_post_success(
const grpc_http_request* request, const char* host, const char* path,
const char* body, size_t body_size, Timestamp /*deadline*/,
@ -2351,11 +2390,15 @@ class TestExternalAccountCredentials final : public ExternalAccountCredentials {
TEST(CredentialsTest, TestExternalAccountCredsSuccess) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
@ -2393,11 +2436,15 @@ TEST(CredentialsTest, TestExternalAccountCredsSuccessWithUrlEncode) {
{"authorization", "Bearer token_exchange_access_token"}};
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience_!@#$", // audience;
"subject_token_type_!@#$", // subject_token_type;
"", // service_account_impersonation_url;
"external_account", // type;
"audience_!@#$", // audience;
"subject_token_type_!@#$", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token_url_encode", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
@ -2422,18 +2469,22 @@ TEST(CredentialsTest,
TestExternalAccountCredsSuccessWithServiceAccountImpersonation) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"https://foo.com:5555/service_account_impersonation", // service_account_impersonation_url;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
TestExternalAccountCredentials creds(options, {"scope_1", "scope_2"});
// Check security level.
@ -2451,21 +2502,113 @@ TEST(CredentialsTest,
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(
CredentialsTest,
TestExternalAccountCredsSuccessWithServiceAccountImpersonationAndCustomTokenLifetime) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 1800;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"https://foo.com:5555/service_account_impersonation", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
TestExternalAccountCredentials creds(options, {"scope_1", "scope_2"});
// Check security level.
GPR_ASSERT(creds.min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
// First request: http put should be called.
auto state = RequestMetadataState::NewInstance(
absl::OkStatus(),
"authorization: Bearer service_account_impersonation_access_token");
HttpRequest::SetOverride(
httpcli_get_should_not_be_called,
external_acc_creds_serv_acc_imp_custom_lifetime_httpcli_post_success,
httpcli_put_should_not_be_called);
state->RunRequestMetadataTest(&creds, kTestUrlScheme, kTestAuthority,
kTestPath);
ExecCtx::Get()->Flush();
HttpRequest::SetOverride(nullptr, nullptr, nullptr);
}
TEST(
CredentialsTest,
TestExternalAccountCredsFailureWithServiceAccountImpersonationAndInvalidCustomTokenLifetime) {
const char* options_string1 =
"{\"type\":\"external_account\",\"audience\":\"audience\","
"\"subject_token_type\":\"subject_token_type\","
"\"service_account_impersonation_url\":\"service_account_impersonation_"
"url\",\"service_account_impersonation\":"
"{\"token_lifetime_seconds\":599},"
"\"token_url\":\"https://foo.com:5555/token\","
"\"token_info_url\":\"https://foo.com:5555/token_info\","
"\"credential_source\":{\"url\":\"https://foo.com:5555/"
"generate_subject_token_format_json\","
"\"headers\":{\"Metadata-Flavor\":\"Google\"},"
"\"format\":{\"type\":\"json\",\"subject_token_field_name\":\"access_"
"token\"}},\"quota_project_id\":\"quota_project_id\","
"\"client_id\":\"client_id\",\"client_secret\":\"client_secret\"}";
grpc_error_handle error1, error2;
auto json1 = JsonParse(options_string1);
GPR_ASSERT(json1.ok());
ExternalAccountCredentials::Create(*json1, {"scope1", "scope2"}, &error1);
std::string actual_error1,
expected_error1 = "token_lifetime_seconds must be more than 600s";
grpc_error_get_str(error1, StatusStrProperty::kDescription, &actual_error1);
GPR_ASSERT(strcmp(actual_error1.c_str(), expected_error1.c_str()) == 0);
const char* options_string2 =
"{\"type\":\"external_account\",\"audience\":\"audience\","
"\"subject_token_type\":\"subject_token_type\","
"\"service_account_impersonation_url\":\"service_account_impersonation_"
"url\",\"service_account_impersonation\":"
"{\"token_lifetime_seconds\":43201},"
"\"token_url\":\"https://foo.com:5555/token\","
"\"token_info_url\":\"https://foo.com:5555/token_info\","
"\"credential_source\":{\"url\":\"https://foo.com:5555/"
"generate_subject_token_format_json\","
"\"headers\":{\"Metadata-Flavor\":\"Google\"},"
"\"format\":{\"type\":\"json\",\"subject_token_field_name\":\"access_"
"token\"}},\"quota_project_id\":\"quota_project_id\","
"\"client_id\":\"client_id\",\"client_secret\":\"client_secret\"}";
auto json2 = JsonParse(options_string2);
GPR_ASSERT(json2.ok());
ExternalAccountCredentials::Create(*json2, {"scope1", "scope2"}, &error2);
std::string actual_error2,
expected_error2 = "token_lifetime_seconds must be less than 43200s";
grpc_error_get_str(error2, StatusStrProperty::kDescription, &actual_error2);
GPR_ASSERT(strcmp(actual_error2.c_str(), expected_error2.c_str()) == 0);
}
TEST(CredentialsTest, TestExternalAccountCredsFailureInvalidTokenUrl) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"https://foo.com:5555/service_account_impersonation", // service_account_impersonation_url;
"invalid_token_url", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
service_account_impersonation, // service_account_impersonation;
"invalid_token_url", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
@ -2486,18 +2629,22 @@ TEST(CredentialsTest,
TestExternalAccountCredsFailureInvalidServiceAccountImpersonationUrl) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"invalid_service_account_impersonation_url", // service_account_impersonation_url;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(httpcli_get_should_not_be_called,
@ -2519,18 +2666,22 @@ TEST(CredentialsTest,
TestExternalAccountCredsFailureTokenExchangeResponseMissingAccessToken) {
ExecCtx exec_ctx;
Json credential_source = Json::FromString("");
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
TestExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"https://foo.com:5555/service_account_impersonation", // service_account_impersonation_url;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source;
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
credential_source, // credential_source
"quota_project_id", // quota_project_id;
"client_id", // client_id;
"client_secret", // client_secret;
"", // workforce_pool_user_project;
};
TestExternalAccountCredentials creds(options, {});
HttpRequest::SetOverride(
@ -2555,11 +2706,15 @@ TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatText) {
auto credential_source = JsonParse(
valid_url_external_account_creds_options_credential_source_format_text);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2592,11 +2747,15 @@ TEST(CredentialsTest,
auto credential_source = JsonParse(
valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2626,11 +2785,15 @@ TEST(CredentialsTest, TestUrlExternalAccountCredsSuccessFormatJson) {
auto credential_source = JsonParse(
valid_url_external_account_creds_options_credential_source_format_json);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2660,11 +2823,15 @@ TEST(CredentialsTest,
auto credential_source =
JsonParse(invalid_url_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2689,11 +2856,15 @@ TEST(CredentialsTest, TestFileExternalAccountCredsSuccessFormatText) {
"{\"file\":\"%s\"}",
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})));
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2734,11 +2905,15 @@ TEST(CredentialsTest, TestFileExternalAccountCredsSuccessFormatJson) {
"}",
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})));
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2768,11 +2943,15 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureFileNotFound) {
ExecCtx exec_ctx;
auto credential_source = JsonParse("{\"file\":\"non_exisiting_file\"}");
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2812,11 +2991,15 @@ TEST(CredentialsTest, TestFileExternalAccountCredsFailureInvalidJsonContent) {
"}",
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})));
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2849,11 +3032,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccess) {
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2883,11 +3070,15 @@ TEST(CredentialsTest, TestAwsImdsv2ExternalAccountCredsSuccess) {
auto credential_source = JsonParse(
valid_aws_imdsv2_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2923,11 +3114,15 @@ TEST(CredentialsTest,
auto credential_source = JsonParse(
valid_aws_imdsv2_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -2966,11 +3161,15 @@ TEST(
auto credential_source = JsonParse(
valid_aws_imdsv2_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3003,11 +3202,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessIpv6) {
auto credential_source = JsonParse(
valid_aws_external_account_creds_options_credential_source_ipv6);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3039,11 +3242,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionEnvKeysUrl) {
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3076,11 +3283,15 @@ TEST(CredentialsTest,
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3115,11 +3326,15 @@ TEST(CredentialsTest,
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3154,11 +3369,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionUrlKeysEnv) {
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3195,11 +3414,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsSuccessPathRegionEnvKeysEnv) {
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3240,11 +3463,15 @@ TEST(CredentialsTest,
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3285,11 +3512,15 @@ TEST(CredentialsTest,
auto credential_source =
JsonParse(valid_aws_external_account_creds_options_credential_source);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3324,8 +3555,9 @@ TEST(CredentialsTest, TestExternalAccountCredentialsCreateSuccess) {
const char* url_options_string =
"{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://foo.com:5555/"
"token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"url\":\"https://foo.com:5555/"
"generate_subject_token_format_json\",\"headers\":{\"Metadata-Flavor\":"
"\"Google\"},\"format\":{\"type\":\"json\",\"subject_token_field_name\":"
@ -3341,8 +3573,9 @@ TEST(CredentialsTest, TestExternalAccountCredentialsCreateSuccess) {
const char* file_options_string =
"{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://foo.com:5555/"
"token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"file\":\"credentials_file_path\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
@ -3356,7 +3589,8 @@ TEST(CredentialsTest, TestExternalAccountCredentialsCreateSuccess) {
const char* aws_options_string =
"{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"environment_id\":\"aws1\","
"\"region_url\":\"https://169.254.169.254:5555/"
@ -3378,11 +3612,15 @@ TEST(CredentialsTest,
auto credential_source = JsonParse(
invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3407,11 +3645,15 @@ TEST(CredentialsTest,
auto credential_source = JsonParse(
invalid_aws_external_account_creds_options_credential_source_invalid_regional_cred_verification_url);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3443,11 +3685,15 @@ TEST(CredentialsTest, TestAwsExternalAccountCredsFailureMissingRoleName) {
auto credential_source = JsonParse(
invalid_aws_external_account_creds_options_credential_source_missing_role_name);
GPR_ASSERT(credential_source.ok());
TestExternalAccountCredentials::ServiceAccountImpersonation
service_account_impersonation;
service_account_impersonation.token_lifetime_seconds = 3600;
ExternalAccountCredentials::Options options = {
"external_account", // type;
"audience", // audience;
"subject_token_type", // subject_token_type;
"", // service_account_impersonation_url;
service_account_impersonation, // service_account_impersonation;
"https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token_info", // token_info_url;
*credential_source, // credential_source;
@ -3496,8 +3742,9 @@ TEST(
const char* options_string =
"{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://foo.com:5555/"
"token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"random_key\":\"random_value\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
@ -3513,8 +3760,9 @@ TEST(CredentialsTest,
"{\"type\":\"external_account\",\"audience\":\"//iam.googleapis.com/"
"locations/location/workforcePools/pool/providers/provider\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://foo.com:5555/"
"token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"url\":\"https://foo.com:5555/"
"generate_subject_token_format_json\",\"headers\":{\"Metadata-Flavor\":"
"\"Google\"},\"format\":{\"type\":\"json\",\"subject_token_field_name\":"
@ -3535,8 +3783,9 @@ TEST(CredentialsTest,
"{\"type\":\"external_account\",\"audience\":\"invalid_workforce_pool_"
"audience\",\"subject_"
"token_type\":\"subject_token_type\",\"service_account_impersonation_"
"url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"url\":\"service_account_impersonation_url\","
"\"token_url\":\"https://foo.com:5555/"
"token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"url\":\"https://foo.com:5555/"
"generate_subject_token_format_json\",\"headers\":{\"Metadata-Flavor\":"
"\"Google\"},\"format\":{\"type\":\"json\",\"subject_token_field_name\":"

Loading…
Cancel
Save