AutomationFlowsAI & RAG › Slack Bot Actions with OpenAI and Permit.io RBAC

Slack Bot Actions with OpenAI and Permit.io RBAC

Original n8n title: Gate AI Slack Devops Bot Actions with Openai and Permit.io Rbac

ByTaofiq @taofiq on n8n.io

> This n8n workflow template uses a community node and is only compatible with the self-hosted version of n8n.

Event trigger★★★★☆ complexityAI-powered14 nodesSlack TriggerOpenAI@Permitio/N8N Nodes PermitioHTTP RequestSlack
AI & RAG Trigger: Event Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #14087 — we link there as the canonical source.

This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Gate AI Slack bot actions with role-based permissions from Permit.io",
  "tags": [],
  "nodes": [
    {
      "id": "e2b71c25-9820-4fc3-8edb-ac66a67598d7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        -64
      ],
      "parameters": {
        "width": 436,
        "height": 712,
        "content": "## Gate AI Slack bot actions with role-based permissions from Permit.io\n\n### How it works\nA Slack bot that handles DevOps requests and checks every action against Permit.io RBAC before execution.\n\n1. Team member @mentions the bot with a request\n2. OpenAI classifies the intent into action + resource\n3. Permit.io checks if the user has permission\n4. Allowed \u2192 executes the action, posts result to Slack\n5. Denied \u2192 shows what the user can do and who to escalate to\n\n### Setup\n1. Install `@permitio/n8n-nodes-permitio` community node\n2. Configure Slack app with `app_mentions:read`, `chat:write`, `channels:read`, `users:read`\n3. Add OpenAI API key\n4. In Permit.io, create resources (logs, staging, production, secrets) with actions (view, deploy, restart, rotate)\n5. Create roles: viewer, developer, sre, admin\n6. Sync Slack user IDs as users in Permit.io and assign roles\n\n### Customization\n- Replace the mock HTTP Request with your real infra endpoints\n- Add ABAC conditions in Permit.io for time-based or amount-based rules without changing this workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "96226226-75ad-4647-8353-c2abb4eecbab",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 516,
        "height": 288,
        "content": "### 1. Trigger & Classify\nSlack trigger captures the @mention, then OpenAI extracts the action and resource from natural language."
      },
      "typeVersion": 1
    },
    {
      "id": "a83091f1-f07a-494d-834f-adb23750680a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 268,
        "height": 304,
        "content": "### 2. Permission Gate\nPermit.io checks RBAC policy. The IF node branches on the result."
      },
      "typeVersion": 1
    },
    {
      "id": "433a4b61-fb3d-461f-a18d-72a92a2e35b8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1312,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 548,
        "height": 352,
        "content": "### 3a. Allowed \u2192 Execute\nReplace this HTTP Request with your actual infra endpoint (GitHub Actions, ArgoCD, Jenkins, etc.)"
      },
      "typeVersion": 1
    },
    {
      "id": "898d810a-fa16-406c-b08e-3d677c66ffee",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        160
      ],
      "parameters": {
        "color": 7,
        "width": 844,
        "height": 320,
        "content": "### 3b. Denied \u2192 Help\nTells the user what they CAN do and who to escalate to."
      },
      "typeVersion": 1
    },
    {
      "id": "d7fe3502-734f-4d64-8a53-44d7596dd229",
      "name": "Slack Trigger - Bot Mention",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        528,
        224
      ],
      "parameters": {
        "options": {},
        "trigger": [
          "app_mention"
        ],
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f7b009d2-7db5-4c38-badc-4e84d5a5b607",
      "name": "Classify DevOps Intent",
      "type": "n8n-nodes-base.openAi",
      "position": [
        752,
        224
      ],
      "parameters": {
        "model": "gpt-4o",
        "prompt": {
          "messages": [
            {
              "role": "system",
              "content": "You are an intent classifier for a DevOps Slack bot. Given a user message, extract the action and resource.  Valid actions: deploy, restart, view, rotate Valid resources: staging, production, logs, secrets  Respond ONLY with valid JSON, no markdown: {\"action\": \"<action>\", \"resource\": \"<resource>\", \"summary\": \"<one line summary of what the user wants>\"}  If the message doesn't match a DevOps action, respond with: {\"action\": \"unknown\", \"resource\": \"unknown\", \"summary\": \"<what the user asked>\"}"
            },
            {
              "content": "={{ $json.text }}"
            }
          ]
        },
        "options": {
          "temperature": 0
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e3f3bd66-7d50-402c-b5ab-54b70873fcc0",
      "name": "Check Permission",
      "type": "@permitio/n8n-nodes-permitio.permit",
      "position": [
        976,
        224
      ],
      "parameters": {
        "user": "={{ $('Slack Trigger - Bot Mention').item.json.user }}",
        "action": "={{ JSON.parse($json.message.content).action }}",
        "resource": "={{ JSON.parse($json.message.content).resource }}"
      },
      "credentials": {
        "permitApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0880127b-7f77-4658-975f-50ec1fa4e169",
      "name": "Is Allowed?",
      "type": "n8n-nodes-base.if",
      "position": [
        1200,
        224
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.allow }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3b508186-d1f2-4ed1-a801-7b29e6df9413",
      "name": "Execute DevOps Action (Mock)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1424,
        128
      ],
      "parameters": {
        "url": "https://httpbin.org/post",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "action",
              "value": "={{ JSON.parse($('Classify DevOps Intent').item.json.message.content).action }}"
            },
            {
              "name": "resource",
              "value": "={{ JSON.parse($('Classify DevOps Intent').item.json.message.content).resource }}"
            },
            {
              "name": "triggered_by",
              "value": "={{ $('Slack Trigger - Bot Mention').item.json.user }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f549ad19-adf1-479f-8cb7-7028b92b870d",
      "name": "Slack - Action Succeeded",
      "type": "n8n-nodes-base.slack",
      "position": [
        1648,
        128
      ],
      "parameters": {
        "text": "= Action executed successfully\n\n- Action: {{ JSON.parse($('Classify DevOps Intent').item.json.message.content).action }}\n- Resource: {{ JSON.parse($('Classify DevOps Intent').item.json.message.content).resource }}\n- Summary: {{ JSON.parse($('Classify DevOps Intent').item.json.message.content).summary }}\n- Triggered by: <@{{ $('Slack Trigger - Bot Mention').item.json.user }}>",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Slack Trigger - Bot Mention').item.json.channel }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "60c248fe-3748-4b7a-9ea5-a8cb95965e3d",
      "name": "Get User Permissions",
      "type": "@permitio/n8n-nodes-permitio.permit",
      "position": [
        1424,
        320
      ],
      "parameters": {
        "operation": "getUserPermissions",
        "resourceTypes": "=logs,staging,production,secrets",
        "userPermissionsUser": "={{ $('Slack Trigger - Bot Mention').item.json.user }}"
      },
      "credentials": {
        "permitApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4b8739bf-7616-4c5c-b32f-42287a1e17c4",
      "name": "Get Authorized Users",
      "type": "@permitio/n8n-nodes-permitio.permit",
      "position": [
        1648,
        320
      ],
      "parameters": {
        "operation": "getAuthorizedUsers",
        "authorizedUsersAction": "={{ JSON.parse($('Classify DevOps Intent').item.json.message.content).action }}",
        "authorizedUsersResourceType": "={{ JSON.parse($('Classify DevOps Intent').item.json.message.content).resource }}"
      },
      "credentials": {
        "permitApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "80b9ad86-d7fe-47bc-bc42-c165b9b4fa10",
      "name": "Slack - Permission Denied",
      "type": "n8n-nodes-base.slack",
      "position": [
        1872,
        320
      ],
      "parameters": {
        "text": "=\ud83d\udeab Permission denied\n\n<@{{ $('Slack Trigger - Bot Mention').item.json.user }}>, you don't have permission to `{{ JSON.parse($('Classify DevOps Intent').item.json.message.content).action }}` on `{{ JSON.parse($('Classify DevOps Intent').item.json.message.content).resource }}`.\n\nYour current permissions:\n{{ $('Get User Permissions').item.json['__tenant:default'].permissions.join(', ') }}\n\nAuthorized users who can help:\n{{ Object.keys($('Get Authorized Users').item.json.users || {}).join(', ') }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Slack Trigger - Bot Mention').item.json.channel }}"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "connections": {
    "Is Allowed?": {
      "main": [
        [
          {
            "node": "Execute DevOps Action (Mock)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get User Permissions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Permission": {
      "main": [
        [
          {
            "node": "Is Allowed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Authorized Users": {
      "main": [
        [
          {
            "node": "Slack - Permission Denied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get User Permissions": {
      "main": [
        [
          {
            "node": "Get Authorized Users",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify DevOps Intent": {
      "main": [
        [
          {
            "node": "Check Permission",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Trigger - Bot Mention": {
      "main": [
        [
          {
            "node": "Classify DevOps Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute DevOps Action (Mock)": {
      "main": [
        [
          {
            "node": "Slack - Action Succeeded",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

&gt; This n8n workflow template uses a community node and is only compatible with the self-hosted version of n8n.

Source: https://n8n.io/workflows/14087/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow automatically turns any audio file uploaded to Google Drive into a complete podcast episode. It handles transcription, content generation, blog drafting, social copy creation, thumbnail

Google Drive Trigger, Google Drive, OpenAI +3
AI & RAG

This workflow is an AI-powered lighting and look development pipeline designed for VFX production. It transforms a single lighting brief into multiple high-quality cinematic lighting references using

Form Trigger, HTTP Request, Google Drive +4
AI & RAG

Overview

Gmail Trigger, Google Drive, OpenAI +4
AI & RAG

How This Works This automation automatically scrapes leads from Apollo using the Apify scraper, filters out those who do not have an Email or URL included, scrapes the leads' website content and write

OpenAI, Google Sheets, HTTP Request +1
AI & RAG

This workflow automates multilingual audio content creation for content creators, educators, and marketing teams distributing materials globally. It solves the challenge of producing high-quality, tra

OpenAI, HTTP Request, Google Drive +1