Add support of implicit and explicit flows for external account creds

pull/24814/head
Chuan Ren 4 years ago
parent 393687c3b7
commit 06cc42eb85
  1. 1
      grpc.def
  2. 8
      include/grpc/grpc_security.h
  3. 6
      include/grpcpp/security/credentials.h
  4. 7
      src/core/lib/security/credentials/external/aws_external_account_credentials.cc
  5. 7
      src/core/lib/security/credentials/external/aws_external_account_credentials.h
  6. 146
      src/core/lib/security/credentials/external/external_account_credentials.cc
  7. 12
      src/core/lib/security/credentials/external/external_account_credentials.h
  8. 11
      src/core/lib/security/credentials/external/file_external_account_credentials.cc
  9. 7
      src/core/lib/security/credentials/external/file_external_account_credentials.h
  10. 7
      src/core/lib/security/credentials/external/url_external_account_credentials.cc
  11. 7
      src/core/lib/security/credentials/external/url_external_account_credentials.h
  12. 4
      src/core/lib/security/credentials/google_default/google_default_credentials.cc
  13. 13
      src/cpp/client/secure_credentials.cc
  14. 2
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  15. 3
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  16. 531
      test/core/security/credentials_test.cc
  17. 1
      test/core/surface/public_headers_must_be_c89.c
  18. 47
      test/cpp/client/credentials_test.cc

@ -110,6 +110,7 @@ EXPORTS
grpc_google_compute_engine_credentials_create grpc_google_compute_engine_credentials_create
grpc_max_auth_token_lifetime grpc_max_auth_token_lifetime
grpc_service_account_jwt_access_credentials_create grpc_service_account_jwt_access_credentials_create
grpc_external_account_credentials_create
grpc_google_refresh_token_credentials_create grpc_google_refresh_token_credentials_create
grpc_access_token_credentials_create grpc_access_token_credentials_create
grpc_google_iam_credentials_create grpc_google_iam_credentials_create

@ -330,6 +330,14 @@ grpc_service_account_jwt_access_credentials_create(const char* json_key,
gpr_timespec token_lifetime, gpr_timespec token_lifetime,
void* reserved); void* reserved);
/** Builds External Account credentials.
- json_string is the JSON string containing the credentials options.
- scopes_string contains the scopes to be binded with the credentials.
This API is used for experimental purposes for now and may change in the
future. */
GRPCAPI grpc_call_credentials* grpc_external_account_credentials_create(
const char* json_string, const char* scopes_string);
/** Creates an Oauth2 Refresh Token credentials object for connecting to Google. /** Creates an Oauth2 Refresh Token credentials object for connecting to Google.
May return NULL if the input is invalid. May return NULL if the input is invalid.
WARNING: Do NOT use this credentials to connect to a non-google service as WARNING: Do NOT use this credentials to connect to a non-google service as

@ -307,6 +307,12 @@ grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options);
std::shared_ptr<CallCredentials> StsCredentials( std::shared_ptr<CallCredentials> StsCredentials(
const StsCredentialsOptions& options); const StsCredentialsOptions& options);
/// Builds External Account credentials.
/// json_string is the JSON string containing the credentials options.
/// scopes contains the scopes to be binded with the credentials.
std::shared_ptr<CallCredentials> ExternalAccountCredentials(
const grpc::string& json_string, const std::vector<grpc::string>& scopes);
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin( std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin, std::unique_ptr<MetadataCredentialsPlugin> plugin,
grpc_security_level min_security_level); grpc_security_level min_security_level);

@ -55,7 +55,7 @@ std::string UrlEncode(const absl::string_view& s) {
} // namespace } // namespace
RefCountedPtr<AwsExternalAccountCredentials> RefCountedPtr<AwsExternalAccountCredentials>
AwsExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options, AwsExternalAccountCredentials::Create(Options options,
std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error) { grpc_error** error) {
auto creds = MakeRefCounted<AwsExternalAccountCredentials>( auto creds = MakeRefCounted<AwsExternalAccountCredentials>(
@ -68,8 +68,7 @@ AwsExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options,
} }
AwsExternalAccountCredentials::AwsExternalAccountCredentials( AwsExternalAccountCredentials::AwsExternalAccountCredentials(
ExternalAccountCredentialsOptions options, std::vector<std::string> scopes, Options options, std::vector<std::string> scopes, grpc_error** error)
grpc_error** error)
: ExternalAccountCredentials(options, std::move(scopes)) { : ExternalAccountCredentials(options, std::move(scopes)) {
audience_ = options.audience; audience_ = options.audience;
auto it = options.credential_source.object_value().find("environment_id"); auto it = options.credential_source.object_value().find("environment_id");
@ -121,7 +120,7 @@ AwsExternalAccountCredentials::AwsExternalAccountCredentials(
} }
void AwsExternalAccountCredentials::RetrieveSubjectToken( void AwsExternalAccountCredentials::RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) { std::function<void(std::string, grpc_error*)> cb) {
if (ctx == nullptr) { if (ctx == nullptr) {
FinishRetrieveSubjectToken( FinishRetrieveSubjectToken(

@ -28,16 +28,15 @@ namespace grpc_core {
class AwsExternalAccountCredentials final : public ExternalAccountCredentials { class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
public: public:
static RefCountedPtr<AwsExternalAccountCredentials> Create( static RefCountedPtr<AwsExternalAccountCredentials> Create(
ExternalAccountCredentialsOptions options, Options options, std::vector<std::string> scopes, grpc_error** error);
std::vector<std::string> scopes, grpc_error** error);
AwsExternalAccountCredentials(ExternalAccountCredentialsOptions options, AwsExternalAccountCredentials(Options options,
std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error); grpc_error** error);
private: private:
void RetrieveSubjectToken( void RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) override; std::function<void(std::string, grpc_error*)> cb) override;
void RetrieveRegion(); void RetrieveRegion();

@ -19,6 +19,7 @@
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/time/clock.h" #include "absl/time/clock.h"
#include "absl/time/time.h" #include "absl/time/time.h"
@ -26,6 +27,10 @@
#include "src/core/lib/security/util/json_util.h" #include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/slice/b64.h" #include "src/core/lib/slice/b64.h"
#include "src/core/lib/security/credentials/external/aws_external_account_credentials.h"
#include "src/core/lib/security/credentials/external/file_external_account_credentials.h"
#include "src/core/lib/security/credentials/external/url_external_account_credentials.h"
#define EXTERNAL_ACCOUNT_CREDENTIALS_GRANT_TYPE \ #define EXTERNAL_ACCOUNT_CREDENTIALS_GRANT_TYPE \
"urn:ietf:params:oauth:grant-type:token-exchange" "urn:ietf:params:oauth:grant-type:token-exchange"
#define EXTERNAL_ACCOUNT_CREDENTIALS_REQUESTED_TOKEN_TYPE \ #define EXTERNAL_ACCOUNT_CREDENTIALS_REQUESTED_TOKEN_TYPE \
@ -57,8 +62,122 @@ std::string UrlEncode(const absl::string_view& s) {
} // namespace } // namespace
RefCountedPtr<ExternalAccountCredentials> ExternalAccountCredentials::Create(
const Json& json, std::vector<std::string> scopes, grpc_error** error) {
GPR_ASSERT(*error == GRPC_ERROR_NONE);
Options options;
options.type = GRPC_AUTH_JSON_TYPE_INVALID;
if (json.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid json to construct credentials options.");
return nullptr;
}
auto it = json.object_value().find("type");
if (it == json.object_value().end()) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("type field not present.");
return nullptr;
}
if (it->second.type() != Json::Type::STRING) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("type field must be a string.");
return nullptr;
}
if (it->second.string_value() != GRPC_AUTH_JSON_TYPE_EXTERNAL_ACCOUNT) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid credentials json type.");
return nullptr;
}
options.type = GRPC_AUTH_JSON_TYPE_EXTERNAL_ACCOUNT;
it = json.object_value().find("audience");
if (it == json.object_value().end()) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("audience field not present.");
return nullptr;
}
if (it->second.type() != Json::Type::STRING) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"audience field must be a string.");
return nullptr;
}
options.audience = it->second.string_value();
it = json.object_value().find("subject_token_type");
if (it == json.object_value().end()) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"subject_token_type field not present.");
return nullptr;
}
if (it->second.type() != Json::Type::STRING) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"subject_token_type field must be a string.");
return nullptr;
}
options.subject_token_type = it->second.string_value();
it = json.object_value().find("service_account_impersonation_url");
if (it != json.object_value().end()) {
options.service_account_impersonation_url = it->second.string_value();
}
it = json.object_value().find("token_url");
if (it == json.object_value().end()) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("token_url field not present.");
return nullptr;
}
if (it->second.type() != Json::Type::STRING) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"token_url field must be a string.");
return nullptr;
}
options.token_url = it->second.string_value();
it = json.object_value().find("token_info_url");
if (it != json.object_value().end()) {
options.token_info_url = it->second.string_value();
}
it = json.object_value().find("credential_source");
if (it == json.object_value().end()) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"credential_source field not present.");
return nullptr;
}
options.credential_source = it->second;
it = json.object_value().find("quota_project_id");
if (it != json.object_value().end()) {
options.quota_project_id = it->second.string_value();
}
it = json.object_value().find("client_id");
if (it != json.object_value().end()) {
options.client_id = it->second.string_value();
}
it = json.object_value().find("client_secret");
if (it != json.object_value().end()) {
options.client_secret = it->second.string_value();
}
RefCountedPtr<ExternalAccountCredentials> creds;
if (options.credential_source.object_value().find("environment_id") !=
options.credential_source.object_value().end()) {
creds = MakeRefCounted<AwsExternalAccountCredentials>(
std::move(options), std::move(scopes), error);
} else if (options.credential_source.object_value().find("file") !=
options.credential_source.object_value().end()) {
creds = MakeRefCounted<FileExternalAccountCredentials>(
std::move(options), std::move(scopes), error);
} else if (options.credential_source.object_value().find("url") !=
options.credential_source.object_value().end()) {
creds = MakeRefCounted<UrlExternalAccountCredentials>(
std::move(options), std::move(scopes), error);
} else {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Invalid options credential source to create "
"ExternalAccountCredentials.");
}
if (*error == GRPC_ERROR_NONE) {
return creds;
} else {
return nullptr;
}
}
ExternalAccountCredentials::ExternalAccountCredentials( ExternalAccountCredentials::ExternalAccountCredentials(
ExternalAccountCredentialsOptions options, std::vector<std::string> scopes) Options options, std::vector<std::string> scopes)
: options_(std::move(options)) { : options_(std::move(options)) {
if (scopes.empty()) { if (scopes.empty()) {
scopes.push_back(GOOGLE_CLOUD_PLATFORM_DEFAULT_SCOPE); scopes.push_back(GOOGLE_CLOUD_PLATFORM_DEFAULT_SCOPE);
@ -351,3 +470,28 @@ void ExternalAccountCredentials::FinishTokenFetch(grpc_error* error) {
} }
} // namespace grpc_core } // namespace grpc_core
grpc_call_credentials* grpc_external_account_credentials_create(
const char* json_string, const char* scopes_string) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_core::Json json = grpc_core::Json::Parse(json_string, &error);
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"External account credentials creation failed. Error: %s.",
grpc_error_string(error));
GRPC_ERROR_UNREF(error);
return nullptr;
}
std::vector<std::string> scopes = absl::StrSplit(scopes_string, ',');
auto creds = grpc_core::ExternalAccountCredentials::Create(
json, std::move(scopes), &error)
.release();
if (error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR,
"External account credentials creation failed. Error: %s.",
grpc_error_string(error));
GRPC_ERROR_UNREF(error);
return nullptr;
}
return creds;
}

@ -35,7 +35,7 @@ class ExternalAccountCredentials
: public grpc_oauth2_token_fetcher_credentials { : public grpc_oauth2_token_fetcher_credentials {
public: public:
// External account credentials json interface. // External account credentials json interface.
struct ExternalAccountCredentialsOptions { struct Options {
std::string type; std::string type;
std::string audience; std::string audience;
std::string subject_token_type; std::string subject_token_type;
@ -48,8 +48,10 @@ class ExternalAccountCredentials
std::string client_secret; std::string client_secret;
}; };
ExternalAccountCredentials(ExternalAccountCredentialsOptions options, static RefCountedPtr<ExternalAccountCredentials> Create(
std::vector<std::string> scopes); const Json& json, std::vector<std::string> scopes, grpc_error** error);
ExternalAccountCredentials(Options options, std::vector<std::string> scopes);
~ExternalAccountCredentials() override; ~ExternalAccountCredentials() override;
std::string debug_string() override; std::string debug_string() override;
@ -81,7 +83,7 @@ class ExternalAccountCredentials
// the callback function (cb) to pass the subject token (or error) // the callback function (cb) to pass the subject token (or error)
// back. // back.
virtual void RetrieveSubjectToken( virtual void RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) = 0; std::function<void(std::string, grpc_error*)> cb) = 0;
private: private:
@ -105,7 +107,7 @@ class ExternalAccountCredentials
void FinishTokenFetch(grpc_error* error); void FinishTokenFetch(grpc_error* error);
ExternalAccountCredentialsOptions options_; Options options_;
std::vector<std::string> scopes_; std::vector<std::string> scopes_;
HTTPRequestContext* ctx_ = nullptr; HTTPRequestContext* ctx_ = nullptr;

@ -26,9 +26,9 @@
namespace grpc_core { namespace grpc_core {
RefCountedPtr<FileExternalAccountCredentials> RefCountedPtr<FileExternalAccountCredentials>
FileExternalAccountCredentials::Create( FileExternalAccountCredentials::Create(Options options,
ExternalAccountCredentialsOptions options, std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error) { grpc_error** error) {
auto creds = MakeRefCounted<FileExternalAccountCredentials>( auto creds = MakeRefCounted<FileExternalAccountCredentials>(
std::move(options), std::move(scopes), error); std::move(options), std::move(scopes), error);
if (*error == GRPC_ERROR_NONE) { if (*error == GRPC_ERROR_NONE) {
@ -39,8 +39,7 @@ FileExternalAccountCredentials::Create(
} }
FileExternalAccountCredentials::FileExternalAccountCredentials( FileExternalAccountCredentials::FileExternalAccountCredentials(
ExternalAccountCredentialsOptions options, std::vector<std::string> scopes, Options options, std::vector<std::string> scopes, grpc_error** error)
grpc_error** error)
: ExternalAccountCredentials(options, std::move(scopes)) { : ExternalAccountCredentials(options, std::move(scopes)) {
auto it = options.credential_source.object_value().find("file"); auto it = options.credential_source.object_value().find("file");
if (it == options.credential_source.object_value().end()) { if (it == options.credential_source.object_value().end()) {
@ -92,7 +91,7 @@ FileExternalAccountCredentials::FileExternalAccountCredentials(
} }
void FileExternalAccountCredentials::RetrieveSubjectToken( void FileExternalAccountCredentials::RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) { std::function<void(std::string, grpc_error*)> cb) {
struct SliceWrapper { struct SliceWrapper {
~SliceWrapper() { grpc_slice_unref_internal(slice); } ~SliceWrapper() { grpc_slice_unref_internal(slice); }

@ -26,16 +26,15 @@ namespace grpc_core {
class FileExternalAccountCredentials final : public ExternalAccountCredentials { class FileExternalAccountCredentials final : public ExternalAccountCredentials {
public: public:
static RefCountedPtr<FileExternalAccountCredentials> Create( static RefCountedPtr<FileExternalAccountCredentials> Create(
ExternalAccountCredentialsOptions options, Options options, std::vector<std::string> scopes, grpc_error** error);
std::vector<std::string> scopes, grpc_error** error);
FileExternalAccountCredentials(ExternalAccountCredentialsOptions options, FileExternalAccountCredentials(Options options,
std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error); grpc_error** error);
private: private:
void RetrieveSubjectToken( void RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) override; std::function<void(std::string, grpc_error*)> cb) override;
// Fields of credential source // Fields of credential source

@ -24,7 +24,7 @@
namespace grpc_core { namespace grpc_core {
RefCountedPtr<UrlExternalAccountCredentials> RefCountedPtr<UrlExternalAccountCredentials>
UrlExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options, UrlExternalAccountCredentials::Create(Options options,
std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error) { grpc_error** error) {
auto creds = MakeRefCounted<UrlExternalAccountCredentials>( auto creds = MakeRefCounted<UrlExternalAccountCredentials>(
@ -37,8 +37,7 @@ UrlExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options,
} }
UrlExternalAccountCredentials::UrlExternalAccountCredentials( UrlExternalAccountCredentials::UrlExternalAccountCredentials(
ExternalAccountCredentialsOptions options, std::vector<std::string> scopes, Options options, std::vector<std::string> scopes, grpc_error** error)
grpc_error** error)
: ExternalAccountCredentials(options, std::move(scopes)) { : ExternalAccountCredentials(options, std::move(scopes)) {
auto it = options.credential_source.object_value().find("url"); auto it = options.credential_source.object_value().find("url");
if (it == options.credential_source.object_value().end()) { if (it == options.credential_source.object_value().end()) {
@ -113,7 +112,7 @@ UrlExternalAccountCredentials::UrlExternalAccountCredentials(
} }
void UrlExternalAccountCredentials::RetrieveSubjectToken( void UrlExternalAccountCredentials::RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) { std::function<void(std::string, grpc_error*)> cb) {
if (ctx == nullptr) { if (ctx == nullptr) {
FinishRetrieveSubjectToken( FinishRetrieveSubjectToken(

@ -26,16 +26,15 @@ namespace grpc_core {
class UrlExternalAccountCredentials final : public ExternalAccountCredentials { class UrlExternalAccountCredentials final : public ExternalAccountCredentials {
public: public:
static RefCountedPtr<UrlExternalAccountCredentials> Create( static RefCountedPtr<UrlExternalAccountCredentials> Create(
ExternalAccountCredentialsOptions options, Options options, std::vector<std::string> scopes, grpc_error** error);
std::vector<std::string> scopes, grpc_error** error);
UrlExternalAccountCredentials(ExternalAccountCredentialsOptions options, UrlExternalAccountCredentials(Options options,
std::vector<std::string> scopes, std::vector<std::string> scopes,
grpc_error** error); grpc_error** error);
private: private:
void RetrieveSubjectToken( void RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) override; std::function<void(std::string, grpc_error*)> cb) override;
static void OnRetrieveSubjectToken(void* arg, grpc_error* error); static void OnRetrieveSubjectToken(void* arg, grpc_error* error);

@ -38,6 +38,7 @@
#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/security/credentials/alts/alts_credentials.h" #include "src/core/lib/security/credentials/alts/alts_credentials.h"
#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
#include "src/core/lib/security/credentials/external/external_account_credentials.h"
#include "src/core/lib/security/credentials/google_default/google_default_credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h" #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
@ -269,6 +270,9 @@ static grpc_error* create_default_creds_from_path(
goto end; goto end;
} }
/* Finally try an external account credentials.*/
result = grpc_core::ExternalAccountCredentials::Create(json, {}, &error);
end: end:
GPR_ASSERT((result == nullptr) + (error == GRPC_ERROR_NONE) == 1); GPR_ASSERT((result == nullptr) + (error == GRPC_ERROR_NONE) == 1);
grpc_slice_unref_internal(creds_data); grpc_slice_unref_internal(creds_data);

@ -28,6 +28,8 @@
#include <grpcpp/impl/grpc_library.h> #include <grpcpp/impl/grpc_library.h>
#include <grpcpp/support/channel_arguments.h> #include <grpcpp/support/channel_arguments.h>
#include "absl/strings/str_join.h"
// TODO(yashykt): We shouldn't be including "src/core" headers. // TODO(yashykt): We shouldn't be including "src/core" headers.
#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/env.h"
#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/error.h"
@ -107,6 +109,17 @@ std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
grpc_google_default_credentials_create(nullptr)); grpc_google_default_credentials_create(nullptr));
} }
namespace experimental {
std::shared_ptr<CallCredentials> ExternalAccountCredentials(
const grpc::string& json_string, const std::vector<grpc::string>& scopes) {
grpc::GrpcLibraryCodegen init; // To call grpc_init().
return WrapCallCredentials(grpc_external_account_credentials_create(
json_string.c_str(), absl::StrJoin(scopes, ",").c_str()));
}
} // namespace experimental
// Builds SSL Credentials given SSL specific options // Builds SSL Credentials given SSL specific options
std::shared_ptr<ChannelCredentials> SslCredentials( std::shared_ptr<ChannelCredentials> SslCredentials(
const SslCredentialsOptions& options) { const SslCredentialsOptions& options) {

@ -133,6 +133,7 @@ grpc_composite_call_credentials_create_type grpc_composite_call_credentials_crea
grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import; grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import; grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import; grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
grpc_external_account_credentials_create_type grpc_external_account_credentials_create_import;
grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import; grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import; grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import;
grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import;
@ -416,6 +417,7 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create"); grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create");
grpc_max_auth_token_lifetime_import = (grpc_max_auth_token_lifetime_type) GetProcAddress(library, "grpc_max_auth_token_lifetime"); grpc_max_auth_token_lifetime_import = (grpc_max_auth_token_lifetime_type) GetProcAddress(library, "grpc_max_auth_token_lifetime");
grpc_service_account_jwt_access_credentials_create_import = (grpc_service_account_jwt_access_credentials_create_type) GetProcAddress(library, "grpc_service_account_jwt_access_credentials_create"); grpc_service_account_jwt_access_credentials_create_import = (grpc_service_account_jwt_access_credentials_create_type) GetProcAddress(library, "grpc_service_account_jwt_access_credentials_create");
grpc_external_account_credentials_create_import = (grpc_external_account_credentials_create_type) GetProcAddress(library, "grpc_external_account_credentials_create");
grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create"); grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create");
grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create"); grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create");
grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create"); grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create");

@ -374,6 +374,9 @@ extern grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
typedef grpc_call_credentials*(*grpc_service_account_jwt_access_credentials_create_type)(const char* json_key, gpr_timespec token_lifetime, void* reserved); typedef grpc_call_credentials*(*grpc_service_account_jwt_access_credentials_create_type)(const char* json_key, gpr_timespec token_lifetime, void* reserved);
extern grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import; extern grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
#define grpc_service_account_jwt_access_credentials_create grpc_service_account_jwt_access_credentials_create_import #define grpc_service_account_jwt_access_credentials_create grpc_service_account_jwt_access_credentials_create_import
typedef grpc_call_credentials*(*grpc_external_account_credentials_create_type)(const char* json_string, const char* scopes_string);
extern grpc_external_account_credentials_create_type grpc_external_account_credentials_create_import;
#define grpc_external_account_credentials_create grpc_external_account_credentials_create_import
typedef grpc_call_credentials*(*grpc_google_refresh_token_credentials_create_type)(const char* json_refresh_token, void* reserved); typedef grpc_call_credentials*(*grpc_google_refresh_token_credentials_create_type)(const char* json_refresh_token, void* reserved);
extern grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import; extern grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
#define grpc_google_refresh_token_credentials_create grpc_google_refresh_token_credentials_create_import #define grpc_google_refresh_token_credentials_create grpc_google_refresh_token_credentials_create_import

@ -2206,13 +2206,13 @@ static int aws_external_account_creds_httpcli_post_success(
class TestExternalAccountCredentials final class TestExternalAccountCredentials final
: public grpc_core::ExternalAccountCredentials { : public grpc_core::ExternalAccountCredentials {
public: public:
TestExternalAccountCredentials(ExternalAccountCredentialsOptions options, TestExternalAccountCredentials(Options options,
std::vector<std::string> scopes) std::vector<std::string> scopes)
: ExternalAccountCredentials(std::move(options), std::move(scopes)) {} : ExternalAccountCredentials(std::move(options), std::move(scopes)) {}
protected: protected:
void RetrieveSubjectToken( void RetrieveSubjectToken(
HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options, HTTPRequestContext* ctx, const Options& options,
std::function<void(std::string, grpc_error*)> cb) override { std::function<void(std::string, grpc_error*)> cb) override {
cb("test_subject_token", GRPC_ERROR_NONE); cb("test_subject_token", GRPC_ERROR_NONE);
} }
@ -2224,7 +2224,7 @@ static void test_external_account_creds_success(void) {
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience", // audience; "audience", // audience;
"subject_token_type", // subject_token_type; "subject_token_type", // subject_token_type;
@ -2262,7 +2262,7 @@ static void test_external_account_creds_success_with_url_encode(void) {
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience_!@#$", // audience; "audience_!@#$", // audience;
"subject_token_type_!@#$", // subject_token_type; "subject_token_type_!@#$", // subject_token_type;
@ -2292,7 +2292,7 @@ test_external_account_creds_success_with_service_account_impersonation(void) {
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience", // audience; "audience", // audience;
"subject_token_type", // subject_token_type; "subject_token_type", // subject_token_type;
@ -2322,7 +2322,7 @@ static void test_external_account_creds_failure_invalid_token_url(void) {
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience", // audience; "audience", // audience;
"subject_token_type", // subject_token_type; "subject_token_type", // subject_token_type;
@ -2356,7 +2356,7 @@ test_external_account_creds_failure_invalid_service_account_impersonation_url(
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience", // audience; "audience", // audience;
"subject_token_type", // subject_token_type; "subject_token_type", // subject_token_type;
@ -2391,7 +2391,7 @@ test_external_account_creds_failure_token_exchange_response_missing_access_token
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr}; nullptr, nullptr};
grpc_core::Json credential_source(""); grpc_core::Json credential_source("");
TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = { TestExternalAccountCredentials::Options options = {
"external_account", // type; "external_account", // type;
"audience", // audience; "audience", // audience;
"subject_token_type", // subject_token_type; "subject_token_type", // subject_token_type;
@ -2431,19 +2431,18 @@ static void test_url_external_account_creds_success_format_text(void) {
valid_url_external_account_creds_options_credential_source_format_text, valid_url_external_account_creds_options_credential_source_format_text,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error); grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2469,19 +2468,18 @@ test_url_external_account_creds_success_with_qurey_params_format_text(void) {
valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text, valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error); grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2506,19 +2504,18 @@ static void test_url_external_account_creds_success_format_json(void) {
valid_url_external_account_creds_options_credential_source_format_json, valid_url_external_account_creds_options_credential_source_format_json,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error); grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2539,19 +2536,18 @@ test_url_external_account_creds_failure_invalid_credential_source_url(void) {
grpc_core::Json credential_source = grpc_core::Json::Parse( grpc_core::Json credential_source = grpc_core::Json::Parse(
invalid_url_external_account_creds_options_credential_source, &error); invalid_url_external_account_creds_options_credential_source, &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error); grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds == nullptr); GPR_ASSERT(creds == nullptr);
@ -2577,19 +2573,18 @@ static void test_file_external_account_creds_success_format_text(void) {
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})), absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::FileExternalAccountCredentials::Create(options, {}, &error); grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2627,19 +2622,18 @@ static void test_file_external_account_creds_success_format_json(void) {
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})), absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::FileExternalAccountCredentials::Create(options, {}, &error); grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2664,19 +2658,18 @@ static void test_file_external_account_creds_failure_file_not_found(void) {
grpc_core::Json credential_source = grpc_core::Json credential_source =
grpc_core::Json::Parse("{\"file\":\"non_exisiting_file\"}", &error); grpc_core::Json::Parse("{\"file\":\"non_exisiting_file\"}", &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::FileExternalAccountCredentials::Create(options, {}, &error); grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2714,19 +2707,18 @@ static void test_file_external_account_creds_failure_invalid_json_content(
absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})), absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::FileExternalAccountCredentials::Create(options, {}, &error); grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2755,19 +2747,18 @@ static void test_aws_external_account_creds_success(void) {
grpc_core::Json credential_source = grpc_core::Json::Parse( grpc_core::Json credential_source = grpc_core::Json::Parse(
valid_aws_external_account_creds_options_credential_source, &error); valid_aws_external_account_creds_options_credential_source, &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2793,19 +2784,18 @@ static void test_aws_external_account_creds_success_path_region_env_keys_url(
grpc_core::Json credential_source = grpc_core::Json::Parse( grpc_core::Json credential_source = grpc_core::Json::Parse(
valid_aws_external_account_creds_options_credential_source, &error); valid_aws_external_account_creds_options_credential_source, &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2834,19 +2824,18 @@ static void test_aws_external_account_creds_success_path_region_url_keys_env(
grpc_core::Json credential_source = grpc_core::Json::Parse( grpc_core::Json credential_source = grpc_core::Json::Parse(
valid_aws_external_account_creds_options_credential_source, &error); valid_aws_external_account_creds_options_credential_source, &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2878,19 +2867,18 @@ static void test_aws_external_account_creds_success_path_region_env_keys_env(
grpc_core::Json credential_source = grpc_core::Json::Parse( grpc_core::Json credential_source = grpc_core::Json::Parse(
valid_aws_external_account_creds_options_credential_source, &error); valid_aws_external_account_creds_options_credential_source, &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2916,19 +2904,18 @@ static void test_aws_external_account_creds_failure_unmatched_environment_id(
invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id, invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds == nullptr); GPR_ASSERT(creds == nullptr);
@ -2950,19 +2937,18 @@ static void test_aws_external_account_creds_failure_invalid_region_url(void) {
invalid_aws_external_account_creds_options_credential_source_invalid_region_url, invalid_aws_external_account_creds_options_credential_source_invalid_region_url,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -2991,19 +2977,18 @@ static void test_aws_external_account_creds_failure_invalid_url(void) {
invalid_aws_external_account_creds_options_credential_source_invalid_url, invalid_aws_external_account_creds_options_credential_source_invalid_url,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -3031,19 +3016,18 @@ static void test_aws_external_account_creds_failure_missing_role_name(void) {
invalid_aws_external_account_creds_options_credential_source_missing_role_name, invalid_aws_external_account_creds_options_credential_source_missing_role_name,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -3074,19 +3058,18 @@ test_aws_external_account_creds_failure_invalid_regional_cred_verification_url(
invalid_aws_external_account_creds_options_credential_source_invalid_regional_cred_verification_url, invalid_aws_external_account_creds_options_credential_source_invalid_regional_cred_verification_url,
&error); &error);
GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(error == GRPC_ERROR_NONE);
grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions grpc_core::ExternalAccountCredentials::Options options = {
options = { "external_account", // type;
"external_account", // type; "audience", // audience;
"audience", // audience; "subject_token_type", // subject_token_type;
"subject_token_type", // subject_token_type; "", // service_account_impersonation_url;
"", // service_account_impersonation_url; "https://foo.com:5555/token", // token_url;
"https://foo.com:5555/token", // token_url; "https://foo.com:5555/token_info", // token_info_url;
"https://foo.com:5555/token_info", // token_info_url; credential_source, // credential_source;
credential_source, // credential_source; "quota_project_id", // quota_project_id;
"quota_project_id", // quota_project_id; "client_id", // client_id;
"client_id", // client_id; "client_secret", // client_secret;
"client_secret", // client_secret; };
};
auto creds = auto creds =
grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error); grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
GPR_ASSERT(creds != nullptr); GPR_ASSERT(creds != nullptr);
@ -3106,6 +3089,92 @@ test_aws_external_account_creds_failure_invalid_regional_cred_verification_url(
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
} }
static void test_external_account_credentials_create_success(void) {
// url credentials
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/"
"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\"}";
const char* url_scopes_string = "scope1,scope2";
grpc_call_credentials* url_creds = grpc_external_account_credentials_create(
url_options_string, url_scopes_string);
GPR_ASSERT(url_creds != nullptr);
url_creds->Unref();
// file credentials
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/"
"token_info\",\"credential_source\":{\"file\":\"credentials_file_path\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
"secret\"}";
const char* file_scopes_string = "scope1,scope2";
grpc_call_credentials* file_creds = grpc_external_account_credentials_create(
file_options_string, file_scopes_string);
GPR_ASSERT(file_creds != nullptr);
file_creds->Unref();
// aws credentials
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://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"environment_id\":\"aws1\","
"\"region_url\":\"https://foo.com:5555/region_url\",\"url\":\"https://"
"foo.com:5555/url\",\"regional_cred_verification_url\":\"https://"
"foo.com:5555/regional_cred_verification_url_{region}\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
"secret\"}";
const char* aws_scopes_string = "scope1,scope2";
grpc_call_credentials* aws_creds = grpc_external_account_credentials_create(
aws_options_string, aws_scopes_string);
GPR_ASSERT(aws_creds != nullptr);
aws_creds->Unref();
}
static void
test_external_account_credentials_create_failure_invalid_json_format(void) {
const char* options_string = "invalid_json";
grpc_call_credentials* creds =
grpc_external_account_credentials_create(options_string, "");
GPR_ASSERT(creds == nullptr);
}
static void
test_external_account_credentials_create_failure_invalid_options_format(void) {
const char* options_string = "{\"random_key\":\"random_value\"}";
grpc_call_credentials* creds =
grpc_external_account_credentials_create(options_string, "");
GPR_ASSERT(creds == nullptr);
}
static void
test_external_account_credentials_create_failure_invalid_options_credential_source(
void) {
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/"
"token_info\",\"credential_source\":{\"random_key\":\"random_value\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
"secret\"}";
grpc_call_credentials* creds =
grpc_external_account_credentials_create(options_string, "");
GPR_ASSERT(creds == nullptr);
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc::testing::TestEnvironment env(argc, argv); grpc::testing::TestEnvironment env(argc, argv);
grpc_init(); grpc_init();
@ -3173,6 +3242,10 @@ int main(int argc, char** argv) {
test_aws_external_account_creds_failure_invalid_url(); test_aws_external_account_creds_failure_invalid_url();
test_aws_external_account_creds_failure_missing_role_name(); test_aws_external_account_creds_failure_missing_role_name();
test_aws_external_account_creds_failure_invalid_regional_cred_verification_url(); test_aws_external_account_creds_failure_invalid_regional_cred_verification_url();
test_external_account_credentials_create_success();
test_external_account_credentials_create_failure_invalid_json_format();
test_external_account_credentials_create_failure_invalid_options_format();
test_external_account_credentials_create_failure_invalid_options_credential_source();
grpc_shutdown(); grpc_shutdown();
return 0; return 0;
} }

@ -177,6 +177,7 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create); printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create);
printf("%lx", (unsigned long) grpc_max_auth_token_lifetime); printf("%lx", (unsigned long) grpc_max_auth_token_lifetime);
printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create); printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create);
printf("%lx", (unsigned long) grpc_external_account_credentials_create);
printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create); printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create);
printf("%lx", (unsigned long) grpc_access_token_credentials_create); printf("%lx", (unsigned long) grpc_access_token_credentials_create);
printf("%lx", (unsigned long) grpc_google_iam_credentials_create); printf("%lx", (unsigned long) grpc_google_iam_credentials_create);

@ -97,6 +97,53 @@ TEST(CredentialsTest, DefaultCredentials) {
auto creds = GoogleDefaultCredentials(); auto creds = GoogleDefaultCredentials();
} }
TEST(CredentialsTest, ExternalAccountCredentials) {
// url credentials
std::string 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/"
"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 url_creds = grpc::experimental::ExternalAccountCredentials(
url_options_string, {"scope1", "scope2"});
EXPECT_TRUE(url_creds != nullptr);
// file credentials
std::string 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/"
"token_info\",\"credential_source\":{\"file\":\"credentials_file_path\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
"secret\"}");
auto file_creds = grpc::experimental::ExternalAccountCredentials(
file_options_string, {"scope1", "scope2"});
EXPECT_TRUE(file_creds != nullptr);
// aws credentials
std::string 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://"
"foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
"token_info\",\"credential_source\":{\"environment_id\":\"aws1\","
"\"region_url\":\"https://foo.com:5555/region_url\",\"url\":\"https://"
"foo.com:5555/url\",\"regional_cred_verification_url\":\"https://"
"foo.com:5555/regional_cred_verification_url_{region}\"},"
"\"quota_project_id\":\"quota_"
"project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
"secret\"}");
auto aws_creds = grpc::experimental::ExternalAccountCredentials(
aws_options_string, {"scope1", "scope2"});
EXPECT_TRUE(aws_creds != nullptr);
}
TEST(CredentialsTest, StsCredentialsOptionsCppToCore) { TEST(CredentialsTest, StsCredentialsOptionsCppToCore) {
grpc::experimental::StsCredentialsOptions options; grpc::experimental::StsCredentialsOptions options;
options.token_exchange_service_uri = "https://foo.com/exchange"; options.token_exchange_service_uri = "https://foo.com/exchange";

Loading…
Cancel
Save