How-tos

How to: Credentials in a serverless Slackbot app

Share this post:

Recently, I introduced you to a new tutorial for a database-driven Slackbot. Today, I am going to discuss security details,  how the IBM Watson Conversation service is accessing a Db2 Warehouse service from within a dialog. It uses a serverless setup with IBM Cloud Functions. All the necessary credentials to execute the code and to access the Db2 database are automatically bound. Hence, the function code and the dialog don’t need any account-specific changes and are generic.

Slack Chatbot Architecture

Slack Chatbot Architecture

Programmatic Calls from Dialog Node

The Conversation service allows to make programmatic calls from a dialog node. It supports both server- and client-side actions. For a client-side action the response to the caller is flagged. It means for the caller to look for action-specific metadata, execute the intended action and to again call into the Conversation dialog. For a server-side action the Conversation service utilizes IBM Cloud Functions and invokes the specified action.

Credentials

In order to do so, it needs the appropriate credentials to execute the intended action. Best practice is to configure the dialog node with a variable that, as a value, holds the variable name of where to find the JSON-formatted username and password. This is also what I implemented for the server-side actions in the Slackbot tutorial. The username and password need to be passed in by the caller to the Conversation service. In the case of the Slackbot, the caller is the Conversation connector, a serverless, Cloud Functions-based framework itself. The connector consists of a sequence of actions. Each part of the sequence can be adapted.

Connector Pipeline

Connector Pipeline

For the Slackbot, the pre-conversation action is the best for adding credentials. That action sits between the handling of Slack- and Facebook-specific tasks and calling into the Conversation service. What I had to do is to implement own version of pre-conversation and update the action with my code. The action is using an OpenWhisk environment variable, OW_API_KEY, to access the user and password information. Thereafter, it adds that data as the configured variable to the call context into the Conversation service. With that information present, the Conversation can invoke the server-side action which accesses Db2.

function main(params) {
     const returnParams = params;

     // retrieve API Key from environment and split it into user / password
     var arr=process.env['__OW_API_KEY'].split(":");
     // check if context exists
     if (typeof(returnParams.conversation.context) === 'undefined') {
         var context={context: {}}
         Object.assign(returnParams.conversation, context);
     }
     // if credentials already exists, we don't have to add them
     // else add credentials under private element in context
     if (typeof(returnParams.conversation.context.icfcreds) === 'undefined') {
         var privcontext = {"private": {icfcreds: {user: arr[0], password: arr[1]}}};
         Object.assign(returnParams.conversation.context, privcontext);
     }

     return returnParams;
 }

Action Bindings

To retrieve data and store new events, the action needs Db2 service credentials. This can be accomplished by binding the action to that service. The CLI for IBM Cloud Functions has a command for that purpose. It is used by my setup script to bind the database-related actions to a specific service key which I created for the Db2 service on IBM Cloud.

# Create the database service
bx service create dashDB Entry eventDB
# Create service key
bx service key-create dashDB-p slackbotkey
# Create the database-related action
bx wsk action create slackdemo/fetchEventByShortname eventFetch.js --kind nodejs:8 
# Bind the service key to the action
bx wsk service bind dashDB slackdemo/fetchEventByShortname --instance eventDB --keyname slackbotkey

 

Conclusions

To call serverless actions and to access the Db2 service credentials are needed. They protect the resources from unauthorized access and use. I could solve access management for my Slackbot tutorial elegantly with the features offered by IBM Cloud and its services: A service key and action binding for the Db2 access, a meta-variable and a Cloud Functions environment variable for the service-side actions in the Conversation service.

If you have feedback, suggestions, or questions about this post, please reach out to me on Twitter (@data_henrik) or LinkedIn.

Technical Offering Manager

More How-tos stories

How to deliver great performance for global apps on IBM Cloud

A large telecommunications service provider in Europe wants to serve customers in Brazil from their Frankfurt, Germany location. One challenge with such large geographical distances is achieving consistently low latency in order to provide a good user experience. Another challenge is scaling the infrastructure to handle a large number of user requests during peak traffic conditions.

Continue reading

Securing your Python app with OpenID Connect (OIDC)

Some weeks back I introduced to a tutorial on how to analyse GitHub traffic. The tutorial combines serverless technology and Cloud Foundry to automatically retrieve statistics and store them in Db2. The data can then be accessed and analyzed using a Python Flask app. Today, I am going to show you how the web site is protected using OpenID Connect and IBM Cloud App ID.

Continue reading

Custom login page for App ID integration

When developing an application that integrates with App ID, the standard hosted login page has a few options to change the colours or logo. In some cases, this isn't enough and direct customisation is necessary. There exists a handy guide for a custom App ID login screen in mobile applications, however for web applications a little more effort is required.

Continue reading