A Slack token is a key to an organisation's conversations, files and people, and unless token rotation is turned on, Slack bot and user access tokens never expire. Every Slack app, bot, workflow and internal script authenticates with one of several token types, each identified by a prefix such as xoxb-, xoxp- or xapp-. A user token posted in a public repository can read whatever its owner can read; a bot token with broad scopes can read every channel the bot has joined. This guide explains how Slack token types differ, who can install apps and approve scopes, how to store, rotate, restrict and revoke tokens, and what to log. It is written for Slack administrators, developers who build Slack apps, and security teams responsible for SaaS and NHI governance.
Key takeaways
- Prefer bot tokens over user tokens. Bot tokens belong to the app installation, not a person, so the app keeps working when the installer leaves and the token cannot see that person's private messages.
- Turn on token rotation for new apps. With rotation, access tokens expire every 12 hours and are renewed with a single-use refresh token; without it, they never expire. Rotation cannot be turned off once enabled, so test first.
- Restrict token use by IP address. The Restrict API Token Usage setting rejects Web API and SCIM API calls from outside up to 20 allowed IPv4 ranges with
invalid_auth. - Control installs, not just tokens. Require app approval, classify scopes by risk and approve only the scopes an app needs; scopes are additive and cannot be removed from a token without revoking it.
- Retire legacy tokens. Legacy custom integration tokens carry the full scope of the user who created them and workspace tokens were fully deprecated in August 2021; replace both with granular bot apps.
How identity and access work in Slack
Slack apps are the unit of non-human identity. An app is installed into a workspace or, on Enterprise plans, an entire organisation, and the installation yields tokens. A bot token acts as the app's bot user and sees only what the bot is allowed to see, such as channels it has joined. A user token acts on behalf of the person who authorised it, with that person's visibility, limited by the user scopes they approved. An app-level token represents the app across every organisation where it is installed and is used mainly for Socket Mode connections.
Scopes are requested in the OAuth v2 flow: bot scopes in the scope parameter and user scopes in the user_scope parameter of https://slack.com/oauth/v2/authorize, with the temporary code then exchanged at oauth.v2.access using the app's client secret. Slack's documentation states that scopes are additive across installs and cannot be removed from an existing token without revoking it. Every reinstall that asks for a new scope therefore permanently widens the token until you revoke it.
Token types at a glance
| Token | Prefix | Represents | Lifetime | Main risk if leaked |
|---|---|---|---|---|
| Bot token | xoxb- | The app's bot user in one installation | Never expires unless token rotation is enabled (then 12 hours) | Reads and posts in every channel the bot can access, within its scopes |
| User token | xoxp- | The authorising user | Never expires unless token rotation is enabled | Reads private channels and direct messages the user can see, if scoped |
| App-level token | xapp- | The app across all its installations | Does not expire by default | Receives the app's events over Socket Mode |
| Rotating app-level token | xoxe.xapp- | As above, for rotation-enabled apps | 12 hours, with a single-use refresh token | Short exposure window |
| Workflow token | xwfp- | A subset of bot permissions for one workflow run | 15 minutes, or until the function step finishes or errors; cannot be refreshed | Low: very short-lived |
| Configuration token | Not documented on the token page | A user and workspace, for the App Manifest APIs | Not stated in the token overview | Creating or changing apps |
| Service token | Not documented on the token page | A long-lived user token for Deno Slack SDK apps and Slack CLI actions | Does not expire; not rotatable | Long-lived user-level access |
| Legacy custom integration and workspace tokens | Varies | The creating user's full scope, or a deprecated workspace app | Long-lived | Broad access; replace |
Slack also issues app credentials that are not access tokens but must be protected the same way: the client secret (used in the OAuth exchange), the signing secret (used to verify that requests came from Slack) and incoming webhook URLs, which are channel-specific and tied to the app's identity. User tokens created before August 2016 may have 6 or 10 character secrets; Slack provides oauth.v2.beginShortTokenRotation and oauth.v2.completeShortTokenRotation to rotate them once to longer secrets.
Admin roles and privileged access
In Slack, privilege over tokens is mostly privilege over apps: who may install them, who approves scopes, and who can create apps that hold admin scopes.
| Role | Relevant powers | Control to apply |
|---|---|---|
| Primary Owner | Transfers primary ownership; deletes the workspace | Named executive account with phishing-resistant MFA through SSO |
| Org Owner and Org Admin (Enterprise) | Set app management policies; approve or restrict apps org-wide; Org Owners configure SSO | Small, named group; review membership quarterly |
| Workspace Owner and Admin | Install apps and manage app settings; approve or restrict apps not already decided at org level | Limit numbers; route installs through approval |
| Members | Install apps and build workflows unless approval is required | Turn on Require App Approval |
| Security Admin, Audit Logs Admin, Roles Admin (system roles, Enterprise) | Manage sessions and deactivate accounts; read audit logs; assign system roles | Delegate these instead of granting Org Admin |
- Admin scopes are the crown jewels: on Enterprise plans, apps holding
admin.*scopes (for exampleadmin.apps:write) orauditlogs:readmust be installed by an Org Owner or admin on the organisation itself, and they use user tokens. A leaked token from such an app can approve apps, manage users or read the whole audit trail. Store these in a secrets manager with the tightest IP restriction you have. - Approve scopes explicitly: the
admin.apps.approvemethod grants all requested scopes, including optional ones, if you omitbot_scopesanduser_scopes. Pass them deliberately. - Configuration tokens create apps: they belong to a user and can create and change apps through the App Manifest APIs, so treat them as privileged and keep them out of shared scripts.
See the SaaS and OAuth App Governance Guide for the wider approval model, and the HubSpot Security Guide for the same problem with CRM integration tokens.
Integrations, API tokens and service accounts
Choosing the right token for each integration removes most of the risk before any monitoring is needed.
| Need | Use | Avoid | Why |
|---|---|---|---|
| Posting alerts to one channel | Incoming webhook or a bot token with chat:write | A user token | Narrowest identity and scope |
| A bot reacting to events behind a firewall | Socket Mode with a rotating app-level token plus a bot token | A public HTTP endpoint without signature checks | No inbound endpoint; events arrive over a pre-authenticated WebSocket |
| A bot reacting to events over HTTP | Bot token plus signing secret verification | Deprecated verification tokens | Signed requests resist forgery and replay |
| Reading a user's own data at their request | User token with minimal user scopes and rotation | Legacy custom integration tokens | Legacy tokens carry the user's full scope |
| Internal tool for one workspace | Single-workspace app with minimal bot scopes | A personal token generated by an engineer | Survives staff changes and can be reviewed |
| Org administration and audit export | Dedicated org-installed app with admin.* or auditlogs:read, IP restricted | Reusing a general-purpose bot | Separates the most privileged token |
Storage and transmission
- Keep tokens server-side: Slack's guidance is to store tokens in a database linked to the owning workspace and user, never expose them to end users or error messages, and never log them outside that store.
- Use a secrets manager in production: inject tokens at build or runtime from a secrets manager; locally, keep them in an
.envfile listed in.gitignore. - Send tokens in headers or POST bodies: Slack says never to pass tokens in the query string of a GET request. For Socket Mode,
apps.connections.opentakes the app-level token in theAuthorizationheader. - Delete when done: remove tokens from production systems and backups when a user or integration is deleted.
Token rotation
Token rotation applies to granular bot tokens, user tokens and app-level tokens. Once enabled, an access token expires every 12 hours and the app exchanges a single-use refresh token for a new access token and a new refresh token. The app must keep doing this for its whole life or it stops working. The Bolt framework handles the refresh automatically. For app-level tokens, enable it in the Token rotation section of app settings or with settings.app_level_token_rotation_enabled in the manifest; tokens created before rotation was enabled keep working as before, so revoke them after migration. Slack states that rotation cannot be turned off once enabled, so test on a development app first.
Revocation
The auth.revoke method revokes the token passed to it; test=1 checks the call without revoking. Revoking a bot token deactivates the bot user and removes its channel memberships but does not uninstall the app: use apps.uninstall for a workspace app, and remove org-wide apps in the admin console. When you regenerate a client secret, Slack notes the previous one stays valid for 24 hours unless revoked, so revoke it explicitly after a leak.
Logging and detection
Most token telemetry in Slack depends on plan. On Enterprise plans, the Audit Logs API (an app with the auditlogs:read user scope, installed on the organisation by the Org Owner) returns events such as user_login and file_downloaded. Events triggered by an app carry a context.app object with the app's ID, name, user and bot scopes, and creator, which lets you attribute actions to specific integrations. Slack also runs anomaly detection and surfaces results in the audit logs, and credential resets by Slack security show the actor USLACKSECURITY.
| Signal | Source | Why it matters |
|---|---|---|
| App installed, scopes expanded or app approved | Audit logs; app_requested events to an approval app | New or wider token access |
| App activity outside expected patterns (bulk file downloads, many channels read) | Audit log events with context.app | Stolen bot or user token in use, MITRE ATT&CK T1213.005 Messaging Applications |
invalid_auth errors in your app's logs | Application logs | Calls from outside the IP allowlist, or a revoked token still in use |
| Slack token patterns in code, tickets and chat | Secret scanning on xoxb-, xoxp-, xapp-, xoxe. | Leak before abuse |
| Signature verification failures | Request handler logs | Forged requests or a leaked signing secret |
Metrics that show it is working
- Percentage of apps using bot tokens only, with no user scopes.
- Percentage of internal apps with token rotation enabled.
- Number of legacy custom integration or workspace tokens still active (target: zero).
- Percentage of internal apps with Restrict API Token Usage configured.
- Median time from a Slack token leak alert to
auth.revoke. - Apps without a named owner at the last quarterly review (target: zero).
Hardening baseline
- Inventory apps and tokens: list installed apps, their scopes and owners from the admin console, and find every place their tokens are stored. Flag user tokens, legacy tokens and apps with
adminor message-history scopes. - Turn on app approval: in the organisation dashboard go to Workspaces, Manage, Manage apps, App Management Settings, and enable Require App Approval. Assign App Managers, classify scopes as always allowed (for example
chat:write), requires approval (for exampleusers:read) or restricted (for exampleadmin), and decide which optional scopes users may grant. - Restrict token usage by IP: under OAuth & Permissions, Restrict API Token Usage, add up to 20 IPv4 CIDR ranges or addresses for each internal app. Pilot on one app, watch for
invalid_auth, then roll out; rollback is removing the range. - Enable rotation on new and rebuilt apps: use Bolt or an equivalent refresh loop, test in a sandbox, then enable in production. Revoke the pre-rotation tokens afterwards.
- Verify every request: compute the
v0HMAC SHA256 signature over the timestamp and raw body with the signing secret, compare in constant time withX-Slack-Signature, and reject requests whoseX-Slack-Request-Timestampis more than five minutes from local time. - Retire legacy tokens: rebuild custom integrations as single-workspace granular bot apps and rotate any short-secret user tokens.
- Lock down redirects: configure HTTPS redirect URLs only on domains you control, and after OAuth confirm the user's account belongs to the expected organisation.
- Review quarterly: remove unused apps, reduce scopes by reinstalling with a fresh token, and confirm owners.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | MITRE ATT&CK |
|---|---|---|---|
| Token rotation, storage and revocation | IA-5 Authenticator Management | PR.AA-01 | T1528 Steal Application Access Token |
| Scope approval and app installs | AC-6 Least Privilege; AC-2 Account Management | PR.AA-05 | T1550.001 Application Access Token |
| Leaked tokens in code and files | IA-5 | PR.AA-01 | T1552.001 Credentials In Files |
| Monitoring app activity | AU-6 Audit Record Review, Analysis, and Reporting | DE.CM-03, PR.PS-04 | T1213.005 Messaging Applications |
Common misconfigurations
- Tokens committed to public code: the GitLab Public Repositories Secrets Study 2025 found Slack tokens among 17,430 live secrets, including one committed from a personal email address that unlocked an organisation's workspace. Non-expiring tokens stay valid until someone revokes them.
- User tokens where a bot would do: a user token inherits the person's visibility into private channels and direct messages, and breaks when they leave.
- Scope creep through reinstalls: because scopes are additive, an app that once asked for
channels:historyfor a test keeps it until the token is revoked. - Revoking the token but not the app:
auth.revokeon a bot token leaves the app installed, ready to be reauthorised. - Unverified HTTP endpoints: apps still checking the deprecated verification token, or not checking anything, accept forged slash commands and events.
- Chat as a secret store: credentials pasted into channels end up in exports and search. See the Collaboration Tool Security Guide.
Practitioner checklist
- Inventory every Slack app with owner, token types, scopes and storage location.
- Require app approval, assign App Managers and classify scopes by risk.
- Use bot tokens by default; justify every user scope in writing.
- Configure Restrict API Token Usage on every internal app with fixed egress.
- Enable token rotation on new apps and revoke pre-rotation tokens.
- Verify signing secrets with a five-minute replay window; drop verification tokens.
- Replace legacy custom integration and workspace tokens.
- Scan code, tickets and chat for
xoxb-,xoxp-andxapp-patterns and revoke on detection withauth.revoke. - Stream Enterprise audit logs to the SIEM and alert on app installs and unusual app activity.
Standards and references
- Slack Developer Docs: Tokens
- Slack Developer Docs: Using token rotation
- Slack Developer Docs: Best practices for security
- Slack Developer Docs: Verifying requests from Slack
- Slack Developer Docs: Managing app approvals
- Slack Developer Docs: Audit Logs API
- Slack Help Center: Roles and permissions in Slack
- MITRE ATT&CK: T1213.005 Messaging Applications
Related NHI Mgmt Group resources: SaaS API Token Security Guide · SaaS and OAuth App Governance Guide · OWASP NHI Top 10 NHI7 Long-Lived Secrets Guide · OWASP NHI Top 10 NHI2 Secret Leakage Guide · GitLab Tokens Security Guide