> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack permissions

> Every permission and event the Slack app Lua sets up asks for, what each one is for, which ones a workspace admin can turn down, and what stops working without them

This page is for the person who approves the app in a Slack workspace. It lists every permission (scope) and event the manifest Lua generates asks for, what the agent does with each, and what happens without it. The bot only ever reads conversations it was added to.

*Verified against lua-cli 3.41.0.*

## Required and optional

Slack lets an app mark permissions as optional, and the app's **OAuth & Permissions** page lists each one with **Required: No**. The agent works without them: a workspace that doesn't grant one only loses that feature. Twelve permissions are required: without them the bot cannot receive a mention or a direct message, know who wrote, or be connected at all. Eight are optional.

Permissions are only ever added. Installing again with a longer list adds the new ones to the same bot token.

## Required permissions

| Permission | What the agent does with it | Without it |
| - | - | - |
| `chat:write` | Posts its replies and shows Slack's "*app* is working…" status | Nothing can be answered |
| `app_mentions:read` | Receives the message when someone @mentions the bot | Mentions in channels only arrive if the channel's own message permission is granted |
| `channels:history` | Receives messages in public channels the bot was added to, and reads a thread's earlier messages the first time it's mentioned there | The bot doesn't follow public-channel threads, and the first answer lacks the thread so far |
| `groups:history` | The same, in private channels the bot was added to | The same, in private channels |
| `im:history` | Receives direct messages sent to the bot | The bot can't be messaged directly |
| `mpim:history` | Receives messages in group DMs the bot is part of | The same, in group DMs |
| `channels:read`, `groups:read` | Reads channel names for conversation titles, lists the channels the bot is in for **Auto-respond**, and learns when the bot is removed from a channel or a channel is renamed | Conversations are titled "Slack channel"; the channel picker in the dashboard is empty |
| `im:read`, `mpim:read` | Reads the type of a direct or group conversation | Direct and group conversations may be misread as channels |
| `users:read` | Reads names and time zones of the people writing, and the bot's own details when connecting | The connection is refused; people appear by their Slack ID |
| `users:read.email` | Matches each person to their Lua account by email, so what they told the agent elsewhere is theirs here too | Each person becomes a separate identity keyed by their Slack ID |

## Optional permissions

| Permission | What the agent does with it | Without it |
| - | - | - |
| `reactions:write` | Puts 👀 on your message while it works and ✅ when it has answered | The "is working…" status still shows; no reaction |
| `files:read` | Opens files people attach to a message | The agent is told an attachment couldn't be opened and says so |
| `files:write` | Not used yet. Asked for now so that sending files instead of links doesn't need another reinstall | Nothing changes today |
| `channels:join` | Not used yet. For posting in a public channel the bot hasn't been invited to | Nothing changes today |
| `reactions:read` | Not used yet. For reading 👍 or 👎 on the agent's answers as feedback | Nothing changes today |
| `team:read` | Not used yet. For reading the workspace's name and domain | Nothing changes today |
| `im:write` | Not used yet. For the agent starting a direct message with someone who hasn't messaged it | Nothing changes today |
| `mpim:write` | Not used yet. For the agent starting a group direct message | Nothing changes today |

What is deliberately not there: `commands` (no slash commands), `users:write`, and every `*:write` scope for channels, user groups or pins.

## Events

Slack sends these to Lua. None of them needs a permission beyond the list above.

| Event | Used for |
| - | - |
| `app_mention`, `message.channels`, `message.groups`, `message.im`, `message.mpim` | The conversation itself |
| `app_uninstalled`, `tokens_revoked` | Noticing the app was removed or its token revoked. Lua asks Slack whether the token still works, and if not the dashboard says **Uninstalled in Slack** instead of showing the bot as connected |
| `channel_left`, `group_left`, `member_joined_channel`, `member_left_channel`, `channel_id_changed`, `channel_rename`, `group_rename` | Received but not acted on yet. Subscribed now so that keeping shared conversations in step with the channel doesn't need another manifest update |
| `app_home_opened` | Received but not acted on yet |

## Signing secret

Every event Slack sends is signed with the app's **Signing Secret** (**Basic Information → App Credentials**). Lua asks for it when you connect and checks each event against it. The first event that matches confirms the secret; from then on Lua rejects any event that doesn't match, so nobody can make the agent act on a forged message. Until that first match, an event that doesn't match is still answered and the dashboard says the secret doesn't match. A wrongly pasted secret never silences a working bot.

## Applying a newer manifest

Lua can't change an app that belongs to your workspace; its owner applies each new version. When a connection lacks a required permission or has no signing secret, the dashboard shows **Update available** on the Slack card:

1. Copy the manifest from the update dialog and paste it under **App Manifest** in Slack, on the **JSON** tab, then **Save Changes**.
2. Save the Signing Secret in the dialog.
3. Reinstall: a public app through **Install in Slack** in the dialog; a private app with the banner Slack shows, or **Install App → Reinstall to Workspace**.
4. Select **Check again**; the card updates once Slack reports the new permissions.

## Next steps

<Columns cols={2}>
  <Card title="Connect Slack" href="/channels/slack">Create the app, connect it, and choose when it answers.</Card>
  <Card title="Teams permissions" href="/channels/teams-permissions">The same page for Microsoft Teams.</Card>
</Columns>
