Engineers paste API keys, connection strings and passwords into Slack and Microsoft Teams to get unblocked, and those messages stay searchable by every member of the conversation for as long as retention allows. MITRE ATT&CK tracks this as its own technique, T1552.008 Unsecured Credentials: Chat Messages, because attackers who gain a single chat account search it for credentials before anything else. This runbook shows how to find secrets already sitting in Slack and Teams history using the exports and APIs each platform provides, how to switch on native DLP to catch new ones, and how to rotate and then remove what you find without breaking legal holds. It is for security engineers, collaboration platform admins and incident responders. For hardening the platforms themselves, see the Collaboration Tool Security Guide.
This is an independent guide from NHI Mgmt Group, based on Slack and Microsoft documentation read on 11 November 2026. Plan and licence requirements change; check them for your tenant before you start.
Key takeaways
- Rotate, then delete. A credential that was posted in chat has been seen by an unknown number of people and integrations; deleting the message does not un-expose it.
- Coverage depends on plan. Slack native DLP needs an Enterprise subscription, and full Slack exports of private channels and DMs need Business+ approval or Enterprise. Teams chat DLP needs an E5-family licence.
- History and new messages need different tools. DLP evaluates messages as they are sent; finding what is already there means export, API or eDiscovery search plus a secret scanner.
- The search tooling is itself privileged. Exports,
Chat.Read.Alland eDiscovery roles can read every conversation, so scope, log and remove them when the work ends. - Holds win over clean-up. Legal holds and retention policies keep Teams messages after deletion; coordinate with legal before purging.
When you need this
- Chat account compromise: an attacker had a user session or token; you need to know which credentials they could have read.
- Leak found in chat: a secret scanner, a bug bounty report or a colleague found a key in a channel; you need to know how many more there are.
- Programme baseline: you are extending secret scanning beyond code repositories to collaboration tools. People also paste keys into AI chat tools; the OmniGPT Breach Claim centred on API keys users had pasted into chat conversations.
- Before migration or retention changes: moving tenants, enabling longer retention, or granting an AI assistant access to message history.
Before you start
| Need | Slack | Microsoft Teams |
|---|---|---|
| Native DLP for new messages | Enterprise subscription; DLP admin system role, assigned by org primary owners or admins | Microsoft Purview DLP with the location "Teams chat and channel messages"; E5-family licence for chat DLP |
| Bulk read of history | Export: public channels on all plans; all channels and DMs on Business+ (application approved by the primary owner) or Enterprise (requested separately; Export admin role) | Teams Export APIs with application permissions Chat.Read.All and ChannelMessage.Read.All, admin consent, protected API access |
| Targeted search | search.messages with a user token and search:read (only what that user can see) | Purview eDiscovery search over the mailboxes that store Teams messages |
| Removal | DLP dashboard delete for flagged messages; message owner or admin deletion | eDiscovery purgeData with purgeAreas set to teamsMessages; Organization Management role group |
Get written approval naming the scope, because these steps read private conversations. Many jurisdictions and works councils have rules on monitoring employee communications; involve legal and HR first. Run all processing on an isolated, encrypted host, and redact scanner output.
Step-by-step: Slack
- Turn on native DLP first (Enterprise): as a DLP admin, open Organisation settings > Security > Data loss prevention and create a rule from the preconfigured secrets (APIs and tokens) category. Start with the action that only creates a dashboard alert, review alerts for a week, then move to warning the member or hiding (tombstoning) the message until review. Slack's documentation does not say that rules scan existing messages, so treat DLP as forward-looking.
- Add custom rules for internal token formats using Use custom regular expression (PCRE syntax). Prefix-based patterns, such as a fixed internal token prefix, keep false positives low.
- Know the gaps: Slack DLP does not inspect non-text files, files over 100 MB, link previews, channel names or externally hosted files, so screenshots of keys and attached archives need a different route.
- Export history: request the export type your plan allows. On Enterprise, a custom export can filter by conversation type, member or workspace, which keeps the dataset smaller. Exports are JSON.
- Scan the export with a file scanner, for example
trufflehog filesystem <export directory>orgitleaks dir <export directory> --redact, and record channel, timestamp and author for each finding from the surrounding JSON. - Targeted search when export is not possible:
search.messageswith a user token holdingsearch:readsupports modifiers such asin:andfrom:, returns up to 100 results per page, and is rate limited at Tier 2. Search for provider prefixes and words such as "password", "token", "BEGIN PRIVATE KEY". Results only cover conversations that user can see, and Slack marks the method as legacy, so prefer exports for completeness. - Review DLP alerts daily on the Alerts tab, where admins can delete flagged messages or restore hidden ones. Alerts expire after 90 days, so export or ticket anything you need to keep.
Step-by-step: Microsoft Teams
- Create a DLP policy in Microsoft Purview: Data loss prevention > Policies, choose the Teams chat and channel messages location, and use the All credentials sensitive information type bundle. It groups 41 credential types including Amazon S3 Client Secret Access Key, Microsoft Entra Client Secret, Azure Storage Account Access Key, Azure SQL Connection String, GitHub Personal Access Token, Google API key, Slack Access Token and X.509 Certificate Private Key.
- Start in audit, then enforce: run the policy with policy tips and incident reports only, check matches for a week, then block. Policy changes take around an hour to reach users.
- Cover files: files shared in Teams live in SharePoint and OneDrive, so include those locations in the same policy, or keys in attached text files and spreadsheets are missed.
- Understand cross-tenant rules: in shared channels each message is evaluated against the sender's home-tenant policy; in external chats the hosting tenant's policy applies. Your policy does not protect messages your users send into another organisation's chat.
- Read history with the Export APIs:
GET /users/{id}/chats/getAllMessagesfor 1:1, group and meeting chats andGET /teams/{id}/channels/getAllMessagesfor channel messages, filtered onlastModifiedDateTimeand paged by following@odata.nextLink. Without a payment model declaration, apps run in a limited evaluation mode, so plan volume. User-deleted messages remain available for up to 21 days. - Scan the exported message bodies with the same scanner and redaction settings as Slack, keeping chat ID, message ID, sender and timestamp with each finding.
- Use eDiscovery for targeted questions: a Purview eDiscovery search over the relevant mailboxes finds Teams messages by keyword and date. One-to-one and group chats are stored in participants' mailboxes, standard and shared channel messages in the team's mailbox, and private channel messages in members' mailboxes.
What to search for
Scanners handle most formats, but targeted searches and custom DLP rules need explicit terms. These well-known formats give high-confidence starting points:
| Secret type | Search term or prefix | Notes |
|---|---|---|
| AWS access key ID | AKIA | The paired secret key has no prefix; check the surrounding message |
| GitHub tokens | ghp_, github_pat_ | Classic and fine-grained personal access tokens |
| Slack tokens | xoxb-, xoxp- | Bot and user tokens, often pasted while debugging an app |
| Private keys | BEGIN PRIVATE KEY, BEGIN OPENSSH PRIVATE KEY | Often in code blocks or attached text files |
| Connection strings | Password=, AccountKey=, :// with @ | Database and storage strings with embedded credentials |
| Free-text passwords | "password", "pwd", "creds" | Noisy; use for targeted incident searches, not DLP blocking |
Choosing the approach
| Approach | Finds history | Prevents new leaks | Privilege needed | Best for |
|---|---|---|---|---|
| Native DLP (Slack Enterprise, Purview for Teams) | No (forward-looking) | Yes: warn, hide or block | DLP admin roles | Every organisation that has the licence |
| Full export plus scanner | Yes, most complete | No | Export admin or primary owner approval (Slack); Chat.Read.All and ChannelMessage.Read.All (Teams) | Baselines and post-compromise reviews |
Targeted search (search.messages, eDiscovery) | Partly: keyword and scope bound | No | A user's own view (Slack); eDiscovery roles (Teams) | Incident questions such as "where was this key posted" |
| Third-party scanning integration | Depends on product | Often | A broad OAuth app or admin grant | Organisations without native DLP licences, after a vendor risk review |
Small organisations on Slack Pro or Microsoft 365 E3 cannot use native chat DLP: do a one-off export and scan of public channels, publish a clear "never paste secrets" rule with an approved sharing tool, and rely on short-lived credentials. Large organisations should enable native DLP everywhere first, then run a full historical scan once, scoped by risk (engineering, operations and support channels first). Any third-party integration that reads all messages is a high-value non-human identity in its own right; see the How to audit Slack apps, bots and tokens runbook.
Remediate what you find
- Triage: check whether each credential is live, preferably with the provider's own console or the owner rather than automated verification from your scanning host. Prioritise production cloud keys, CI tokens and database credentials.
- Rotate: revoke and reissue through the owning team. Follow the Leaked Credential Response Playbook and check provider logs for use of the old value between the post time and revocation.
- Delete the message: in Slack, delete flagged messages from the DLP dashboard, or ask the author. A bot token can only delete messages its own app posted, and a user token only what that user could delete in the client, so admin clean-up of others' messages goes through the dashboard or the author. In Teams, run
purgeDataon an eDiscovery search withpurgeAreasset toteamsMessages; Teams messages are permanently deleted whicheverpurgeTypeyou choose, and the call removes at most 100 items per location per request. - Respect holds: Teams messages under legal hold or retention policy are retained after deletion. Agree with legal whether the record must be kept; if so, rotation is the control and deletion is not.
- Tell the author why: a short, blame-free note with the approved way to share secrets prevents repeats better than silent deletion.
Verify it worked
- Re-run the search or eDiscovery query and confirm the messages no longer return.
- Confirm the old credential fails at the provider.
- Post a revoked test key in a test channel and confirm the DLP rule fires with the expected action.
- Confirm export files, API app credentials and temporary eDiscovery role assignments created for this work have been deleted or removed.
Metrics:
- DLP coverage: share of workspaces, teams and conversation types covered by an enforced credentials rule.
- Secrets detected per month by DLP, which should fall as habits change.
- Time to rotate: median hours from detection to revocation of live credentials.
- Historical backlog: live credentials found in history and not yet rotated.
- Repeat posters: authors with more than one finding in a quarter, a signal that a team lacks an approved secret sharing tool.
Common failure patterns
- Deleting without rotating: the message disappears but the key keeps working, and it may already be in exports, notification emails or a connected app's copy.
- DLP in alert-only mode forever: alerts expire after 90 days in Slack and nobody owns the queue.
- Ignoring files and images: keys in screenshots, attached logs and archives fall outside text DLP rules.
- Leaving the search identity behind: the app registration with
Chat.Read.Allor the export admin role stays in place after the project, creating a new standing path to every conversation. - Bot and webhook messages overlooked: CI and alerting integrations post connection strings and tokens into channels; scope DLP to messages from integrations too, and fix the integration at source. See ChatOps Security.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | T1552.008 Unsecured Credentials: Chat Messages; T1213.005 Data from Information Repositories: Messaging Applications | The behaviour this runbook detects and removes |
| NIST SP 800-53 Rev 5 | IA-5 Authenticator Management; AU-6 Audit Record Review, Analysis, and Reporting | Protection and rotation of exposed authenticators; review of DLP alerts |
| NIST CSF 2.0 | PR.AA-01; DE.CM-09; PR.AT-01 | Managed credentials; monitoring of data in software; awareness for staff who share secrets |
| CIS Controls v8.1 | 3.13 Deploy a Data Loss Prevention Solution | Native chat DLP and its coverage |
| ISO/IEC 27001:2022 Annex A | A.5.17 Authentication information; A.8.12 Data leakage prevention | Rules for handling secrets; DLP measures on collaboration channels |
Practitioner checklist
- Get legal and HR approval before reading message history.
- Enable Slack Enterprise DLP with the secrets category and Purview DLP with All credentials on Teams chat and channel messages.
- Add custom rules for internal token prefixes.
- Run a one-off historical export and scan, starting with engineering and operations channels.
- Rotate every live credential before deleting messages.
- Check legal holds before purging Teams messages.
- Remove export roles, app permissions and eDiscovery roles when the work ends.
- Give teams an approved way to share secrets so chat is not the easiest route.
- Report DLP coverage, detections and time to rotate monthly.
Standards and references
- Slack: Slack data loss prevention
- Slack: Export your workspace data
- Slack Developer Docs: search.messages method
- Microsoft Learn: Data loss prevention and Microsoft Teams
- Microsoft Learn: All credentials sensitive information type
- Microsoft Learn: Export content with the Microsoft Teams Export APIs
- Microsoft Graph: ediscoverySearch purgeData
- MITRE ATT&CK: T1552.008 Chat Messages
Related NHI Mgmt Group resources: Collaboration Tool Security Guide · Slack Enterprise Security Guide · Microsoft Teams Security Guide · Data Loss Prevention (DLP) Guide · Developer Secret Scanning Triage