Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Load content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. #1611

Closed
sheeeng opened this issue Jul 24, 2020 · 12 comments
Assignees
Labels
type: question Request for information or clarification. Not an issue.

Comments

@sheeeng
Copy link

sheeeng commented Jul 24, 2020

According to official documentation[1][2], GOOGLE_APPLICATION_CREDENTIALS environment variable can only accept file path to a JSON formatted credentials file.

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json"

As a user, I would want to load the content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using the file path. I want to prevent writing credentials to the file system.

export GOOGLE_APPLICATION_CREDENTIALS="{"type": "service_account", "project_id": "changeit-project", ...}"

Please forgive my ignorance. Is it possible that we use GoogleCredential.FromJson(string json) function[3] as a workaound?

P.S. There is also a related case[4] under google-api-go-client project.

[1] https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.BigQuery.V2/index.html#authentication
[2] https://cloud.google.com/docs/authentication/getting-started
[3] https://googleapis.dev/dotnet/Google.Apis.Auth/1.48.0/api/Google.Apis.Auth.OAuth2.GoogleCredential.html#Google_Apis_Auth_OAuth2_GoogleCredential_FromJson_System_String_
[4] googleapis/google-api-go-client#185

@sheeeng sheeeng changed the title Load content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Load content of JSON credential directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Jul 24, 2020
@sheeeng sheeeng changed the title Load content of JSON credential directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Load content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Jul 24, 2020
@sheeeng sheeeng changed the title Load content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Load content of JSON credential directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Jul 24, 2020
@sheeeng sheeeng changed the title Load content of JSON credential directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Load content of JSON credentials directly into GOOGLE_APPLICATION_CREDENTIALS environment variable without using file path. Jul 24, 2020
@jskeet
Copy link
Collaborator

jskeet commented Jul 24, 2020

No, you have to choose between automatically loading the credentials from a file, or manually loading it from a string. (Obviously the code doesn't care where you get that string from - it could be in an environment variable.) But the default application credentials path will never use the content of an environment variable as the credential data itself.

@jskeet jskeet self-assigned this Jul 24, 2020
@jskeet jskeet added the type: question Request for information or clarification. Not an issue. label Jul 24, 2020
@sheeeng
Copy link
Author

sheeeng commented Jul 25, 2020

Thanks Jon for the clarification.

Have I understand correctly that the purpose of the mentioned environment variable encapsulates the use of GoogleCredential.FromJson(string json) function?

Thus, it is alright for us to load the content of JSON credentials directly into GoogleCredential.FromJson(string json) function in a .NET client application?

@jskeet
Copy link
Collaborator

jskeet commented Jul 25, 2020

I don't know what you mean by "the purpose of the mentioned environment variable encapsulates the use of GoogleCredential.FromJson(string json) function". It doesn't end up calling that method - it's closer to using FromFile - but they both end up loading JSON and creating a credential from it.

But yes, it's absolutely fine to use GoogleCredential.FromJson in a .NET client application. Could you give any reason why you're concerned it might not be okay to do that? (That's the precise purpose of the method, after all.)

@sheeeng
Copy link
Author

sheeeng commented Jul 25, 2020

Thanks, Jon. Please don't get me wrong. We would want to use GoogleCredential.FromJson in a .NET client application, instead of using GOOGLE_APPLICATION_CREDENTIALS environment variable. I will try to make small example to demonstrate it. Thanks for the clarification again.

@sheeeng
Copy link
Author

sheeeng commented Jul 27, 2020

I did not progress much since the last comment.

I'm authenticating a BigTable client to Google Cloud through Microsoft Azure.

byte[] data = Convert.FromBase64String(base64String);
string jsonKey = Encoding.UTF8.GetString(data);
-        var fileName = "credentials";
-        File.WriteAllText(fileName, jsonKey);
-        Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", fileName);
+        GoogleCredential.FromJson(jsonKey);
System.InvalidOperationException : The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.

I read[1] that If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn't set, Application Default Credentials (ADC) uses the default service account that Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run, and Cloud Functions provide.
[1] https://cloud.google.com/docs/authentication/production#automatically

We have GoogleCredential.GetApplicationDefault(), but is it possible to set application default credential after using GoogleCredential.FromJson(jsonKey) function?

@jskeet
Copy link
Collaborator

jskeet commented Jul 27, 2020

You're just calling GoogleCredential.FromJson, but not using the result anywhere. You need to specify that as the credential when you create the client. It's not like GoogleCredential.FromJson sets the default credential - it just creates one and returns it to you.

If you're using Google.Cloud.BigQuery.V2, just use:

var credential = GoogleCredential.FromJson(jsonKey);
var client = BigQueryClient.Create(projectId, credential);

(I'm slightly confused as you were talking about BigQuery before, and your last comment is about Bigtable. Those are separate products, with slightly different APIs.)

@sheeeng
Copy link
Author

sheeeng commented Jul 27, 2020

Thanks for the clarification. I should be clear about authentication through a Google.Cloud.Bigtable.V2.BigtableClient and `, not BigQuery.

How does authenticating through BigTable client looks like after GoogleCredential.FromJson() funtion?

@jskeet
Copy link
Collaborator

jskeet commented Jul 27, 2020

In that case, you don't even need to call GoogleCredential.FromJson:

var client = new BigtableClientBuilder { JsonCredentials = jsonKey }.Build();

See https://googleapis.github.io/google-cloud-dotnet/docs/faq.html#how-can-i-use-non-default-credentials-for-grpc-based-apis for more details.

@sheeeng
Copy link
Author

sheeeng commented Jul 27, 2020

Thank you for much for the clarification, Jon.

@sheeeng sheeeng closed this as completed Jul 27, 2020
@oskar
Copy link

oskar commented Jul 8, 2021

But the default application credentials path will never use the content of an environment variable as the credential data itself.

@jskeet Could you please elaborate a bit on the rationale behind this design decision? Is it due to some kind of security concern?

@jskeet
Copy link
Collaborator

jskeet commented Jul 8, 2021

@oskar: I can't speak for the auth design team, but I would expect that yes, there are security concerns around environment variables being leaked (see the CodeCov vulnerability for example).

But beyond that, there's a cost to every additional way of specifying credentials - there's more complexity for customers to navigate, more to implement and ensure consistency across many platforms, more documentation to write etc. That means the benefit for "yet another way of specifying credentials" has to be really pretty significant before it's worth doing.

@svetlanama
Copy link

// .env
GOOGLE_APPLICATION_CREDENTIALS=<json_data_in_base_64>

.. usage

const credential = JSON.parse(
   Buffer.from(process.env.GOOGLE_APPLICATION_CREDENTIALS, 'base64').toString()
 );

 const storage = new Storage({
   projectId: process.env.GOOGLE_STORAGE_PROJECT_ID,
   credentials: credential,
 });

@googleapis googleapis deleted a comment from Xuantho78 May 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

4 participants