Most Slack workspaces have accumulated apps, bots, legacy integrations and tokens that nobody owns, and any of them can read or post into channels long after the person who installed them has left. An audit answers three questions: what is installed, what each app can do, and which tokens are still live. This page is a hands-on procedure for Slack workspace and Enterprise organisation administrators: the read-only inventory you run first (admin pages and Web API methods documented by Slack), how to judge risk from scopes, how to remove apps and revoke tokens safely, and how to stop the backlog returning. It assumes you know the token types; if not, read the Slack Tokens Security Guide first.
Key takeaways
- Inventory before you remove anything. Build the app list from the admin pages and API calls, export it, and assign an owner to every row before the first uninstall.
- Scopes are the risk signal. An app that can read message history in private channels or direct messages, or holds admin scopes, is in a different class from one that only posts to a channel.
- Restricting an app is not removing it. Slack states that restricting an app that is already installed does not stop existing members from using it; you must uninstall it or revoke its tokens.
- Uninstall and revoke are different actions. auth.revoke kills one token; apps.uninstall revokes every token for that installation; admin.apps.uninstall removes an app across Enterprise workspaces and cannot be undone.
- Make it continuous. Require app approval, pull the integration log and audit log on a schedule, and re-review high-risk apps at least quarterly.
When you need this
- Routine governance: a quarterly or half-yearly access review of SaaS non-human identities. Slack apps and bots are exactly that: identities with standing access to conversations and files.
- After a vendor incident: any token you gave a vendor lives in their environment. In the Slack GitHub breach, a small set of employee tokens stolen from a third-party vendor was enough to download private repositories. When a connected vendor reports a breach, audit and rotate that vendor's Slack access the same day.
- A leaked token: a xoxb- or xoxp- token found in a repository, ticket or log. Follow the Work SaaS API tokens leak response, then run this audit to find similar exposure.
- Leaver and reorganisation events: apps installed with a user token act as that user; when the user leaves, the app may break or, worse, keep a token tied to an account you are trying to close.
- Before tightening policy: switching on app approval without an inventory produces a flood of requests and broken workflows.
Before you start
| Item | What you need | Notes |
|---|---|---|
| Role | Workspace Owner or Admin; Org Owner or Admin on Enterprise | team.integrationLogs can only be called by Admins |
| Audit app (Enterprise) | An internal app installed on the organisation (not a single workspace) with user token scopes admin.apps:read and auditlogs:read | Slack requires auditlogs:read apps to be installed by the organisation Owner |
| Audit app (other plans) | A user token with the admin scope for team.integrationLogs | Admin and Audit Logs API methods are Enterprise-only |
| Token storage | Store the audit token in your secrets manager, never in a script or notebook | It is itself a high-value token: scope it read-only and restrict it by IP |
| Change record | A change ticket for removals, with app owners informed | admin.apps.uninstall cannot be undone; users must reinstall |
Everything in step 1 to 4 below is read-only. Steps 6 and 7 are destructive and are flagged.
Step-by-step
- Export the admin view (read-only). In the desktop app, open Admin, then Apps and workflows. Record every installed app, custom integration and workflow app, with the installer and installation date. On Enterprise, check both the organisation level and each workspace, because apps can be installed at either.
- Pull the integration history (read-only). Call
team.integrationLogswith an admin user token. Each log entry can carry app_id, app_type, service_id, user_id, user_name, channel, date, change_type and scope. Change types in responses are added, removed, enabled, disabled, expanded and updated. Filter withapp_id,userorchange_type(the filter accepts added, removed, enabled, disabled and updated), and page withcountandpage. Entries with change_type expanded show where an app was reinstalled with more scopes. - On Enterprise, pull approvals and requests (read-only).
admin.apps.approved.listandadmin.apps.restricted.listgive the approved and restricted lists, either per workspace (team_id) or organisation-wide (enterprise_id), but not both in one call;limitruns to 1000 with cursor paging.admin.apps.requests.listshows pending requests, and each requested scope carries anis_sensitiveflag, the token type and whether it is approved. - List bot users and their channels (read-only). Use the Web API
users.listmethod and keep members whereis_botis true, then check which private channels each bot has joined. A bot token can read what its bot user can see within its scopes, so a bot in a sensitive private channel is in scope for that channel's data. - Score each app (read-only). Classify it with the table below, record its owner and business purpose, and mark it keep, reduce, replace or remove. Treat apps with no owner after two attempts at contact as remove candidates.
- Revoke individual tokens (destructive). For tokens you hold, such as a leaked internal script token, call
auth.revoke. Run it first withtest=1, which Slack documents as a testing mode that does not revoke, then for real; the response fieldrevokedconfirms the result. Slack notes that revoking a bot token does not uninstall the app, but it deactivates the bot user and removes its channel memberships. - Uninstall apps (destructive). For your own app,
apps.uninstallwith the app's client_id and client_secret revokes all tokens for that installation. On Enterprise,admin.apps.uninstall(scope admin.apps:write) with theapp_idand exactly one ofteam_ids(up to 100) orenterprise_idremoves it, and Slack states this cannot be undone. For third-party apps on other plans, remove the app from the Apps and workflows admin pages. - Restrict what you removed. Mark removed apps as Restricted (Admin, Apps and workflows, Browse, select the app, Restrict) so the same app is not reinstalled without review.
Scoring apps by scope
| Risk | Examples of what the app can do | Review action |
|---|---|---|
| Critical | Admin scopes (admin.*), audit log access, user tokens that can read private channels or direct messages | Named owner, documented purpose, IP restriction, quarterly review; remove if either is missing |
| High | Read history in public channels the app is not invited to, read files, read user emails | Confirm the vendor's data handling and security review; reduce scopes where the vendor supports it |
| Medium | Read and write in channels the bot is invited to | Check which private channels the bot has joined |
| Low | Incoming webhook or post-only bot | Confirm owner; webhook URLs are still secrets |
| Legacy | Legacy custom integration tokens, apps installed by departed users | Replace with a granular bot app or remove |
Slack's documentation states that scopes are additive across installs and cannot be removed from an existing token without revoking it. Reducing an app's scopes therefore means reinstalling it with a narrower request after revoking the old token, not editing it in place.
Verify it worked
- Token is dead: a call to
auth.testwith the revoked token returns an error such as invalid_auth or token_revoked. - App is gone: it no longer appears under Apps and workflows, and team.integrationLogs shows a removed entry for its app_id.
- Bot is out of channels: the bot user is deactivated or no longer a member of the private channels you recorded.
- No reinstall: the app appears in admin.apps.restricted.list (Enterprise) or as Restricted in the admin pages.
- Business still works: owners of retained apps confirm their integrations ran after the change window.
Rollback and common errors
Rollback
There is no undo for a revoked token or an Enterprise uninstall: Slack requires a fresh install, which issues new tokens. Plan for that rather than against it.
- Before step 6 or 7, note for each app the installer, the workspaces, the channels the bot was in and any configuration in the app itself.
- To restore, the owner reinstalls through the approval flow, requesting only the scopes now agreed.
- Update the integration with its new token from the secrets manager, and re-invite the bot to the agreed channels.
Common errors
| Symptom | Likely cause | Fix |
|---|---|---|
| admin.apps.* returns an error about scope or installation | Audit app installed on one workspace, not the organisation | Reinstall the audit app at organisation level |
| admin.apps.approved.list rejects the call | Both team_id and enterprise_id passed | Use one or the other |
| Restricted app still in use | Restriction does not affect existing installs | Uninstall it as well |
| Bot still posts after token revoked | Another token for the same installation, or an incoming webhook URL | Uninstall the app to revoke all tokens; remove webhooks |
| Integration broke after a user left | App ran on that user's token | Rebuild on a bot token owned by the app installation |
| Audit log calls fail on a non-Enterprise plan | Audit Logs API is Enterprise-only | Use team.integrationLogs and the admin pages |
Hardening afterwards
- Require approval: Admin, Apps and workflows, App Management Settings, Edit next to Require approved apps, then Only allow pre-approved apps. Name app managers under Select App Managers so requests do not queue on Workspace Owners alone.
- Collect the logs: on Enterprise, pull the Audit Logs API (base URL https://api.slack.com/audit/v1/, read-only GET) into your SIEM and alert on app installs, scope expansions and approvals; use the API's actions endpoint for the current action names. On other plans, pull team.integrationLogs daily and alert on added and expanded entries.
- Watch workflow apps: on Enterprise,
admin.apps.activities.list(scope admin.app_activities:read) returns workflow, function and trigger events, including external_auth_token_fetch_result for workflows that use stored third-party tokens. - Shorten token life: turn on token rotation for apps you build, so access tokens expire every 12 hours, and restrict API token usage to your egress IP ranges. See the Slack Tokens Security Guide.
- Scan for tokens: enable secret scanning in source control for Slack token prefixes. See the Git Secret Scanning Guide.
- Measure: track the percentage of apps with a named owner, the number of apps holding critical scopes, apps installed by departed users, median approval time and days since each high-risk app was last reviewed.
Framework mapping
| Framework | Reference | How the audit supports it |
|---|---|---|
| NIST CSF 2.0 | ID.AM-02, PR.AA-05, DE.CM-09, GV.SC-07 | Inventory of software and services; least privilege; monitoring; third-party risk across the relationship |
| NIST SP 800-53 Rev. 5 | AC-2, AC-2(3), AC-6, AU-6, CM-8, SA-9 | Account management and disabling, least privilege, audit review, component inventory, external services |
| MITRE ATT&CK | T1528, T1550.001, T1213.005 | Stolen and reused application access tokens; collection from messaging applications |
Practitioner checklist
- Export installed apps, integrations and workflow apps at organisation and workspace level.
- Pull team.integrationLogs and flag expanded entries.
- On Enterprise, pull approved, restricted and pending request lists.
- List bot users and the private channels they belong to.
- Score every app by scope and assign a named owner.
- Revoke tokens with auth.revoke (test mode first) and uninstall unowned apps.
- Restrict removed apps so they cannot be reinstalled without review.
- Turn on app approval and name app managers.
- Send integration or audit logs to the SIEM with alerts on installs and scope expansion.
- Schedule the next review and track owner coverage and critical-scope counts.
Standards and references
- Slack: team.integrationLogs method
- Slack: admin.apps.approved.list method
- Slack: admin.apps.requests.list method
- Slack: admin.apps.uninstall method
- Slack: auth.revoke method
- Slack: Audit Logs API
- Slack Help Center: Manage app approval for your workspace
- MITRE ATT&CK: Steal Application Access Token
Related NHI Mgmt Group resources: Slack Tokens Security Guide · Slack Enterprise Security Guide · SaaS and OAuth App Governance Guide · Shadow SaaS and Unsanctioned App Discovery Guide