Slow Your Role: ChatOps Access Control
by August 20, 2014

Filed under: Application Performance Management, Performance Management Tech

AppNeta no longer blogs on DevOps topics like this one.

Feel free to enjoy it, and check out what we can do for monitoring end user experience of the apps you use to drive your business at www.appneta.com.

ChatOps is a growing trend in the DevOps world, where one can monitor and control infrastructure and operations from the convenience of a chat room. From building Jenkins jobs to executing Fabric tasks, the possibilities are endless thanks to Hubot and it’s constantly growing script ecosystem.

One of the controversial tenets of ChatOps is the idea that everyone within the chat room has the ability to run commands. This idea is built upon the notion that team members understand they are accountable for their actions and that all commands executed are visible to all team members within the chat room. So not only do you have a “public” record what commands team members are executing, but you also get real-time peer review.

While this rather open access philosophy leaves plenty of room for debate, it’s clear that it goes completely against the traditional view that only an elite few have access to the critical components of a system. Thus, this has the unfortunately consequence of making ChatOps hard (or even impossible) for many to adopt within their organizations.

Enter hubot-auth. A Hubot script that makes assigning and enforcing user-based roles easy as Sunday morning. That’s right control freaks, rejoice! You can finally convince your team it’s time to take operations to the next level!

NOTE: This article assumes you have a basic understanding of ChatOps. If this is a new concept to you, I highly recommend you watch the following talks:

Fall In

Getting started with hubot-auth is easy slightly complicated. The bad news is that there are multiple versions of this script coexisting within the Hubot community. The good news is that all but one are unofficially deprecated, so you just have to do a little cleanup before getting started:

UPDATE: The folks at GitHub have resolved the multiple versions issue! So if you’re using a newer version of Hubot, you should only have to do the following cleanup if the files/references exist.

  1. Remove any reference to auth.coffee from your hubot-scripts.json file
  2. Delete auth.coffee if it exists in the scripts directory within your Hubot directory

Now that you’ve removed any possibility of loading a deprecated version of the script, let’s go ahead and install the correct one:

$ npm install hubot-auth --save

Now add hubot-auth to your external-scripts.json file:

["hubot-auth"]

Finally, set the HUBOT_AUTH_ADMIN environment variable to a comma separated list of user IDs who should have admin privileges. Getting user IDs is quite simple using the redis-cli command (assuming you’re using redis to store your Hubot brain):

$ redis-cli get "hubot:storage" | jsonlint | grep "Dan Riti" -C 3
    "12345": {
      "id": "12345",
      "jid": "12345@chat.example.com",
      "name": "Dan Riti",
      "mention_name": "Riti",
      "room": "traceview",
    }
$ redis-cli get "hubot:storage" | jsonlint | grep "Jane Doe" -C 3
    "54321": {
      "id": "54321",
      "jid": "54321@chat.example.com",
      "name": "Jane Doe",
      "mention_name": "Doe",
      "room": "traceview",
    }
$ export HUBOT_AUTH_ADMIN=12345,54321

And with a simple restart of Hubot, our hubot-auth script is setup and ready to go!

The Power Is Yours

Now that we’ve declared our admin users, we’re ready to start dishing out user roles. Like many other aspects of Hubot, the commands are simple and easy to remember:

Adding a role:

Dan Riti> hubot Dan Riti has deploy role
Hubot> @Riti: OK, Dan Riti has the 'deploy' role.

Checking a specific user’s current roles:

Dan Riti> hubot what roles does Dan Riti have
Hubot> @Riti: Dan Riti has the following roles: admin, deploy.

Removing a role from a user:

Dan Riti> hubot Dan Riti doesn't have deploy role
Hubot> @Riti: OK, Dan Riti doesn't have the 'deploy' role.

Now we’re ready to lay down the law.

I AM THE LAW

The last step of the process is actually enforcing user roles within your Hubot scripts. hubot-auth exposes the following method on the robot object for checking user roles:

robot.auth.hasRole(msg.envelope.user,'<role>')

For a quick demonstration, let’s look at how we can add role based access control to the “Hello World” of Hubot, hubot ping:

# Description:
#   Utility commands surrounding Hubot uptime.
#
# Commands:
#   hubot ping - Reply with pong
module.exports = (robot) ->
  robot.respond /PING$/i, (msg) ->
    msg.send "PONG"

A user enters: hubot ping and Hubot responds with PONG. Pretty simple stuff! Now let’s go ahead and update this script to only allow users with the ping role from executing the command:

# Description:
#   Utility commands surrounding Hubot uptime.
#
# Commands:
#   hubot ping - Reply with pong
module.exports = (robot) ->
  robot.respond /PING$/i, (msg) ->
    role = 'ping'
    unless robot.auth.hasRole(msg.envelope.user, role)
      msg.send "Access denied. You must have this role to use this command: #{role}"
      return
    msg.send "PONG"

And now let’s see it in action:

Dan Riti> hubot ping
Hubot> Access denied. You must have this role to use this command: ping
Dan Riti> hubot Dan Riti has ping role
Hubot> @Riti: OK, Dan Riti has the 'ping' role.
Dan Riti> hubot ping
Hubot> PONG

Victory!

Conclusion

While turning a chat room into a multi-user terminal can seem like a scary idea, it’s actually helpful in disseminating operations knowledge across any team. Adding role based access control into the mix not only sweetens the deal, but will help you sleep better at night. So if you haven’t considered bringing ChatOps into your organization, now is a good time to reconsider!

As a final note, I want to point out that one of the current deficiencies with hubot-auth is that many scripts do not support it off the shelf. Thus, I’d like to propose a call to action and encourage users to start sending pull requests to your favorite scripts that add support for the hubot-auth script!

  • After seeing this blog post, I was motivated to “fix” the “problem” in https://github.com/github/hubot/pull/656 . I’ve updated hubot to officially deprecate the included auth.coffee, and recommending hubot-auth. If anyone reading this is starting with a new hubot running 2.8.1, they can skip the step on removing `scripts/auth.coffee` and removing `auth.coffee` from `hubot-scripts.json`. Enjoy!

    • @technicalpickles:disqus, fantastic! i’ll update the article to point this out for users running a new version of hubot!

  • If your company is a Ruby shop, Lita ( https://www.lita.io/ ) is a similar chat bot that has this type of authentication system built into the core.

  • phoenix

    How can an admin we assign role on hipchat? I am using hipchat as an adapter for hubot.