Restricting Google API Server to server service account key to be used with specific domains - google-api

Google API Server To Server service account key is a simple json or p12 file which can be compromised in some scenarios. Is there a way to limit its use to specific IPs or domains from Google Developer Console? The support topics there are not helpful at all.

No service accounts cant be restricted to IPs or Domains. Currently if you have the correct credentials then you can use them.
This is why you need to keep them safe. However that being said i think its a good idea. I am going to see if i can find someplace to add it as a feature request.
Note for openid signin
Signin returns an id token this id token can be verified verify the hd claim matches your domain name. Again this only works if you are authenticating with the openid scope.
Response from Google
I contacted one of the developers on Google identity this was his response.
IP restrictions had some value many years ago. Now, most of the apps are hosted in the cloud and traffic can move around the world thus making the IP restriction not very useful. If service account credentials are compromised, it is time to get a new credential or they were used in an incorrect way.

Related

Best way to access Google APIs without user authorization from desktop application

I am trying to make a desktop application with Twitch API and Google API.
Since this application requires Twitch user permission, a user needs to authorize my application through twitch's OAuth and I think there's no way to omit this process.
Now, I want to add some functionalities from Goole APIs, for instance TTS.
My application will be installed and run on user's local machine,
it cannot store API key or credential information safely.
I think I have three options:
Add Google OAuth: This is most safe way, I think, but I don't think I can convince users to authorize another Google account even though they already authorized their Twitch account.
Make a kind of proxy server which verifies request for Google API using twitch authentication information and relays request to/response from Google API. This seems feasible but it requires additional payment to running server for sending data from Google API. I already have to pay for TTS service, another payment for proxy server which sends binary data frequently would be a financial burden for me.
Make a server to acquire API key for Google API. This also requires additional server, but it does not involve lots of traffic because application will access Google API directly once API key acquired. However, I concern that the API key may be easily stolen using monitoring tool such as wireshark.
Which method should I use here, and how can I improve it?
Or, is there better way for this case?

Authenticating External System Connections to Web API with Azure AD

I'm trying to figure out how to migrate a system that is currently using ACS to Azure AD. I've read the migration docs provided by Azure and have looked through the Azure AD docs and the sample code but I'm still a bit lost as to what the best approach for my situation would be.
I've got a web API that has about 100 separate external systems that connect to it on a regular basis. We add a new connections approximately once a week. These external systems are not users--these are applications that are integrated with my application via my web API.
Currently each external system has an ACS service identity / password which they use to obtain a token which we then use to authenticate. Obviously this system is going away as of November 7.
All of the Azure AD documentation I've read so far indicates that, when I migrate, I should set up each of my existing clients as an "application registration" in Azure AD. The upshot of this is that each client, instead of connecting to me using a username and password, will have to connect using an application ID (which is always a GUID), an encrypted password, and a "resource" which seems to be the same as an audience URL from what I can see. This in itself is cumbersome but not that bad.
Then, implementing the authorization piece in my web API is deceptively simple. It looks like, fundamentally, all I need to do is include the properly configured [Authorize] attribute in my ApiController. But the trick is in getting it to be properly configured.
From what I can see in all the examples out there, I need to hard-code the unique Audience URL for every single client that might possibly connect to my API into my startup code somewhere, and that really does not seem reasonable to me so I can only assume that I must be missing something. Do I really need to recompile my code and do a new deployment every time a new external system wants to connect to my API?
Can anyone out there provide a bit of guidance?
Thanks.
You have misunderstood how the audience URI works.
It is not your client's URI, it is your API's URI.
When the clients request a token using Client Credentials flow (client id + secret), they all must use your API's App ID URI as the resource.
That will then be the audience in the token.
Your API only needs to check the token contains its App ID URI as the audience.
Though I want to also mention that if you want to do this a step better, you should define at least one application permission in your API's manifest. You can check my article on adding permissions.
Then your API should also check that the access token contains something like:
"roles": [
"your-permission-value"
]
It makes the security a bit better since any client app with an id + secret can get an access token for any API in that Azure AD tenant.
But with application permissions, you can require that a permission must be explicitly assigned for a client to be able to call your API.
It would make the migration a tad more cumbersome of course, since you'd have to require this app permission + grant it to all of the clients.
All of that can be automated with PowerShell though.

google marketplace multiple client_id

We are trying to put an app on the marketplace which needs multiple client_ids
(The app is running on appengine standard with python 2.7)
a client_id for the service_account with domain wide authority
a client_id for the web application
a client_id from an apps-script library
All client_ids use different scopes. I have combined all scopes and entered them on the marketplace SDK configuration.
When i deploy the app on a test domain, only the serviceaccount seems to be authorized.
When the user then access the webapplication he is presented a grant screen which we want to avoid.
The documentation https://developers.google.com/apps-marketplace/preparing?hl=fr seems to imply that multiple client_id's are possible.
How should i configure the marketplace app so that multiple client_ids are authorized?
Is there something special i should do on the credentials configuration page of the api-manager?
Check how you implement the authorization using OAuth 2.0, Service accounts allow a Google Apps domain administrators to grant service accounts domain-wide authority to access user data on behalf of users in the domain. You can also read Server to Server Applications documentation.
Note: You can only use AppAssertionCredentials credential objects in applications that are running on Google App Engine or Google Compute Engine. If you need to run your application in other environments—for example, to test your application locally—you must detect this situation and use a different credential mechanism (see Other). You can use the application default credentials to simplify this process.
Hope this helps.
It turned out all three client_id's were being authorized after all.
the days that i was testing this, it took very long for the authorization to take effect.
At this time all scopes and clientid are authorized within a few minutes.

Backendless.com Business Logic - Making an HTTP Request to Google Places API

I am using Backendless.com as a BAAS for my application. I have some custom logic running on their servers which need to make an HTTP request to the Google Places API.
I'm trying to generate an API key for the Backendless.com server to run this request but i'm not sure what API key I need to generate. The Google developer console gives me 4 options. Server Key, Browser Key, Android Key, & iOS Key.
Server key seems to be the one I want to use... but I need to provide it with some IP addresses... I don't know where or how to find those! The console states that they are optional, but it seems insecure to not add the server IP address. What are the risks? Where can I find Backendless.com app server IP's?
Server key is what you want. Restricting access is a good additional security step to take, it is not however required. They basically make it so that if someone manages to steal your API Key, they can't use it from IPs that are not whitelisted. You will have to ask backendless.com if they have a finite list of IPs they can gurentee your requests will come from.

Only allow access to my REST APIs from my own application?

We have a Windows app hosting a WebBrowser control that hits our REST APIs. We like to restrict access to the APIs to be only coming from withing the Windows app itself (for example, the APIs cannot be accessed in a browser, etc).
How can we accomplish that? what is the most secure way without having to expose any kind of credential (for example, if we use HTTP Basic auth, the username and password can be seen by reverse engineering the app itself)?
Thanks a bunch!
EDIT: We plan to distribute the application freely so we have no control over where the connection will be made from.
Restrict the REST interface to only accept connections from 127.0.0.1 (home) and then connect from your rest-consuming application only with http://localhost or http://127.0.0.1 in the URLs (if you use the external IP or DNS name of your machine it'll be treated as a remote connection and denied access).
You can do this with web server settings, or within the code of your REST APIs
I had a similar situation during a project where we distributed an iPhone app that also connected to a REST api that my team developed.
For security we used somewhat of a three-legged scenario. The app was required to authenticate using the user's credentials against a standalone service responsible only for authenticating and generating access tokens. Once the app received a valid access token, subsequent requests to the api required sending this token in the Authorization header.
You could do something similar. If you come up with a credential scheme to authenticate your app as valid API consumers you could use basic auth over HTTPS to obtain tokens, and then only by using those tokens could a consumer gain access to the rest of the API.

Resources