Restricting a Slack Workflow (MOSTLY works for MS Teams too!)

There are a couple different methods available to restrict who can run a Slack workflow. The simplest one is restricting the channels that can trigger the workflow. The more complicated methods involve examining the user who triggered the workflow and determine if it should proceed.

With Slack, the trigger uses a regex expression to evaluate the channel name, and only triggers if the message was received in a channel that matches. IN THE MS TEAMS PLUGIN IT’S AN EXACT MATCH, SO NO REGEX SUPPORT IN TEAM OR CHANNEL NAME. Because it’s regex, you can include multiple channels, a channel prefix, postfix, or require an entire match. Also, because it’s regex, you can supply multiple patterns to match.

For example: We have a workflow that’s highly sensitive so we only want it to trigger if called from a channel named “secure-security-workflows”.
We’d set the “Match Channel” field of the trigger to ^secure-security-workflows$

The ^ and $ are critical to maintain security - without them it’s a “contains” match and anybody in your slack instance could create a channel that matches and run the workflow. By forcing a match on the beginning and end of the string, we prevent secure-security-workflows2 from being able to trigger the workflow!.

Let’s say we wanted to match 2 different channels, both with the same restrictions. This is where the regex OR operator comes in - aka |
(^secure-security-workflows$)|(^secure-security-workflows2$)

So that’s how we can restrict a slack workflow to a narrowly defined set of channels! Just don’t forget to invite the slackbot to the channel and you should be all set!

But what if you want to restrict the workflow based on user information?

Take the following scenario:
You have a workflow that’s meant to be a self-service workflow, but it performs a security-sensitive operations like requesting an exception to a URL blocklist. You build the workflow so anybody can trigger it, but it goes to a human decision point for security to review the request before it is actually performed. Now, security wants to give certain users the ability (maybe it’s just their own team) to unblock a URL without a review. How can we accomplish this?

There are a few options - and these can all be used to just end the workflow as well. They all follow the same pattern: check the username against a list of authorized users.

This is the basic pattern:
image

The differences between the different mechanisms comes from the input to the decision step. The two most useful steps are:

  • Lookup username in authorized users global artifact
  • require membership in a specific AD group

Global artifact lookups are easy and I won’t go into detail here on how to use them - they’re covered in the ICON documentation and in multiple workflows in the extension library.

Looking up a user in AD has a couple tricky components:

  1. Translating the slack username to AD username
  2. Handling nested groups

Determining the user’s AD identity is really dependent on your specific naming scheme. Most companies use an auto-provisioning system that follows certain rules, so you can just re-use those rules in your workflow. A very common one is to have the sAMAccountName be the slack username. With Microsoft Teams, of course, the linkage is built-in!

For group membership, you should use the custom matcher outlined here: Active Directory Group Membership Tip

Combining the group membership and the global artifact approaches, where the global artifact contains a list of authorized groups, our LDAP query might look something like this:
(&(objectClass=user)(|{{#each ["Get Allowed Groups"].[matches]}}(memberOf:1.2.840.113556.1.4.1941:={{this.[group]}}){{/each}}) (sAMAccountName={{["Request"].[message].[user]}}))
For teams, check userPrincipalName instead of sAMAccountName. The UPN should match, but full disclosure, I haven’t tested for this post.

It’s a little complicated to get setup, but once it’s configured your workflow will have granular permissions driven by a user’s group membership in AD. You control the groups the workflow checks with a simple global artifact that contains the DN of the authorized groups! Administration is a breeze and you’re re-using your security classifications from your authorization source of record!

I hope this helps to illuminate the security options available around securing chat-initiated workflows!

3 Likes

Heh…we needed this post about a week ago. Nice work.

Obviously, you could also just create a group in AD for each workflow and add users/groups to that group for authorization - cut the global artifact out entirely… If that approach wasn’t clear already.

I’m a simple guy, I’ll just trigger the WF from restricted/private channels or teams. However, the advice about the exact regex is very good. We had someone hit that exact problem about a week ago. It’s something I always forget about.

1 Like

I’ve always done the AD user membership lookup on anything that has elevated access as a double check to make sure someone didn’t get added to a channel that shouldn’t have. We talked about the Global Artifact also because AD Group membership can also get unexpected guests, but because we have alerting on the modification of that AD group we felt that the lack of maintenance with auditability was justified. @elijah_martin-merrill I did the LDAP query that you mentioned in another post but without the recursion because this is a group that we maintain explicit membership of, never allowing embedded groups to be added.

This is probably one of the only things Teams does better than slack. Teams are built around groups and group membership, so getting someone into a team they’re not supposed to be on is a bit more difficult than on the Slack side of things.