How to restrict which Google Home devices can interact with an action? - actions-on-google

I want to build a Conversation Action for Google Home device and control its access. Only certain devices can invoke some actions. How can this be done, once the agent is publicly deployed?

Think of Google Home the same way you would think about a web browser and an Action the same as a web page or site. If you wanted to limit what web browsers can access a public site on the Internet, you're somewhat limited.
You could restrict access to certain IP addresses, and this will work in some cases - but it means that access via non-static IP addresses aren't possible, and if (ie - when) a machine gets a new static IP address, you have a lot of work to do. Similarly, the Google Home device can send a random user_id string for each unique user, and you can use this to limit who has access. But this string can change by the user resetting their Google Home device, and when it does, you will have to deal with that.
A better solution on the web is to allow people to log into your site. This way you can have a public facing web page, but only people with accounts can access. You can determine how to hand out accounts, so this is very flexible. The equivalent with Google Home is Account Linking where you will maintain an account as part of an OAuth2 system that you control. Google Home will ask for permission to access your system, and you will issue OAuth2 tokens to Actions - these tokens will be passed back to you for each request, and you can verify that the user has access.
I strongly suggest going with the Authorization Code Flow since this seems to be where Google is focusing on providing additional features - such as signing up to your service through Google Home.

Related

Is there a way to secure a public endpoint?

Am I correct in thinking that a public REST api, such as a registration endpoint can't authenticate a user. For example our endpoints should only accept requests coming from our mobile applications and future web apps.
I am pretty sure it's not logically possible. I think apple and google offer a way (acting like a ca) for the server to identify a request is coming from a registered device however that changes the API to a private one. As authentication is essentially moved to the app store so only owners of app store accounts can use it.
So keeping it completely public the only way to prevent bots attacking it is to use email confirmation with auto deletion if not confirmed in x amount of time, and IP rate limiting.
A contractor suggested we use a unique secret key hard coded in to each app however, that to me sounds illogical and completely wrong. A secret between the app and server is compromised the second a user downloads the application on their device.
So am I correct about the secret key, are there any other ways to secure the endpoint from bots? The only other thing I can think of is using a captcha.
There are 2 separate things here.
Securing Public REST APIs
You are correct that a secret, even an asymmetric one, would be compromised if the attacker downloads and reverse-engineers the application. Attackers can use debuggers, Chrome developer tools, and tools like Wireshark to reverse engineer and find the secret.
In general, an attacker can mimic the behavior of the app or user, i.e. same the same requests in very similar patterns.
The approach to this in today's industry is to filter out as many of those attackers as possible using tools like Web Application Firewalls, and increasingly, Bot Management solutions, which work for web, mobile, and APIs.
The better the tool, the more work the attacker has to do, ergo fewer are attackers willing to do it, ergo smaller chance of being attacked.
Secure Authentication
Authentication is a specific case of the above, however this problem is currently (one of) the biggest problem faced by web applications.
The main solutions employed today is are bot filtering techniques e.g. CAPTCHA (which resourceful attackers can overcome), and Multi-Factor Authentication.
It's quite uncommon these days to be able to register without email, however services such as 10 Minute Mail can be used to overcome this. It's actually not very difficult to set up your own mail server as well.
Login is more difficult because you can't expect people to go through email, and even other MFA methods get quite annoying. You'd be OK with MFA for your bank account, but not with MFA to your Domino's Pizza account.
Because of that, the latest fad in web attacks is Account Takeover.
All those security vendors which offer WAF and bot management also try to protect APIs such as registration & login, with various degrees of success. There are even dedicated products are starting to emerge.

How to store app tokens and secrets for ionic apps

I'm using adjust and firebase in my ionic app but the app secrets for these integrations and others all show up in my app's js code if I extract the APK/IPA.
How do I keep credentials secure and package them with the app's APK/IPA for such hybrid apps?
This is an interesting question and it's good that you are asking it :)
For the Firebase settings, they are secret, but not secret-secret. They are just a starting point. Nothing can be done with those unless the user also logs in with their password which is hashed using the secret key and then sent over.
This proves that the person knows enough to identify themselves as a user.
Then on the server side, you have your rules that say "for the person that has identified themselves as user X they have permission to do Y"
If somebody has got your password then you are exposed just the same as you are always exposed.
You can also restrict your Firebase account by apps package id, hostname, IP address, in the Google Cloud admin panels.
As for your other things, like Adjust, they have their own solutions along the same lines. Either the API key is just enough for you to read the information, or if its a powerful level of access then normally there is some kind of authentication/account linking process so you can prove yourself to the other API.
If not, then you cannot just put it out there, you need to create your own proxy. Firebase supports cloud functions (aka serverless) so you can run snippets of code which are only accessible by users that have logged in, and then return that information back to the client as a proxy.

Authentication needed when chat bot conversing with user

This got stuck in my head from many days, can anyone help or say at-least this is not at all possible?
I'm working on developing a chat bot using dialogflow which integrates multiple applications along with google home assistant, dialogflow, actions on google and an application which i want to manage using chat or voice commands. Until now its good and got amazed of features providing by google.
But i'm expecting one more feature. Don't know whether any alternatives available for this or not, but i tried exploring and reached to desert. Below are my requirements, if others think this is really unique and useful to them as well then i can say they are improvements or add-ons i'm expecting from DialogFlow.
Let's take an example of a chat bot which is serving users through google assistant and as a web bot as well. Now while conversing, intents may trigger web-hook in fulfillments which may require an authentication like OTP(Nope if anyone thought it for payments) which means registered users or limited users only can perform actions. This is same as we use roles and groups in all the applications.
The way google is sending google prompt to the user for logging into gmail, is there any way that we can collect PIN or OTP or PASSWORD through some notification sent to the users phone as some card's or input box like and html while conversing with chatbot through web or home assistant etc..., so that it helps in adding more security.
I recently worked in a chatbot project where I had to authenticate my users. I'm writing an article about it, but I'll tell you what I did:
First of all, I'm using OAuth 2.0 protocol to authenticate my users, but if you doesn't use OAuth, there's no problem, you could do something equivalent.
I'm using Authorization Code Grand flow.
Let's see the steps:
Step 1 - Authorization Url:
My bot generates an authorization url which contains all needed data to identify the conversation in callback moment. Like this one:
https://authorization-server.com/oauth/authorize
?client_id={your-client}
&response_type=code
&state={conversation_id: 123456789}
&redirect_uri={your-callback-url}
Notice that the state parameter contains the conversation_id which identifies your conversation, this state parameter will be back when users return to your handler.
Step 2 - User Authentication
When users click in this link, they'll be redirected to your login page at your authorization server.
Step 3 - Callback
After users get authenticated, they'll be redirect back to your handler (an endpoint which will receive the authorization code from authentication server and the state parameter).
When it received this authorization code, it'll be exchanged by an access token in authorization server.
Step 4 - Store token
In the final step, you already has an access token and the conversation_id parameter, you can store it in a database, in a cache or be stateless. Your rules!
In my case, I'm using Watson Assistant with Cloudant database, and I store those access tokens in my database. So, when users request something to my bot, it could get this token from database and pass to my back-end servers.
This kind of approach, I call "magic link". And you could improve it by shortening the url as bit.ly does.
I hope it could help you, feel free to ask me if you need.
Best
You probably don't want to implement the OTP scheme yourself. While you could do this, there are other systems already in place that will do this for you.
The best is the one that you reference - Google Sign In.
Fortunately, you can leverage Google Sign In for both your website (where you would get the user to sign in and then pass this information along as you do the Dialogflow calls) and for the Assistant (where Google will pass along an ID token, indicating it has authenticated the user).

Google Assistant actions on google

All my hardware is already developed. I use MQTT for communication between my devices, I have lights, fans, heaters and many more ioT appliances. I can controll all of these from my Android application which i have built. I would like to use Google Assistant to control my devices as well. The status of my lights (on/off) are stored in a sql database and when ever a change occurs to the database(detected by the hardware) my hardware can control that specific light. In My Android app i do the same thing which is updating the databases value(on/off) of the light and the change is detected by my hardware platform. Can i use Google Assistant to update a sql database value?
I can create a webserver( ASP.NET C#) and pass the command to the sql database of my relevant customer if google assistant can invoke the username or email, lightID, command to my webserver. Can google assistant do this? If not how would achieve this.
It sounds like you want to take a look at the Actions on Google Smart Home API which will let the Assistants Smart Home controls work with your control server directly.
Without knowing exactly how your database or existing web server are configured or hosted, I can speak only broadly at best. Your web server will need to implement two primary things:
You'll need an OAuth2 server that can issue tokens that represent your users. This is how Google will associate the user's account on the Assistant with your account, and how Google will identify (to you) which user is issuing the command.
You will need to implement a webhook at a URL on your web server. This webhook will be sent a POST message containing a header with a valid auth token (that you issued) and a JSON body. The JSON will contain information about the command that has been issued by the user. Your HTTP reply body will also be JSON. For details of the JSON formats and all the fields that it can send and that you must reply with, consult Google's documentation.
There are a number of different commands (which Google calls "intents") that Google can send you on behalf of the user. You should be able to handle all of them by either querying or modifying your database:
SYNC - A request for what devices this user has, some of their configuration information, and what commands they respect.
QUERY - What is the current state of the devices for this user.
EXECUTE - Change the state on some of the user's devices.
RESYNC - (Future update) A re-request of the user's device info.

Facebook Connect on multiple domains with centralized login

we are looking into implementing Facebook Connect on our wiki service, http://www.wikidot.com. User-created sites span the *.wikidot.com domain, but also custom domains (like mine http://michalf.me), all handled by our single service.
We have a centralized account system. Users always log in (and create accounts) at www.wikidot.com and they are automatically logged in in all subdomains (cookie domain set to .wikidot.com - easy) and custom domains (automatically, via a series of redirects).
We would like to add FC into our login flow. Now, it would be great to get some clarification about FC Terms, which suggests using one App ID for every domain. In our case however user-created sites are not separate applications.
So, is it OK to use FC on one centralized website where our users log in (on www.wikidot.com) and expand user status on other domains connected to our service? This is how it works right now, without FC.
It would be great if we could get clarification from someone from FB to make sure we will not be violating any terms or policies.
Thanks!
It isn't possible (as far as I know anyway) to use the same app ID on multiple domains. FB allows use across subdomains, but I have found some difficultly with this even at times with the cookies. When you set up an app, you are asked to provide the domain for it. The domain you put here is the only domain that your app will work for. If your users are only ever signing in on wikidot.com, then I suppose you can use what you have already to move those sessions onto the other domains, but once you are on the other domain, you won't be able to use any of the facebook api features; any requests you make will fail.
I think the 'one app id for every domain' condition is more to target people who are trying to use multiple app ids for one domain. I think so long as you aren't transferring any data about the user to different domains/adverts etc, you should be ok. Essentially what you are doing is adding FB connect to your wikidot site, then a separate feature of wikidot is to keep you logged in on other partner sites?