Is there a way to maintain context permanently ? such as an API key - chatbot

I'm using API.AI with a backend in Golang to create a chatbot that queries an API. This API needs a API key.
This API key is user specific, it does not reply the same answer for different users.
I understand that context in API.AI can persist informations but it lasts only for a session.
Is there a way to memorize indefinitely (more or less) an information ?
Thank you all

API.AI doesn't store most dynamic data beyond the session as you've already indicated. For data as secure as API or authentication keys I'd recommend a secure database or datastore outside of API.AI and using user IDs for the platform's your working with through API.AI to connect the user to their API/authentication key (API.AI passes through information about where the request is coming from the originalRequest attribute of the JSON sent with every webhook request).
For instance you can retrieve the ID of a user who accesses your API.AI agent through the Google Assistant with originalRequest.data.user.user_id, Slack users with originalRequest.data.user and Facebook users with originalRequest.data.sender.id

Related

Making API requests to a 3rd party that requires authentication

Here is my scenario. Imagine there is a Yoga studio that uses a professional booking and reservation system that exposes an API. Through this API an application can make a reservation for a client. The API takes the client's userid and password to make the reservation. The booking API doesn't use OAuth or any social media sign-ins.
My desire is to create an Assistant Action that would retrieve the list of classes and allow the client to make a booking.
My puzzle is what design/architecture to look towards to supply the userid/password pair required by the booking API.
How have others solved this puzzle?
Should I store the userid/password as "user state" associated with the action?
First, you should have a conversation with the API provider about why they don't provide an OAuth-based solution. This is a security vulnerability waiting to happen, if it hasn't already.
Second, you need to think very carefully about your own risk profile in this case:
Google does not allow you to collect credential information (ie - passwords) through your Action.
Because of this, you must use Account Linking to authenticate them.
This means that you will need something (ie - a database or data store) to manage their account on your side.
This database would be a good place to keep the username/password you need to use for them for the API...
...but it now means that you need to take extreme care about protecting this database.
You don't really say how this API allows for accounts to be created and managed. If these accounts are just used for you (ie - the user doesn't necessarily see them), then you can mitigate some of that risk by treating the username/password as an opaque token that you manage and generate and that the user never sees.
If this is something that the user is aware of, then you'll need to approach the account linking in one of two ways:
Have them log into your service via an app or webapp using this credential info that you will need to save (ack!) and then link to the Assistant using OAuth.
Have them log into your service via an app or webapp using Google Sign-In, which will carry over to your Action. Then have them provide the credential info for the API, which you will need to save (ack!).

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).

Creating an API Layer on top of Firebase Real-Time Database

I do have some data stored in my Real-Time Firebase database. I am willing to expose some of this data via a REST API to my B2B customers.
I know that Firebase is itself a REST API but its authentication mechanisms don't fit my needs. I am willing my customers to access the API with a simple API Key passed in the HTTP request headers.
To summarize, I need an API layer sitting on top of my Firebase real-time database with the following properties:
Basic Authentication via an API key passed in the HTTP request headers
Some custom logic that makes sure customers respect the API limits (maximum requests per day for example)
The only thing I can think of is implementing this layer in AWS lambda but that also sounds a bit off. From the lambda, I would have to access my Firebase database and serve that data. That seems too many network requests; something native to Firebase would be great.
Thanks,
Guven.
Why not have a simple API which provides them an Oauth token for the original firebase REST API if they have the correct Api Key
It'll be more secure as only you'll be able to make the tokens as only you'll have the service account private key. Also saves you the headache of making a whole REST API. Also the Oauth tokens expire relatively quickly so it's less of a risk than a normal key that you furnish
I personally have created my own Servlets where a user posts their data if they are authenticated using an id pass combo.
In the Servlets i use the default REST API provided by Firebase with the Oauth generated in my servlet. This way, i can have the DB security rules set to false for all writes from any client api. And the REST API and their admin sdk on my server ignore the security rules by default.
After some research, I have decided that AWS is the best platform such API related features.
Gateway API lets you setup your API interface in a matter of seconds
DynamoDB stores your API data; you can easily populate the data here
AWS Lambda lets you write the integration code between Gateway API and DynamoDB
On top of these, the platform offers these features out of the box:
Creation & handling and verification of API keys for authentication
Usage plans to make sure that API consumers don't exceed your API usage limits
Most of what I was looking for is offered in these AWS services.

OAuth 2.0 in background while creating events on GCAL from Salesforce using Google Calendar API v3 (REST API)

My Situation:
I'm trying to populate a shared Google Calendar when an event is created on the Salesforce interface. Im currently using the latest Google Calendar v3 (RESTful) API for the same https://developers.google.com/google-apps/calendar/ with APEX my development language.
I'm using a trigger that catches all the value from the fields (trigger.new) and passing those values to a class that does the JSON serialization, authentication and API call.
Till now, I was able to get all the data from the object and pass is to the class and get it serialized. But I need to do the OAuth 2.0 call before I can make a Google Calendar API call. https://developers.google.com/google-apps/calendar/
I have setup my application on the Google API Console and obtained the Client ID, Client Secret etc.
The usual way OAuth 2.0 works is that an authentication page pops-up waiting for the user to grant access to the API so that it can access the calendars linked to the users account.
My question:
Is there any way I can get the OAuth done in the background using a static/private key which is either obtained by granting access just once but not every time or just programmatically using the key value in the class to authenticate the user.
Looking forward to getting useful suggestions/inputs/help from everyone.
If the user --once-- have made the authorization you got the access_code and the refresh_code.
I found it helpful to store both codes with the application (here Firefox and password manager). With the next start of the application (Firefox/extension) I use the refresh_code to request a new access_code. That is used during the session for any further calendar call.

REST related query- for use in Java web app

I am trying to create a REST API using Java.
Now, for the front end, I am using socialauth, so that facebook/twitter/yahoo/hotmail/gmail users can sign in to the application.
After a user is signed in, he should be able to access the data for his account- I want to create a REST API that enables each user to access his data. I have understood the basics of creating a REST API using Jersey framework, however how do I ensure that only a user who is correctly logged in to the application, can access data via the REST API?
What I thought of is, I will store the user's email ID in session, when he logs in. And whenever he makes a request to the API, the email ID in session is passed as a input parameter to the REST API, and the REST API checks that data is asked for same email ID, as the email ID parameter.
Is the above way of thinking correct? What is the recommended/best way to implement REST API in the scenario as given above?