Hi Manh,
By the way gRPC does this automatically via the
GOOGLE_APPLICATION_CREDENTIALS environment variable defined in grpc_security_constants.h:
/* Environment variable that points to the google default application
credentials json key or refresh token. Used in the
grpc_google_default_credentials_create function. */
#define GRPC_GOOGLE_CREDENTIALS_ENV_VAR "GOOGLE_APPLICATION_CREDENTIALS"
Keep in mind if you go via the the
GoogleDefaultCredentials() function - as Yang previously suggested - it basically performs several checks to find a way to authenticate you. Basically the call in
secure_credentials.cc calls
grpc_google_default_credentials_create()as such:
std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
GrpcLibraryCodegen init; // To call grpc_init().
return WrapChannelCredentials(grpc_google_default_credentials_create());
}Which
grpc_google_default_credentials_create() goes through a multitude of checks in
google_default_credentials.c:
grpc_channel_credentials *grpc_google_default_credentials_create(void) {
...
/* First, try the environment variable. */
err = create_default_creds_from_path(
gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
...
/* Then the well-known file. */
err = create_default_creds_from_path(
grpc_get_well_known_google_credentials_file_path(), &call_creds);
...
/* At last try to see if we're on compute engine (do the detection only once
since it requires a network test). */
if (!compute_engine_detection_done) {
int need_compute_engine_creds = is_stack_running_on_compute_engine();
compute_engine_detection_done = 1;
if (need_compute_engine_creds) {
call_creds = grpc_google_compute_engine_credentials_create(NULL);
...
}
Then
create_default_creds_from_path() performs these two checks:
/* First, try an auth json key. */
key = grpc_auth_json_key_create_from_json(json);
...
/* Then try a refresh token if the auth json key was invalid. */
token = grpc_auth_refresh_token_create_from_json(json);
...And the last function above looks up the stored gcloud credentials:
char *grpc_get_well_known_google_credentials_file_path(void) {
if (creds_path_getter != NULL) return creds_path_getter();
return grpc_get_well_known_google_credentials_file_path_impl();
}
The returned function call is in
credentials_posix.c:
gpr_asprintf(&result, "%s/.config/%s/%s", home,
GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY,
GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE);
And the two above variables are stored in
google_default_credentials.h:
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"If you tried to see if you have this file - which you will by running
gcloud beta auth application-default login - you will see the following directory as constructed above (the one below is for how it looks for me):
$ ls ~/.config/gcloud/application_default_credentials.json
/home/pgrosu/.config/gcloud/application_default_credentials.json
$And sure it is possible via the
Google APIs Client Library for C++. In the
example file you'll notice the following on
lines 657-661:
googleapis::util::Status status;
flow_.reset(OAuth2AuthorizationFlow::MakeFlowFromClientSecretsPath(
FLAGS_client_secrets_path,
config_->NewDefaultTransportOrDie(),
&status));
I think you might also find the following links helpful:
https://developers.google.com/identity/protocols/OAuth2http://google.github.io/google-api-cpp-client/latest/doxygen/classgoogleapis_1_1client_1_1OAuth2AuthorizationFlow.htmlhttp://google.github.io/google-api-cpp-client/latest/doxygen/classgoogleapis_1_1client_1_1OAuth2Credential.htmlHope it helps,
Paul