Three-legged OAuth2 scope verification issues for Angular & Firebase app - firebase

I'm trying to verify an app that manages a user's Firestore collections using Google Cloud APIs.
After submitting for verification, I received this email from the API dev team:
Dear Developer,
Thank you for submitting an OAuth App Verification request for the following Cloud scopes:
https://www.googleapis.com/auth/cloud-platform.read-only
https://www.googleapis.com/auth/cloud-platform
Three-legged OAuth2 scope grants are intended for human users to grant access to all of their data hosted on a particular API. Access to your requested OAuth2 scopes would provide overly broad access for Google Cloud Platform customers. Google Cloud Platform only supports grants to specific resources for specific users/services, with access controlled using Cloud IAM Policies.
Follow the instructions below to gain access to the Cloud scopes you requested:
Create a service account to represent your service and to access data from your users’ Google Cloud Platform project
Instruct your customers to grant your service account appropriate access to their Cloud data via IAM Policies
Note that you may want to create a service account for each customer to avoid confused deputy problems.
I already have 3 service accounts (I think they were created automatically by GCP or Firebase), but I'm having trouble understanding what the second point is and what action should I take.
The app makes requests from the client using my Firebase API Key to read and write on Firestore collections on the users' behalf. These are the scopes I'm using:
email
profile
openid
../auth/cloud-platform.read-only
../auth/cloud-platform
I expect the app verification process to complete successfully so the users don't see the "Unverified application" screen when logging in.

You are trying to grant yourself access to a customer's account/data using your Project's OAuth Client ID. This is very dangerous as you can receive an Identity Token and Refresh Token that can make it difficult for a customer to revoke your Access Token. Most customers/developers do not know how to do this.
Google is tightening the level of access that you can request. You have asked for permissions that are too privileged. The correct approach is for the customer to grant you access to their account via Google Cloud IAM. These privileges can be to a service account created by your Google account or to your Google Account email address. Both methods require the customer to grant permissions in their GCP account using IAM.
Your problem can be solved in three steps:
1) Delete the following scopes as Google will not approve your app with them without an audit.
cloud-platform.read-only
cloud-platform
Note: If you only require access to a very specific service, change the scope for that service. You might not get approved.
2) Create a service account in your Google Cloud Platform account. Provide the email address of your service account to each customer. They will need to add the email address to the Google Cloud Platform console under the IAM section and assign the required IAM permissions.
Note: You may want to create one service account per customer for better security, separation, and logging.
3) Use the service account instead of a Client Application.
Note: If you require Google Console access to your client's Google Cloud Platform account, provide them with your Google Account email address. They can assign your email address the required permissions to access the console for their project.

Related

How to get the access for the identity platform users to acces the cloud function in GCP

I'm new to GCP, i found that identity platform is similar to cognito userpool in AWS. So that I have created few users in Identity platform (GCIP), able to authorize them with firebase script provided. I'm able to get the access token for the valid user present in Identity platform. By using that token I'm unable to access the Authorised cloud function.
Please suggest the steps to access the authorized cloud function for the users who are there in Identity platform.
You need to use an identity token not an access token.
See e.g. Authenticating for Developer Testing.
This is a little confusing with Google Cloud services where some accept access token and others require identity tokens.
Please include your attempts to solve a problem for yourself in your question. As you've seen, general "How do I?" questions will be downvoted and eventually closed.

How do Google OAuth 2.0 Scopes for Google APIs differ from roles and permissions in an IAM on Google Cloud?

I am trying to decipher the meaning "scopes" in the following error message from Error: Could not load the default credentials. context: firebase login:ci AND firebase auth:export:
[2021-04-27T20:48:23.188Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
[2021-04-27T20:48:26.208Z] Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
at GoogleAuth.getApplicationDefaultAsync (/home/node/.npm-global/lib/node_modules/firebase-tools/node_modules/google-auth-library/build/src/auth/googleauth.js:160:19)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at runNextTicks (internal/process/task_queues.js:66:3)
at listOnTimeout (internal/timers.js:518:9)
at processTimers (internal/timers.js:492:7)
at async GoogleAuth.getClient (/home/node/.npm-global/lib/node_modules/firebase-tools/node_modules/google-auth-library/build/src/auth/googleauth.js:502:17)
at async GoogleAuth.getAccessToken (/home/node/.npm-global/lib/node_modules/firebase-tools/node_modules/google-auth-library/build/src/auth/googleauth.js:524:24)
Error: An unexpected error has occurred.
If I understood what "scopes" are I might be able to figure out where to set them. So far I have only found a place to set roles and permissions in the IAM for my user.
Here are the definitions I could find:
roles & permissions (source)
A role contains a set of permissions that allows you to perform
specific actions on Google Cloud resources. To make permissions
available to members, including users, groups, and service accounts,
you grant roles to the members.
scopes (source, source)
Access scopes are the legacy method of specifying permissions for your
instance. They define the default OAuth scopes used in requests from
the gcloud tool or the client libraries.
The error message arose when I tried to run firebase --debug auth:export using an OAuth token generated by firebase login:ci and applied in my script with firebase use --token. The OAuth token was generated with the Google user id that owns my Firebase project. That user has role "Owner" on the Google Cloud IAM page (i.e. https://console.cloud.google.com/iam-admin/iam).
How do I set the required scopes for my Google user id when the Google Cloud IAM page only allows you to set roles and permissions?
I'm not familiar with Firebase, but I do recognize this:
Error: Could not load the default credentials
This is telling you that no (application) default credentials were found. You can generate default credentials using a Google user account by executing:
gcloud auth application-default login
There's also other options. I wrote a whole blog post on application default credentials that you may find interesting.
To give you an answer to your other question, I'm afraid I'm going to get a bit wordy...
OAuth
Scopes are a term from OAuth; scopes are not specific to GCP or even to Google. OAuth is a protocol for authority delegation and is in wide use all over the internet. Understanding OAuth fully is not trivial.
The "parties" that OAuth concerns itself with are:
resource (the GCP service you're trying to access),
end-user (you, Michael)
authorization server (Google account service) and
client (in this case, the firebase CLI; the program you want to act on your behalf).
The problem that OAuth concerns itself with is the following: You, as the end-user, have the authority to act on the resource. You want a client to be able to act on the resource on your behalf. To do this, you log in with the authorization server, and get a secret token to the client; how to do this specifically is defined in detail in the OAuth spec. The resource recognizes anyone who possesses such a token as "speaking" on behalf of the end-user. By handing the client a token, you're "delegating" your end-user authority to the client.
Scopes
Anyway... Where to scopes come in? In interactions like the above, you do not necessarily want to delegate all the authority that you carry at the resource to the client. Therefore, you can bind a "scope" to the token. The scope tells the resource that the token bearer may not perform everything on behalf of the end-user, but only certain actions. What specific scopes mean is not defined by the OAuth protocol. Scopes are free-form strings, and it's the resource that should know how to interpret them.
IAM
IAM, on the other hand, is what defines the end-user's authority at the resource, that is, it defines what a Google account can do when it comes to handling GCP resources. Naturally, you a Google account cannot delegate authority to a client that it itself does not have, even if it can create tokens with very broad scopes.
If Google receives a request to, say, start a GCE instance, it will first check if the request is signed by a valid, trusted token with sufficient scopes. If the check passes, Google checks if the end-user that's "backing" the token actually has the authority to perform the requested action using IAM.
In your example above: you're the OWNER, so you have plenty of IAM permissions. However, if the token you generated does not include appropriate scopes, that token does not carry that authority, and the requests sent by firebase to GCP will not pass the first check.
Legacy?
The concept of scopes is not legacy, but the way in which GCP uses scopes to regulate processes' permissions is.
In the past, processes on GCP often ran using generic identities with very broad (IAM) permissions, such as the default compute account. The processes' permissions were limited by scoping the tokens generated for them.
IAM is much more powerful and can be defined at a more granular level as scopes. Nowadays we define custom identities with minimal permissions for different processes. Given appropriate IAM permissions, we can simply create tokens with very broad scopes, such as https://www.googleapis.com/auth/cloud-platform.

Is there any way to directly login users to firebase via google assistant? And if not is there any plan to implement that in future? #askfirebase

I'm creating an app that will run on the Google Assistant which should use firebase authentication to authenticate the user and then perform some user specific stuff.
It isn't currently possible for a user's Assistant account to automatically be linked to a Firebase Authentication account. You can create a basic OAuth2 server that uses Firebase Authentication to identify them as part of the Assistant Account Linking procedure, but this isn't done automatically. Once they have done the account linking, your Action will get an auth token (that your OAuth2 server has issued) and can use this to get a valid token to work with Firebase on their behalf.
Google doesn't typically announce future plans, however there have been a number of requests for similar features.

What's the difference between api key, client id and service account?

I needed to access a Google's service, i.e. Google Analytics, from my Symfony 2 application, so I had to use the Google api client (version 2). Before accessing Google Analytics' info, I had to create either a api key, a client id or a service account in the Google API Console.
At the end, I created a service account, and a file was downloaded. This file is used by the Google api client to grant access to my Google Analytics account and its respective collected info.
My question are:
What are the differences between api key, client id and service account?
When to create/use one over the other, and why?
I've not seen any exhaustive article which explains what I'm asking in this question.
This thread is old, but still adding the information. Might help others in future.
Google needs unique identifier to tie it to your project (with your android package) for authentication and to manage traffic or quotas.
Oauth and API key are such unique identifiers.
OAuth 2.0 client IDs: If your application is using OAuth 2.0 protocol, then use OAuth client ID.
OAuth is used to create the Access token, which in turn is a unique identifier. However, the user needs to agree a consent.
https://developers.google.com/identity/protocols/OAuth2
API keys: An API key is a unique identifier that you generate using the console. The advantage is the user does not require an user action or consent. But you cannot use the API key for authorization unlike OAuth. Use an API key when the data you want is public and does not need a user authentication, such as Google maps.
Service Account : Google APIs such as the Prediction API and Google Cloud Storage can act on behalf of your application without accessing user information. In these situations your application needs to prove its own identity to the API, but no user consent is necessary. Similarly, in enterprise scenarios, your application can request delegated access to some resources.
For these types of server-to-server interactions you need a service account.
https://developers.google.com/identity/protocols/OAuth2#serviceaccount
The API keys authenticate for APIs that do not access personal data.
The client id authenticates with your Google Account.
The service account authenticates your application when you do not want to use the login data of your own account (or any real persons account).
You still need to add the service account to any Google service you want to access with that service account.

Web API not recognizing new users when created by Web Portal

I have a Web API and an Azure Web App that access the same database. This database has all user information. I'm using ASP.NET Identity for user management. I'm having an issue where when a user is created by the web app the Web API requires a restart, or at least a relatively long while before the user becomes authenticated by it. This, of course, is entirely impractical. How can I update the environment immediately on the Web API so that the user can access their resources?
UPDATE 3:
Turns out it WAS authenticating with the API, but I didn't hold the correct claims because my user was not associated with a Google account. See Answer below.
Wow. Nevermind. We require Google accounts to sign on one kind of client, and we SHOULD require it on the web client, but I haven't set that up yet. If an account is set up without an associated Google account, AND that email has a Google account set up on the client then it will try to authenticate with those Google claims that don't exist in the DB. So while I CAN authenticate with that claim through the Google SSO, there are no claims set up in the DB, resulting in 401 errors. Authenticated, but unauthorized.
This means my auth filter is probably misconfigured because it should not authenticate with Google if my account does not have an associated Google account, no matter what my client requests. It also means that I need to refactor my SPA on my Web App that statically calls for Google authentication with the API.

Resources