Basic Authentication for Google Cloud Stored Files - google-cloud-platform

I would like to store files on Google Cloud Storage and give devices access to the files via GET HTTP with basic authentication using username and password or something similar. Can this be done?

I will ask you a question to introduce my answer:
If you set a login/password in the basic authentication, which system will validate them?
Cloud Storage relies only on OAuth token. Nothing built-in, you have to build your custom authentication mechanism.
So, you need an additional service that check the credential and then provide a link to download the file.
I recommend you to
Create a serverless service, such as a Cloud Functions or a Cloud Run services
Perform a GET on it with your basic authentication to this service
The service check the authentication, you can use firestore database to store the credential/permissions/autorisations of the connected user
If the auth is OK, create a signed URL and return it with a 302 HTTP code (redirect)

Related

Does Google Cloud API support MFA/2VS authentication?

I wanted to know if GCP supports multi-factor authentication (MFA) or 2-Step Verification (2SV) for cloud API calls.
From this link: https://cloud.google.com/docs/authentication, I read the following:
"Google Cloud APIs only accept requests from registered applications, which are uniquely identifiable applications that present a credential at the time of the request. Requests from anonymous applications are rejected.
Application credentials provide the required information about the caller making a request to a Google Cloud API. Valid credential types include API keys, OAuth 2.0 client credentials, or service account keys."
However, it does not specify if I can use these factors simultaneously.
Thanks in advance,
Vijay

How to pass dynamic Google Cloud API Key to client side from server?

Currently, I am testing Google Cloud's Speech API and wondering how to pass dynamic Google Cloud API key to client app from server.
The speech function will be on client's app (React Native). Before every request to Google Cloud API or session, I am thinking to generate API key dynamically from server side (Nodejs) with a short lifetime and pass to client side. Only then, clients can use the Google service.
The main concern is that I do not want to embed Google Cloud API key on client app and I want to have control on which client can / cannot use the service. Is there a way to dynamically generate API keys on server side with short lifetime and pass to client? Thanks.
Update:
I was checking https://github.com/GoogleCloudPlatform/android-docs-samples/tree/master/speech/Speech and found the suggestion:
This Android app uses JSON credential file locally stored in the resources. You should not do this in your production app. Instead, you should set up your own backend server that authenticates app users. The server should delegate API calls from your client app. This way, you can enforce usage quota per user. Alternatively, you should get the access token on the server side, and supply client app with it. The access token will expire in a short while.
This is exactly what I want to do but can anyone suggest how can I achieve this? Thanks.
I am trying to find out how to get the API key for Step 2 on server backend side.
Never store credentials in users' browsers, luckily you are trying to adhere to this principle!
A setup that might be useful here has the following components:
Use an authentication mechanism in your client-side app, by means of an identity provider. You could use Okta, Auth0, Cognito, or any other authentication provider which supports Oauth2.
Use the same authentication provider to secure a custom-build endpoint, which could be a Google Cloud Function. This could be combined with Cloud Endpoints, but not necessarily.
In the same Cloud Function, after a user's identity is checked, you call the speech API.
The API key could be stored as a secret in Google Secret Manager.
The Cloud Function acts as a "serving hatch" to the API, passing back and forth requests from a user to the Google Cloud Speech API.
Your API key remains on the backend, stored as a secret. Users that are not authenticated using the authentication provider, will never have access to the Speech API.

Authorization in Google Cloud Endpoints for external clients

We are developing an API which is intended to be used by our external clients which are not inside Google Cloud.
It seems that Google Cloud Endpoints is a good candidate for such case.
What we need:
Client to be able to register in our "developer portal" to obtain necessary credentials.
To keep track of our clients (to see the number of requests of a particular client, to revoke his access to API, etc.)
The part which is not very clear to me is how to authenticate and identify our clients if they are not in Google Cloud.
We already use Firebase authentication by user email in one part or our application. It would be handy to continue using that authentication, but I am not quite understand how.
Google docs say that client application must send a JWT token. But what private key does it have to use to sign the JWT?
The second option to authenticate client we are thinking of is to use custom method to authenticate users. But I have the same question: What private key does the client application have to use to sign the JWT?
Is it intended that client generates its' own key pair?
If there are some better options for our use-case or if I am missing something, feel free to point me in the right direction.
You are on the right way!
With firebase, the JS library allow you to authenticate to the correct identity provider and the lib also allows you to generate a JWT. No private key needed here!
With custom method, it's different. Cloud Endpoint need to validate the signature of the JWT. For this, Cloud Endpoint need to know the public key of the private key used to sign the JWT. Most of time, it's provided by your own IdP system.
In your context, Firebase auth (or Cloud Identity Platform, if you want to manage your users on Google Cloud) is the best solution for you. With several customers, you can't register all their public keys, the only one solution is to have your own IdP and all your customer registered on it.
I have additional question: How do you plan to count the number of request per client? Through Cloud Endpoint or you own database?
We came up with a solution using custom method to authenticate users:
We implemented user authentication by email using firebase (as stated in my question).
Added a way for users to upload their public certificate to our "portal".
2.1. This was done using Google Cloud functions. Basically, we created a two endpoints:
2.1.1. to upload public certificate using firebase token.
2.1.2. to display all public certificates in JWKS format by some url (this way google is able to verify users JWT signature)
Published an instruction for users on how to form JWT to use our API (at this point every user have to have private key associated with their public key uploaded earlier).
Now users of our API are able to make API calls with JWT token provided.
Our technologies stack looks like following:
Cloud functions (for certificate handling).
Firestore (for authentication, storing certificates etc.).
Cloud Endpoints with ESPv2
Google App Engine standard environment

How to authenticate to GCP API with service account file

I am new user to GCP. I starting to implement an application that is going to use GCP API. In order to authenticate to API I've created service account and stored it in file.
In official documentation it is written that auth file can be assigned to environment variable: GOOGLE_APPLICATION_CREDENTIALS
I would like to make a request to google API from my http client (let's say Postman) and to use this file for authentication.
Is it possible at all or I suppose to use GCP client in order to make HTTP requests?
Yes, you can create an authenticate API key, and use that API key to call GCP API. Here is the doc for Creating and Using API key.
Also, you need to be careful not to expose your API keys to the public, like Github. Because we have seen many people just write their API key directly in the code and expose to the public.
As you said, you would like to use the API key in HTTP request, maybe you should add restrictions to your keys.
Here are some best practices that Google provided, hope this helps!

Getting Google IdToken for service account?

I have a backend that is serving android clients, authenticating them with IdToken sent from the android app.
Now, I need to authenticate a service running on aws that is using my apis. So I figured a service account would do the trick, using the private pem file to create a IdToken and send it along just as the android clients do. But I find no way of obtaining an IdToken with these credentials. Is this possible (preferrably in nodejs).
Or am I on the wrong path here?
I know this is older, but I found this question and it didn't lead me to the answer I ended up with.
I followed the guide in https://cloud.google.com/endpoints/docs/openapi/service-account-authentication#using_a_google_id_token with some mix of https://cloud.google.com/iap/docs/authentication-howto, which mentioned that the key to this was to include a target_audience claim in the generated JWT.
So, essentially I made a JWT that looked like:
{
"exp": 1547576771,
"iat": 1547575906,
"aud":"https://www.googleapis.com/oauth2/v4/token",
"target_audience": "https://example.com/",
"iss": EMAIL OF SERVICE ACCOUNT
}
and posted that to https://www.googleapis.com/oauth2/v4/token with params grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer and assertion=<THE JWT>
Without target_audience the endpoint gave me an access token, but with it I got an id_token instead.
Grettings since 2020
I had problems in Java for take ID_TOKEN of a Google Service Account. My project had two years and i were using GoogleCredentials, fromStream method and a JSON credential, but this class didn't gave me ID_TOKEN, only access_token on a not JWT format.
I solved because on this years Google updated here java code for authentication, for take ID_TOKEN you must use this library https://github.com/googleapis/google-auth-library-java
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-credentials</artifactId>
<version>0.20.0</version>
</dependency>
And then use ServiceAccountCredential
String credPath = "/path/to/svc_account.json";
ServiceAccountCredentials sourceCredentials = ServiceAccountCredentials
.fromStream(new FileInputStream(credPath));
When you create this class, itself will authenticate with google and have a access_token,refreshToken...
For extract ID_TOKEN you must use this function:
String audience = "http://localhost"; //Your server domain
IdToken idToken = credential.idTokenWithAudience(audience, new ArrayList<IdTokenProvider.Option>());
String id_token = idToken.getTokenValue();
And with this you have a JWT token.
I hope this help people like me,that are trying get ID_TOKEN.
You cannot use service accounts generated for Google Cloud APIs to directly authenticate against your own APIs. How will you know which service account private keys are valid and which have been revoked? Google does not expose this information.
Service accounts are rather meant for delegation of credentials. When you access Google Cloud platform service, you will be authenticating with your google account credentials. You will not want to provision the very same credentials everywhere your running code needs to access any of the Google cloud services (i.e. Cloud APIs). Instead you create service accounts whose scope can be reduced to a subset of the scope of your google account credentials. This way a particular piece of code can be limited to only a few set of APIs.
Service Accounts
A service account is a special account that can be used by services
and applications running on your Google Compute Engine instance to
interact with other Google Cloud Platform APIs. Applications can use
service account credentials to authorize themselves to a set of APIs
and perform actions within the permissions granted to the service
account and virtual machine instance.
What are service accounts?
Service accounts authenticate applications running on your virtual
machine instances to other Google Cloud Platform services. For
example, if you write an application that reads and writes files on
Google Cloud Storage, it must first authenticate to the Google Cloud
Storage API. You can create a service account and grant the service
account access to the Cloud Storage API. Then, you would update your
application code to pass the service account credentials to the Cloud
Storage API. In this way, your application authenticates seamlessly to
the API without embedding any secret keys or user credentials in your
instance, image, or application code.
I know where your confusion stems, it is because service account also have the same OAuth model you are used to.
You can use service accounts to get access tokens and refresh them as needed, but the scope of authentication is at the very maximum limited to the surface of the Google Cloud APIs. You will not be able to mix and match your APIs with that.
Alternative is to either build your own authentication model (which is not so clear from your question when you say authenticating them with IdToken sent from the android app) or rely on something like Cloud endpoints which you create and manage APIs along with API keys for authentication.
As you already mentioned in one of your comments, you can follow the Service-to-Service authentication guide which describes how you can use Google Cloud Service accounts to authenticate with your APIs running on Google Cloud Endpoint.
It supports using Google ID JWT tokens. The caller will have to send the JWT to Google Token endpoints to obtain a Google ID token and then use this Google ID token in all of your requests. This approach also has the advantage that you only have to whitelist the Google ID token server in your API configuration.