Google APIs can have usage limits, both on a per-user and a per-application basis. For example, the GMail API free tier is limited to a billion daily quota units across all users of your application.
This works for well-designed server-side applications, which can centrally ensure they obey these usage limits. However, I’m not sure how this is supposed to work for client-side apps. As Google’s documentation says,
Installed apps are distributed to individual devices, and it is assumed that these apps cannot keep secrets.
These apps are still supposed to use a client_secret and credentials, but these are assumed to not be confidential despite the name. However, just saying they aren’t secret doesn’t prevent abuse; a user of the app can take the credentials file and use it for a different purpose, perhaps one that uses the APIs more. What can an application developer do to prevent people doing this from burning through all the available quota?
Edit for clarification:
The use case that prompted this is a purely desktop app that doesn’t connect to any service except GMail (see https://github.com/mbrt/gmailctl/issues/48). If it weren’t for a global quota for all users of the app, there would be no reason to worry about individual users at all; they don’t connect to any service except GMail itself.
You could write a server app (a Cloud Function would work) which holds the secrets. Clients call your endpoint with some form of identifier and you return an Access Token. If your users have a browser, they can auth each time; if not you would need to request a Refresh Token which you store and use that to generate an AT.
Related
I am working with Google Firestore in native mode and CRUD'ing data within it using the "cloud.google.com/go/firestore" api in Go. Access to the data is wide open as long as you know the project id and using the Firestore API on a server. I don't want to try the rules until I figure out how to secure the data from server attacks that. Again, all the API requires is the project id to access the data so I need to lock that down firstly before I move any further. Rules are only for mobile/web clients from what I read and Server side clients completely bypass the rules. Please help. I do not want to use the Firebase API because attackers can still use the Firestore api to access the data.
It's unclear from the limited information in your question but, your Firestore database is not open to anyone with the Project ID.
The service is only accessible to any thing (human|machine) that has valid credentials. Either humans with e.g. Gmail accounts or Service Account key holders.
In either case, only identities that you've explicitly added to the project will be able to access its resources and then only those with the appropriate IAM roles|permissions.
Google provides an elegant facility called Application Default Credentials (ADCs) that simplifies authenticating clients.
I suspect that your code is using ADCs to authenticate you to the project|service.
Access to the data is wide open as long as you know the project id and using the Firestore API on a server.
If that is a concern, consider disallowing all access in the Firebase security rules for your Firestore database.
Also have a look at my answer here to understand why sharing your project ID is not a security concern, and in fact is necessary if you want to allow direct access from client-side devices: Is it safe to expose Firebase apiKey to the public?. If you don't want to allow direct client-side access, closing down the security rules (as they are by default, unless you choose test mode when creating the database) is the way to go.
I have a Teams application (Tab). I am an ISV provider, and provide a multi-tenant application that is installed by customers via Teams App Store in their organizations.
How do I save settings for my application organization-wide for the customers? For example, CustomerA has installed the app and then CustomerB. I want some storage that would be unique for CustomerA and CustomerB and the app, and located in customer's environment. The settings I want to save are not per-user, but per-organization (tenant).
Somewhat similar to "App Data" folder you have in Windows Desktop for example.
Does such a storage exist? Does API for this storage exist?
A tab app is a simply a web application that you render inside of Teams. As a result, what the app does, and where and how it does it, is totally up to you. This includes any data storage you choose to have behind the scenes. For example, your tab could be built in PHP and use MySQL, or built in ASP.Net and use SQL Azure or CosmosDB. It's totally up to you, but you need to implement it yourself, as an ISV.
The important piece to differentiate clients, however, is being aware of the TenantId for each user, so you can look up which client's settings you need from the database. The most simple way to do this is simply the tid property on the Teams tab context. You can read more about that here. Unfortunately, because it's just accessed via Javascript, it's not entirely secure - for a more secure mechanism, you should be creating an Azure Application, and generating jwt tokens that you can authenticate against in your backend. It's a much more complex topic, but hopefully this answer at least gives the background you need. For more info on the security aspects (validating the token etc.), please see this question: How to restrict access to Azure Function to only allow requests from a custom Microsoft Teams App?.
Google started the OAuth developer verification process a few months back which forces the developers having OAuth applications to apply for verifications if they don't want their users to see a warning screen and to have an unlimited number of users using the OAuth flow.
I'm facing a problem due to this verification process when I have to use the projects in a local environment. There is no way I can verify the apps for local environments since the policies and T&Cs cannot be hosted.
Q1. Is there any way to skip the verification process and sandbox the OAuth application?
Q2. What is the exact limit for the accounts? (Since I use 5-10 Gmail accounts, but do multiple signups per day from those accounts and I still hit the limit quite often)
Q1. Is there any way to skip the verification process and sandbox the OAuth application?
If you check the side of the consent screen it answers some of your questions.
you can learn more here
Q2. What is the exact limit for the accounts? (Since I use 5-10 Gmail accounts, but do multiple signups per day from those accounts and I still hit the limit quite often)
If you add these accounts as users on the project in the developer console they should be able to use it while you are testing.
I have a .NET console application that performs operations on files. I would like to allow clients to give us access to their Google Drive accounts so we can read and write files. Our console application runs as a service so there is no way for the user to interact with it and authorize our access to their Google Drive account.
I was looking at using a Google Service Account for application level authentication until I learned that a Service Account does not have access to the Google Drive folder of the user that sets up the Service Account. This sort of defeats the purpose because it is the client's Google Drive account I am looking to gain access to.
I saw a workaround posted by SO member #pinoyyid posted in this SO answer where the refresh token can be generated using Google's Oauth2 Playground, but I am concerned that the refresh tokens could expire and user intervention would be needed again to generate another one.
Another response mentioned the solution was to create the Service Account and then share the user's Google Drive account with the Service Account.
What is the recommended approach by Google? How best to gain access to a Google Drive account while only requiring the owner to authenticate on a one-time basis, yet allowing them the ability to revoke access at any time?
Both Service Account and a stored OAuth Refresh Token are viable approaches. Each has its pros and cons.
A Service Account will work where your users only need to grant access to a specific folder which they can share to the SA. Be aware that any files the SA creates are owned by, and consume quota of, the SA. You can't "share the user's Drive account to the SA", you can only share individual folders.
Storing a RT is the more permissive option. You wouldn't use the OAuth playground as described in my answer that you referenced as that's far to clunky to ask users to go through. Instead you would need to write your own registration/authorisation service (you can use AppEngine, Lambda, etc - so it's not difficult to write and host).
I'm currently building a RESTful API to our web service, which will be accessed by 3rd party web and mobile apps. We want to have certain level of control over API consumers (i.e. those web and mobile apps), so we can do API requests throttling and/or block certain malicious clients. For that purpose we want every developer who will be accessing our API to obtain an API key from us and use it to access our API endpoints. For some API calls that are not dealing with the specific user information, that's the only required level of authentication & authorization, which I call "app"-level A&A. However, some API calls deal with information belonging to the specific users, so we need a way to allow those users to login and authorize the app to access their data, which creates a second level (or "user"-level A&A).
It makes a lot of sense to use OAuth2 for the "user"-level A&A and I think I have a pretty good understanding of what I need to do here.
I also implemented OAuth1-like scheme, where app developers receive a pair of API key & secret, supply their API key with every call and use secret to sign their requests (again, it's very OAuth1 like and I should probably just use OAuth1 for that).
Now the problem that I have is how to marry those two different mechanisms. My current hypothesis is that I continue to use API key/secret pair to sign all requests to be able to access all API endpoints and for those calls that require access to user-specific information apps will need to go through OAuth2 flow and obtain access tokens and supply them.
So, my question to the community is - does it sounds like a good solution or there are some better ways to architect this.
I'd also appreciate any links to existing solutions that I could use, instead of re-inventing the wheel (our services is Ruby/Rails-based).
Your key/secret pair isn't really giving you any confidence in the authorship of mobile apps. The secret will be embedded in the executable, then given to users, and there's really nothing you can do to prevent the user from extracting the key.
In the Stack Exchange API, we just use OAuth 2.0 and accept that all we can do is cutoff abusive users (or IPs, in earlier revisions without OAuth). We do provide keys for tracking purposes, but they're not secret (and grant nothing of value, so there's no incentive to steal them).
In terms of preventing abuse, what we do is throttle based on IP in the absence of an auth token, but switch to a per-user throttle when there is one.
When dealing with purely malicious clients, we unleash the lawyers (malicious in our case is almost always violation of cc-wiki guidelines); technical solutions aren't sophisticated enough in our estimation. Note that the incidence of malicious clients is really really low (single digits in years of operation, with millions of daily API requests).
In short, I'd ditch OAuth 1.0 and switch your throttles to a hybrid of IP and user based.