# Source: https://docs.slack.dev/tools/deno-slack-sdk/guides/following-security-best-practices

# Following security best practices

## Workflow apps require a paid plan

Join the [Developer Program](https://api.slack.com/developer-program) and provision a sandbox with access to all Slack features for free.

Keeping your apps and functions secure is an important part of developing on the Slack platform.

Slack’s managed hosted environment is built on the [Deno](https://deno.land/) runtime, a secure JavaScript runtime. Learn more about Deno’s [permissions model](https://deno.land/manual@v1.32.1/basics/permissions).

Here are some best practices to keep in mind when developing [custom functions](/tools/deno-slack-sdk/guides/creating-custom-functions), [workflows](/tools/deno-slack-sdk/guides/creating-workflows), and [triggers](/tools/deno-slack-sdk/guides/using-triggers) for Slack automations.

## Set appropriate access control levels (ACLs)

- [Limit access](/tools/deno-slack-sdk/guides/managing-triggers#manage) to your [functions](/tools/deno-slack-sdk/guides/creating-custom-functions) and [triggers](/tools/deno-slack-sdk/guides/using-triggers) to only the intended audience. Use the `slack function access` or `slack trigger access` commands to control who can use your functions or trip your triggers.
- Your app collaborators can deploy your functions and manage your workflows and triggers. Only add collaborators to your app that you trust.

## Validate input

- It’s always important to validate inputs to your functions. If you’ve changed the distribution of your function, keep in mind it may be used in other workflows in ways you may not anticipate. Your app collaborators may also create or update triggers to start your workflows.
- When using Slack [datastores](/tools/deno-slack-sdk/guides/using-datastores), avoid [injection attacks](https://owasp.org/Top10/A03_2021-Injection/) by properly sanitizing user input when building queries, and use the `expression_values` and `expression_attributes` fields when querying for data. Also ensure that the user has read access to data from the datastore before processing it.
- Always confirm the user has access to perform whatever operation your function is being asked to perform. In complex workflows, several users may participate in the various steps, so ensure you’re checking the correct user’s permissions. For example, in a contract approval workflow, anyone may be able to request an approval, but only certain approvers may actually provide an approval.
- When listening to [message metadata events](/tools/deno-slack-sdk/guides/integrating-message-metadata-events), keep in mind that many apps may be posting messages with the same event types. If you’d like to listen to messages from only specific apps, use a filter on the `app_id` in the event trigger definition.

## Handle sensitive data

- Secrets needed by your custom functions running on Slack-managed infrastructure should be shared with Slack using the `slack env add` command and never hard-coded in your functions. Examples are API keys, OAuth client IDs and secrets, certificates, and cryptography keys. If possible, use Slack’s [third party auth support](https://docs.slack.dev/faq#third-party) to manage OAuth-based credentials.
- For local apps using `slack run`, ensure that the `.env` file containing local secrets does not end up in your source control system.
- When using `slack env add`, ensure the secret does not end up in your shell’s history. This can be done using shell environment variables, or by running `slack env add` without any parameters. With no parameters, `slack env add` will prompt you for the secret’s name and value in the console, using a password display.
- Be careful about collecting or logging sensitive information in workflows from users, especially passwords or personally identifiable information (PII). Data may be exposed to later workflow steps, in data exports, or in activity logs.

## Secure credentials

- The Slack CLI stores credentials in the `credentials.json` file in the `.slack` folder in your home directory. Slack will never ask you share the tokens contained in that file.
- While these credentials expire and are regularly rotated, access to this file should be limited to only you.
- Never share the tokens or challenge strings generated by the `slack login` flow.
- Never paste a `/slackauthticket` command given to you by another user into Slack.

## Use secure libraries

- It is your responsibility to monitor and respond to security vulnerabilities in your custom function’s code and dependencies, and to deploy new versions to Slack-managed infrastructure as needed.
- Keep your Slack CLI and SDKs up to date by upgrading when prompted.
- Only use a Slack CLI download by following instructions found within the [Slack CLI docs](/tools/slack-cli/).

## Handle network egress

- Slack’s `outgoingDomains` configuration limits which domains your custom function code can use when making external network requests. Only list `outgoingDomains` if the domains are required by your functions.

## Make scopes and tokens

- Functions are given a short-lived token that can be used to make [Slack API](/tools/deno-slack-sdk/guides/calling-slack-api-methods) calls, which use the scopes requested in the app’s manifest. We recommend only sending these tokens to Slack API endpoints, and not logging them or sending them to external systems.
- Only request the scopes your functions need to do their job.

Following these guidelines will get you on your way to building secure workflow apps.