Use Google Storage Transfer API to transfer data from external GCS into my GCS - authentication

I am working on a web application which comprises of ReactJs frontend and Java SpringBoot backend. This application would require users to upload data from their own Google Cloud storage into my Google Cloud Storage.
The application flow will be as follows -
The frontend requests the user for read access on their storage. For this I have used oauth 2.0 access tokens as described here
The generated Oauth token will be passed to the backend.
The backend will also have credentials for my service account to allow it to access my Google Cloud APIs. I have created the service account with required permissions and generated the key using the instructions from here
The backend will use the generated access token and my service account credentials to transfer the data.
In the final step, I want to create a transfer job using the google Storage-Transfer API. I am using the Java API client provided here for this.
I am having difficulty providing the authentication credentials to the transfer api.
In my understanding, there are two different authentications required - one for reading the user's bucket and another for starting the transfer job and writing the data in my cloud storage. I haven't found any relevant documentation or working examples for my use-case. In all the given samples, it is always assumed that the same service account credentials will have access to both the source and sink buckets.
tl;dr
Does the Google Storage Transfer API allow setting different source and target credentials for GCS to GCS transfers? If yes, how does one provide these credentials to the transfer job specification.
Any help is appreciated. Thanks!

This is not allowed for the the GCS Transfer API unfortunately, for this to work it would be required that the Service Account have access to both the source and the sink buckets, as you mentioned.
You can try opening a feature request in Google's Issue Tracker if you'd like so that Google's Product Team can consider such a functionality for newer versions of the API, also you could mention that this is subject is not touched in the documentation, so it can be improved.

Related

How to allow authenticated Identity Platform user to upload to Cloud Storage from web

I am not able to use Firebase Storage however I am using Identity Platform (firebase auth). Once a user is logged in to my web application, I would like them to be able to upload to a Cloud Storage bucket. The current way I am thinking about doing this is by have a Cloud Function which first uses firebase admin library to verify the token of the user and then generates a signed-url for the upload.
Is this the correct method for doing this?
Google Cloud Identity Platform uses the same SDKs and most of the same back-end as Firebase Authentication. The main difference in is the set of features it supports, and its pricing model.
If your project is set up for using Cloud Identify Platform, you can still use the Firebase SDKs for Cloud Storage to upload, and use Firebase's server-side security rules to control read/write access for it. A common security model to get started with is content-owner only access.

GCP external application to app-engine endpoint authentication

We are building a small web-UI using React that will be served up by GCP App-Engine (standard). The UI will display a carousel of images along with some image metadata to our client's employees when they click on a link inside of their internal GIS system. We are looking to authenticate these calls since the App-Engine endpoint will be exposed publicly, and are hoping to use a GCP Service Account private key that will be used by the client to create a time-limited JSON web-token that will give temporary access to the GIS user when they open the web-UI. We are following this GCP documentation. In summary:
We create a new service-account with necessary IAM permissions in GCP along with a key
We share the private key with client which they then use to sign a Json Web Token which is passed in the call to our endpoint when user accesses our web-UI from their GIS system
Call is authenticated by GCP backend (ESP/OpenAPI)
Question: is this a recommended approach for external system accessing GCP resources or is there a better pattern more applicable to this type of situation (external system accessing GCP resource)?
I believe this is the recommended approach for your use case.
According to the official documentation:

Google BigQuery authentication

I want to use Google BigQuery authentication like other Google services (for example, Google sheet).
The auth of Google sheet works on the scope and makes appear to the user a popup like "The app XXX request the access to your Google Account" and in this popup, you can see what permission needed by the app.
I would the same auth with Google BigQuery but after I read the docs, looks the code of official PHP client, I can't understand how to make this auth. Is this possible?
P.S. Obviously I tried the flow in the google docs with generated JSON from google developer console and it works fine.
What you want to do is not possible. At least in the way you would like.
When using, let's say, "native" GCP products, the OAuth authentication is performed automatically after logging in. This is why you don't are prompted to identify yourself when accessing to your GCS buckets, or when getting into the App Engine Dashboard.
When you want to grant access to an external user to your project, you run the command gcloud auth login. An authorization screen is shown like the one below:
This screen is also shown to "non-native" GCP services, such as BigQuery Geo Viz, Dialogflow, etc. You are prompt to grant access since these are "external" GCP features which interacts with your project's internal info.
BigQuery is an integrated GCP service and does not requires OAuth authentication when used via the UI.
If you would like to interact with the BigQuery API's, I highly recommend you to use the BigQuery Client libraries which do the authentication method much easier.
However, there is a way to grant access to external users. I found the Authorizing API requests doc where it's said that you can get a temporal access token for external users. This is done by following these steps:
Run the command gcloud auth application-default print-access-token in a Cloud Shell session.
Copy the output and paste it in a HTTP request like
https://www.googleapis.com/bigquery/v2/projects/$GOOGLE_CLOUD_PROJECT/datasets?access_token=ACCESS_TOKEN
Note that this could lead to even more effort than the required for Client libraries.
Hope this is helpful.

Authenticate client-side app with Google Cloud Platform

I am currently developing a client-side app where users login using e-mail/password against MongoDB Atlas. The backend runs completely serverless.
All logged in users should be able to upload and retrieve images from GCP - Storage bucket without a visible login, which means the application should authenticate for every user on the background.
I was thinking about using Google Service Accounts in combination with auth0, but I don't know where to start...
If someone could help me tell where to start, that would be great :)
The question is difficult to answer. However, here some insights.
The prefered way is to have a serverless backend, AppEngine standard, Cloud Run or Cloud Function for doing this. The user performs its authentication and then exchange security token between the frontend and the backend. When the user want to reach a GCP resource, it asks the backend, which request the request thanks to its own service account.
By the way, it's easy to trace the user request and to serve him only the resources related to it. And you have only 1 service account, for the backend
If you grant access to a bucket to a user, it could download all the files (But maybe there is one bucket per user?). If you chose to limit object access with ACL, the management is complex.
You don't need to have a service account per user (and in any case, you have a quota to 100 service accounts per project), you can use Cloud Identity Platform (CIP) instead of your MongoDB database for authentication (CIP don't perform authorization, you should use MongoDB for authorization and other stuffs related to authenticated user). CIP is Firebase Auth rebranded

Long lived key/token based way to download google storage bucket objects with curl?

O.k. my fellow devops and coders. I have spent the last week trying to figure this out with Google (GCP) Cloud Storage objects. Here is my objective.
The solution needs to be light weight as it will be used to download images inside a docker image, hence the curl requirement.
The GCP bucket and object needs to be secure and not public.
I need a "long" lived ticket/key/client_ID.
I have tried the OAuth2.0 setup that Google's documentation mentions but everytime I want to setup an OAuth2.0 key it I do not get the option to have the "offline" access. AND to top it off it requires you to put in source URL's that will be accessing the auth request.
Also Google Cloud Storage does not support the key= like some of their other services. So here I have a an API KEY for my project as well as an OAuth JSON file for my service user and they are useless.
I can get a curl command to work with the temp OAuth bearer key but I need a long term solution for this.
RUN curl -X GET \
-H "Authorization: Bearer ya29.GlsoB-ck37IIrXkvYVZLIr3u_oGB8e60UyUgiP74l4UZ4UkT2aki2TI1ZtROKs6GKB6ZMeYSZWRTjoHQSMA1R0Q9wW9ZSP003MsAnFSVx5FkRd9-XhCu4MIWYTHX" \
-o "/home/shmac/test.tar.gz" \
"https://www.googleapis.com/storage/v1/b/mybucket/o/my.tar.gz?alt=media"
A long term key/ID/secret that will allow me to download a GCP bucket object from any location.
The solution needs to be lightweight as it will be used to download
images inside a docker image, hence the curl requirement.
This is a vague requirement. What is lightweight? No external libraries, everything written in assembly language, must fit in 1 KB, etc.
The GCP bucket and object needs to be secure and not public.
This normal requirement. With some exceptions (static file storage for websites, etc) you want your buckets to be private.
I need a "long" lived ticket/key/client_ID.
My advice is to stop thinking "long-term keys". The trend in security is to implement short-term keys. In Google Cloud Storage, seven-days is considered long-term. 3600 seconds (one hour) is the norm almost everywhere in Google Cloud.
For Google Cloud Storage you have several options. You did not specify the environment so I will include both user credentials, service account, and presigned-url based access.
User Credentials
You can authenticate with User Credentials (eg username#gmail.com) and save the Refresh Token. Then when an Access Token is required, you can generate one from the Refresh Token. In my website article about learning the Go language, I wrote a program on Day #8 which implements Google OAuth, saves the necessary credentials and creates Access Tokens and ID Tokens as required with no further "login" required. The comments in the source code should help you understand how this is done. https://www.jhanley.com/google-cloud-and-go-my-journey-to-learn-a-new-language-in-30-days/#day_08
This is the choice if you need to use User Credentials. This technique is more complicated, requires protecting the secrets file but will give you refreshable long term tokens.
Service Account Credentials
Service Account JSON key files are the standard method for service-to-service authentication and authorization. Using these keys, Access Tokens valid for one hour are generated. When they expire new ones are created. The max time is 3600 seconds.
This is the choice if you are programmatically accessing Cloud Storage with programs under your control (the service account JSON file must be protected).
Presigned-URLs
This is the standard method of providing access to private Google Cloud Storage objects. This method requires the URL and generates a signature with an expiration so that objects can be accessed for a defined period of time. One of your requirements (which is unrealistic) is that you don't want to use source URLs. The max time is seven-days.
This is the choice if you need to provide access to third-parties to access your Cloud Storage Objects.
IAM Based Access
This method does not use Access Tokens, instead, it uses Identity Tokens. Permissions are assigned to Cloud Storage buckets and objects and not to the IAM member account. This method requires a solid understanding of how Identities work in Google Cloud Storage and is the future direction for Google security - meaning for many services access will be controlled on a service/object basis and not via roles that grant wide access to an entire service in a project. I talk about this in my article on Identity Based Access Control
Summary
You have not clearly defined what will be accessing Cloud Storage, how secrets are stored, if the secrets need to be protected from users (public URL access), etc. The choice depends on a number of factors.
If you read the latest articles on my website I discuss a number of advanced techniques on Identity Based Access Control. These features are starting to appear on a number of Google Services in the beta level commands. This includes Cloud Scheduler, Cloud Pub/Sub, Cloud Functions, Cloud Run, Cloud KMS and soon more. Cloud Storage supports Identity Based Access which requires no permissions at all - the identity is used to control access.