What is the correct way to protect Google API key for Places service? - google-maps

First of all I want to use Google Places API for autocomplete. I have created API key and it works fine. I make api calls from client so I need to protect or restrict it. I tried to use HTTP restriction, but it doesn't work with Places API. There are recommendation in the docs to use IP restriction but it requires that some proxy server to make api calls. So which way is right? Do I need proxy server with IP restriction to make api calls? Or is there some way to make secure api calls from client?

Normally, when you are calling the requests from the Client-Side, it should be restricted via HTTP referrers, and IP address restrictions are used when you are calling the requests from the server-side which has a static IP address. If you're calling from the Client-Side and your HTTP restrictions are not working, it will be best to file a support case via https://console.cloud.google.com/google/maps-apis/support in order to open personalized communication channel as this must be an isolated case and might have something to do with your configuration in your GCP console.
I would also recommend to check the sample HTTP restriction below:
example.com
*.example.com
These two will allow your API key to be used in all subdomains and paths in your website.

Related

To authenticate the client that invokes Google cloud function in Java

I have a google cloud function in Java.
Client will invoke the function using HTTP trigger URL.
But that is not secure. I have gone through some docs saying that you should pass a token or client ID and then verify it in server side.
Can anyone explain that in detail and please provide a code example if any.
My doubt is to authenticate the client while they invoke the function using Http trigger
This page explains quite well all the capacity that you have to authenticate a requester on Cloud Functions.
If you have users, the best way is to use Firebase Auth (our Google Cloud Identity Platform which is simply a more advance solution than Firebase Auth with more features)
However, you need to grant all you user with cloudfunction.invoker role, to allow them to invoke the Cloud Functions. It could be difficult. You can also perform the check on your side, but in this case you remove the security (filter) layer of google and you have to check all the traffic by yourselves (not really safe, in term of billing and in case of attack).
The latest solution, API keys, is not recommended, especially for the users. But for machine to machine it's sometime the only solution. However, there isn't out of the box solution and for this I wrote an article, that explains how to create a Cloud Endpoint (or now a Cloud API Gateway which is the serverless solution of Cloud Endpoint with ESPv2) to accept API Keys.
With this latest solution, if you change your security definition, you can also accept OAuth2 tokens coming from Firebase Auth (or Cloud Identity Platform), but this time, you don't need to grant all the users on your Cloud Functions IAM role. The token only need to be valid and it's the Cloud Endpoint service account which is used to perform the call (and thus which needs to be authorized on the Cloud Functions).
In addition, because you can accept OAuth2 token, you can also accept non Google token, and thus have your users in any IDP OAuth2 compliant (KeyCloak, Okta,...)
You could use external OAuth server like keycloack (https://github.com/keycloak/keycloak), or use somethging like Json Web Tokens -- https://jwt.io/ -- available for various languages, siutable for microservices.

will google cloud functions 'always' be available via http?

Maybe a strange question, but how long will google support http on cloud functions. Be default the https version of a cloud function will be used ofcourse.
But some IoT devices aren't able to create a secure connection and can only send (already encrypted) data straight to an IP addresses or http urls.
A static IP address pointing to a cloud function is not supported, but I do can send GET requests to the http version of a cloud function endpoint.
The only big thing is: If Google will ever redirect http to https, data will not come in anymore.
Regards, Peter
Your question seems to be asking about the future of Cloud Functions. There is no public roadmap for the development of Cloud Functions, so it's not really possible to say with certainty whether or not HTTP support will ever go away. I suggest contacting Google Cloud support directly if you need a more definitive answer.

How to secure my api key?

I want to use from my android/ios app the autocomplete api. For this I need to call url like:
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=paris&key=<myapikey>
the problem is: What can make that someone else will not extract from my app my api key and use it for his own purpose ? It's important because at the end it's me who will be billed by google for the usage ...
Your intention is to call a Places API web service. Google Maps web services support only IP address restrictions.
You can check what type of restriction is supported by each API on the following page:
https://developers.google.com/maps/faq#keysystem
In order to protect an API key that is used with your sample request you should create an intermediate server and send your requests from this server. So your application should send request to intermediate server, intermediate server should send Places autocomplete request with protected API key to Google and pass response back to your app. In this case you can use an IP address of your intermediate server to protect unauthorized access with your API key.
I hope this helps!
What if you create and intermediate server and create a token for each single user, and also create a monitoring service which block suspicious behavior?
for example, a normal user would request x times/per day || hour || ...
Or
when a user runs application for the first time, application receives the [encrypted api + decryption key] and store them to a safe place like keychain(for iOS)
As I know, if you request directly to google-map-api there is always a way to sniffing packets.

Google maps API key HTTP restriction causes 403 error in geocoding API

I receive a 403 error in google maps API dashboard for the geocoding API after limiting the key to my domain. The geocoding works when the key is unrestricted. Currently I have the following as acceptable HTTP referrers:
https://website.com/*
https://www.website.com/*
This allows my basic javascript map and autocomplete forms to work on HTML pages. However, the geocoding is done through a python script that accesses website.com/markers (has no HTML page, just displays JSON data if you visit it). Is there a reason it will not work? The 403 error is what I see in the API dashboard, but I receive an internal server error message when visiting website.com/markers. When unrestricted, the dashboard shows response code 200 and I can see the correct JSON data. Therefore, I believe my code is not the issue.
Things I have tried:
Allowing “https://website.com/markers” as a referrer, as well as www. version of that, and http versions. Also used versions without http or https.
Changing to allow IP address of website (referrer not allowed error happens when I do this)
Double checking all references to API key in code. Code works in development and in production when unrestricted.
Double checked that all needed services are enabled in Google api console and not over quotas.
I have searched for this issue for hours and cannot find an answer, please go easy on me if I have overlooked something simple.
It sounds like you're trying to use the method of URL restriction intended for use with client-side web api's. In that case, the public URL of the site is used in the validation.
You want to use the IP address validation, intended for server-side calls.
The following is from https://developers.google.com/maps/faq#keysystem:
API Key: An API key is a unique identifier that you generate using the
Google API Console. API keys are generally used with the standard
APIs. Premium Plan customers1 typically can choose to use a client ID
or an API key. You can choose to use an API key without applying
restrictions (called a “generic API key”) or a key with restrictions
applied for greater security. APIs in any platform may use a generic
API key.
You can optionally add a restriction (for example, IP address) to the
API key. Once restricted, a key will only work on platforms that
support that type of restriction. Four types of API key restrictions
are available:
IP addresses (individual servers) - for use with the web service APIs.
HTTP referrers (web sites) - for use with the Web APIs.
Android app restriction (by package name and fingerprint) - for use with the Android APIs.
iOS app restriction (by iOS bundle identifier) - for use
with the iOS APIs.
You need a different key for the webservices. You can't apply both HTTP and IP restrictions on the same key. You need HTTP Restrictions on your Google Maps Javascript API v3 key and IP Restrictions on your web service key.

Using XMLHttpRequest within a Google Sheet Sidebar

I'm trying to make a REST call to a server that has restricted IP access. Therefore, I need to make the call from the client. To do so, I'm trying to use the XMLHttpRequest object within an HTML page loaded in the Google Sheet Sidebar. When I call XHR.send(), however, I always get an exception of the form:
"NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://some.host.com/'."
Does XMLHttpRequest not work within a google sheet sidebar? Is there an alternative?
Thanks.
When you say that the server you're talking to has "restricted IP access" do you mean only whitelisted IP Addresses can call it? Have you added Google's servers to that whitelist?
This answer provides details:
Google App Engine - list of IP addresses?
As does the FAQ here
https://cloud.google.com/appengine/kb/
(see question "Static IP Addresses and App Engine apps").
I've discovered that making XHR requests from the sidebar is in fact possible.
The problem I was running into was that the browser was blocking the request due to it being a cross-origin request. And, unfortunately, I'm not able to add google to the list of acceptable origins on the server I'm communicating with. So, I may be stuck for my particular use case.