Back to blog
SlackMicrosoft TeamsOAuthAI agents

Securing an AI Agent Connected to Slack or Teams

Published on 2026-11-046 min read
In short: an AI agent connected to Slack or Microsoft Teams reads messages written by colleagues, guests and sometimes strangers, and can post in the company’s name. To secure it: limit the channels it can read, grant the narrowest write scope, treat every message and link as untrusted, and require human approval for sensitive sends.

Why is an agent connected to Slack or Teams exposed?

Because a team messaging tool combines private data, content written by third parties and a way to write outward. Researcher Simon Willison calls this combination the “lethal trifecta”: an agent that accesses private data, reads untrusted content and can communicate externally can be manipulated into leaking that data.

The best-documented case is Slack AI. On 20 August 2024, PromptArmor showed that an attacker could post an instruction in a public channel and get Slack AI to produce a Markdown link containing data from a private channel the attacker could not access, for example an API key. Clicking the link sent that data in the query string to the attacker’s server. PromptArmor also described a phishing variant: a “click here to reauthenticate” link. Slack first called the behavior intended, then said it deployed a patch on 20 August 2024.

The lesson applies to any in-house agent: the risk comes from the meeting of broad read access, untrusted content and the ability to produce a link or a message. This is indirect prompt injection, which OWASP ranks as LLM01:2025.

Which Slack scopes should the agent get?

Grant only the scopes that match a specific task. Slack itself describes the scopes as follows:

ScopeWhat Slack says
channels:historyView messages in public channels the app has been added to
groups:historyView messages in private channels the app has been added to
im:historyView messages in direct messages the app has been added to
chat:writeSend messages as the app
chat:write.publicSend messages to channels the app isn’t a member of
files:readView files shared in channels and conversations the app has been added to
search:readSearch a workspace’s content

Three points to keep. The history scopes only cover conversations the app was added to, so the read perimeter is also set by choosing which channels you invite the agent into. chat:write.public lets the app write to channels it was not invited to: avoid it if the agent needs a single channel. And search:read opens search across the whole workspace, which deserves a separate review.

Slack recommends a three-tier scope policy: always allowed (low risk, for example chat:write), requires approval (for example users:read) and restricted (for example admin), with regular audits of the scopes of installed apps.

How do you secure channel reading in Teams?

By default, a Teams agent in a channel or group chat only receives the messages in which it is @mentioned. Microsoft states that to receive all messages, the agent must declare resource-specific consent (RSC) permissions in its manifest: ChannelMessage.Read.Group for the channels of a team, ChatMessage.Read.Chat for a group chat. The team or chat owner must consent at installation.

These permissions do not open other conversations, only all the messages of the ones where the agent is already installed. Microsoft adds that messages from other agents or bots, including the Workflows (Power Automate) bot, are not delivered to your agent. For an agent, this reduces the attack surface.

Microsoft’s Graph best practices point the same way: apply least privilege, prefer RSC, then delegated permissions, and use application permissions only as a last resort, because they grant access to data without a signed-in user and carry the most privacy risk. Microsoft’s own example: to send a message to a chat, the RSC permission ChatMessage.Send.Chat is enough in place of the delegated permission Chat.ReadWrite.

A practical tip to cut noise and surface: filter on messages where the agent is @mentioned, as Microsoft’s documentation shows, when the agent does not need to read the whole thread.

What risks are specific to messages and links?

Three keep coming back: the instruction hidden in a message, the link the agent produces, and the leak through a reply.

  • Instruction in a message. Any member, guest or compromised account can write an instruction into a channel the agent reads. The message is data to read: the agent executes none of its instructions.
  • Markdown link or image. In the Slack AI case, a generated link carried the data out. Forbid the agent from producing links to unlisted domains, and do not render remote images from its output.
  • Reply in a wide channel. An agent that answers in a large channel can republish information read in a restricted one. The reply channel must have a confidentiality level at least equal to the sources read.

Our article on agents connected to Gmail or Outlook covers the same logic for email.

How do you test a Slack or Teams agent?

Test in a test workspace or tenant, with accounts created for the occasion and fictional data. Each test looks for one precise answer.

  1. Rights inventory. List the Slack scopes or Graph and RSC permissions actually granted, and compare them to the functions in use. Any gap is a finding.
  2. Readable channels. Can the agent read a private channel it was not added to, through search or a command? In Teams, does it read outside the teams where it is installed?
  3. Instruction in a channel. In a test channel, post a message asking the agent to repeat a canary token placed in another test channel. Does the canary come out?
  4. Link and image. Through a test message, ask it to produce a link or an image pointing to a test domain with the canary in the URL. Does it comply? Does the client render it?
  5. Out-of-scope writing. Can the agent write to an unplanned channel, use @channel, or send a direct message to a third party?
  6. Files. Does a shared file containing an instruction influence the agent? PromptArmor noted that adding files to Slack AI answers created a new vector.
  7. Human approval. Which actions go out without confirmation: public message, global mention, deletion, invitation?

Which controls should you put in place?

  • Reduce reading: invite the agent only into useful channels, without search:read or chat:write.public unless needed.
  • Separate read and write: an agent that summarises a channel does not need to write, and the reverse.
  • Destination allowlist: write channels and link domains fixed in code and never in the prompt.
  • Human approval for global mentions, direct messages and anything leaving the company.
  • Rotation and revocation of tokens (see our article on an agent’s secrets).
  • Logs of messages read, API calls and sends.

The AI agent security page gives the general framework for these controls.

How can CleanIssue test your Slack or Teams agent?

We reproduce these scenarios in your test space: a booby-trapped channel, a canary, an outgoing link, an out-of-scope write. In the Agent Red Team Express, that is one agent and a defined scope over 5 days, starting within 48 hours of signing the quote and the authorisation. If your Slack or Teams agent is part of a larger set (MCP, email, database), the Custom Red Team is quoted on request.

The first conversation is a free 30-minute discovery call.

Does your product ship an AI agent? CleanIssue tests what a stranger can make it do with the Agent Red Team Express (5 days, €1,900), or a custom red team for several agents and MCP servers. First step: a free 30-minute discovery call.

Know what your agent can do before an attacker does.

A free 30-minute discovery call: you describe your agent, I tell you what I would test and what it costs. Five case studies are published.

Book a call