You must enable javascript in order to use the Slack API Documentation. You can do this in your browser settings.
Go to Slack

Safely Storing Credentials

Keeping credentials secure is important whether you're developing open source libraries and tools, custom integrations for your workspace, or Slack apps for distribution to workspaces across the world.

Even if you're not working with OAuth 2.0 and user access tokens, please consider these safety suggestions when working with the Slack Platform.

Practical considerations

Security considerations for Slack apps

As a Slack App developer, you'll be working with credentials issued to you from Slack, as well as token values representing members, workspaces, and specific features of your application.

Client ID and secret

  1. Your Client ID is one piece of information used to identify your application and frequently appears in OAuth negotiation URLs and other contexts. Your Client ID can be shared freely in code and email and cannot be used alone to act on your application's behalf.

  2. Your Client Secret should be treated delicately. It is how you securely identify your application's rights and identity when exchanging tokens with Slack. Do not distribute client secrets in email, distributed native applications, client-side javascript, or public code repositories.

Slack-app based user & bot user tokens

These tokens represent specific access levels granted by the OAuth scopes you negotiated.

Bot user tokens can connect to the real time messaging API and post messages on their own behalf. They can also access a subset of API methods to better understand the channels, members, and messages received as part of its activities.

User tokens, such as those received through the Add to Slack and Sign in with Slack flows are capable only of the permissions granted to it during the OAuth flow using scopes.

Store user and bot user tokens with care and never place them in a public code repository or client-side code like Javascript.

Restricting token use by IP address

One way to build confidence in the sanctity of your user and bot tokens is to lock down their usage to a known set of IP addresses you control.

If you're building an internal integration and have explicitly marked your app as undistributed, you can further limit access to the Web API:

By providing a whitelist of IP addresses, Slack will only accept requests to Web API methods if originating from a listed IP address. If the request matches your whitelist, Slack will execute the request and respond as usual.

If the request originates from an IP address not listed in your whitelist, it will be rejected with this response:

{
  "ok": false,
  "error": "invalid_auth"
}

IP whitelisting only applies to token use against the Web API for internal integrations.

Configuring your whitelist

Navigate to your application management and select the OAuth & Permissions pane. The Restrict API Token Usage section allows you to specify a whitelist of acceptable public IP addresses.

Up to two entries are allowed. Each entry specifies either a CIDR range of IP addresses or a single IP address.

For example:

  • Entering 101.101.101.106 will whitelist only that IP address, which we'll consider as 101.101.101.106/32.
  • Presenting a submask like 101.101.101.0/24 will whitelist all 256 IP address between 101.101.101.0 and 101.101.101.255.

"Local" IP addresses cannot be whitelisted and IPv6 is not supported.


Incoming webhook URLs

Slack app-based incoming webhook URLs allows posting messages only to a specific channel configured by the approving member. Their identity is always tied to the application associated with the URLs and cannot be used as arbitrary users or on unapproved channels.

Redirect URIs

Redirect URIs appear as URLs and are safe to be part of published code. However, ensure that the redirect URIs defined in a public application are limited only to domain names in your direct control.

We recommend that after you complete local development, remove localhost and related domains from your configuration list.

Best practices for Custom Integrations

Developers working with custom integrations have the benefit of each feature having its own credentials and an association with a single workspace. However, without the application permissions enforced by Slack apps, the tokens, URLs, and credentials used by Custom Integrations can be very powerful and require special care.

Incoming webhook URLs

Do not share incoming webhook URLs in public code repositories. Incoming webhook URLs belong to a specific member that installed them. When a webhook is contained within a Slack app, it is scoped to only post as a specific application-associated user and approved channel. Custom integration-based webhooks are capable of posting to any channel and have more flexibly identities.

Compromised incoming webhook URLs can be used to post unwanted, unsolicited, or malicious messages to your workspace.

Slash command tokens

Tokens for slash commands represent a relationship between your application and Slack. Do not store them in public code repositories.

Each application can have only one slash command token, even if they have multiple commands associated with an app. Safely store this token in your environment so that it is known only to your application and to Slack. Slack will use it to identify itself when executing slash command invocation URLs.

Bot user tokens

Custom Integration-based bot user tokens have more capabilities than bot user tokens received through Slack apps. Be especially careful with both kinds of tokens.

Bot user tokens may connect to the real time streaming APIs, and perform a number of other activities, including posting messages. Do not distribute in code repositories or yield to untrusted third parties.

Test tokens

The tokens generated by the OAuth Test Token Generator should never be shared or published externally. They represent all the capabilities of a specific user.

Safe Token Storage

Storing authentication secrets is difficult, and how you do it best depends on context, usage, and design requirements. While it would be super cool if all tokens were encrypted with individual keys controlled by the customers, most implementations do not allow that. Here are some things to consider when storing tokens to ensure that we're doing everything we can to prevent accidental exposure or mix-up of usage.

The actual token

  • Do you need a token to make your functionality work?
    • If not, err on the side of not storing more customer secrets than you need to.
  • Are you asking for a least-privilege token?
    • Most application need only perform a handful of things with a token. Make sure you are requesting the most limited token authorization scopes possible to protect your customers in case of a breach.

Thinking of things in the 7-Layer OSI model

The 7-Layer OSI model breaks out how applications and computers function over a network and can provide a useful model for thinking about security at each layer. By breaking apart each layer, it's possible to look at different risks and mitigations to best apply.

7/6. Application layer and Presentation layer

The Application layer is mostly focused on high-level APIs, and how your application exposes itself to an end user. Here are some things to consider:

  • Don't expose the token to the end user once it is stored in a database
    • Ensure there is no functionality that echoes back tokens (or any other customer secrets) to the user. Check your error scenarios especially. Unless this is absolutely required, consider creating a middleware layer to facilitate the usage of a stored token without storing it within your application code.
  • Lock down the usage of your application itself to prevent misuse of the token
    • Think about OWASP Top 10 Web Vulnerabilities such as XSS, CSRF, SQLi
    • Can an attacker abuse your application's functionality to gain access to a token? or trigger functionality that may be undesirable functionality?
  • Think about rate-limiting
    • Does your application utilize rate-limiting in a way that prevents misuse of a token? Spamming a token can potentially disable that token, leaving your integration in an erroneous state.
  • Use a database to store tokens, and do not hard-code any tokens into code
  • Don't consume tokens via the query string of a URL via a GET request. Always use a POST request when transmitting secrets over HTTP

5. Session layer

  • Store tokens in a way that directly links them to the owner (workspace and user)
  • Ensure that if a user deletes their account, data, or integration, that you also delete that token from your production systems, and backups
  • If you no longer have need for a customer's token, delete it immediately from all production systems and backups
  • Make sure that there is absolutely no way to expose one users token (or the functionality of that token) to another user on accident
  • Ensure that your sessions on your application utilize best practices on session id generation, and test for the ability of one session to know about our see the contents of another user's session. (ensure that any debug functionality for user impersonation among other things does not exist in your application)

4. Transport

  • Ensure you are using proper TLS to encrypt all traffic between you and the customer; you and the service you're using the token with to ensure the token never gets transmitted unencrypted across the wire
    • Make sure you do not have any "Ignore SSL/TLS Errors" in your application code
    • If you have a web-facing service, ensure that you do not have any mixed content, and that your certificate setup is proper and supports modern cryptographic standards.
  • Once your application has knowledge of a user token, ensure that you are not logging it, or moving it in any way outside of your application's database

3-1. Network, Data Link, Physical

These layers encompass most of the non-application-based internet-plumbing, including protocols such as TCP, IPv4, MAC, and Ethernet. We're going to assume for safe token usage and storage that these layers are already secured, however there are a few points to consider, especially if you are hosting in the cloud.

  • If you are using a cloud provider (AWS, DigitalOcean, Heroku, etc), make sure that your account has two-factor authentication enabled, and that you are using strong passwords
    • Make sure that the only accounts with access to your production systems actually need that access
  • If you are backing up your data, ensure that you are storing it in a safe location that is locked down. Unsecured backups are easy targets for attackers to practically steal most if not all of your application's data and secrets
  • If your application is not web based, but based on a computer or mobile device, ensure that you are using that platform's guided advice on how to store secrets. You should never have an instance in which you are writing a token to disk in plaintext when there is a system keychain or other encryption mechanism available.