# Secrets

> Secrets are a specific type of Environment Variable: they aren't shown in the bitrise.yml and their value is not exposed in the build logs.

Secrets are a specific type of Environment Variable: they hide their information in an encrypted format and their value is not exposed in the build logs. They aren't shown in the `bitrise.yml` configuration either. You can store confidential information, such as passwords or API keys as Secrets.

Just like Environment Variables, Secrets can be used as the value of a Step input: [Using an Env Var as a Step input](/bitrise-ci/configure-builds/environment-variables#using-an-env-var-in-a-step-input)

## Setting a Secret

:::note[Every Env Var value is a string]

The value of an Environment Variable or Secret can only be a string. Even if you set a number (for example, 7), it will be passed on as a string.

:::

You can create a Secret either on the **Secrets** page in the Workflow Editor or when modifying Step inputs.

**Secrets page**

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. On the left, select **Secrets**.
1. Under **Project level Secrets**, click the **Add new** button.

   ![secrets-screenshot.png](/img/_paligo/uuid-b269a597-65ef-34a5-1828-ad1ab954437d.png)
1. Add a key and a value.

   :::important[Using the $ character]

   You can use the `$` character in the value of an Env Var or Secret (for example, in a password) but in that case always leave the **Replace variables in inputs** option unchecked. If you replace the variable's key with its value in inputs, the Bitrise CLI will treat the value as another Env Var because of the `$` character.

   :::
1. Optionally, you can [replace the key of your Secret with its value in inputs](/bitrise-ci/configure-builds/environment-variables#replacing-variables-in-inputs): check the **Replace variables in inputs** option.
1. Optionally, you can expose your Secret to pull requests by selecting the option.

   In most cases, we strongly recommend [not to expose Secrets](/bitrise-ci/configure-builds/secrets#exposing-a-secret-to-pull-requests).
1. Click **Save**.

**Step inputs**

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. Select a Workflow and find the Step you want to configure.
1. Find the sensitive input you wish to modify.
1. Click the **$** sign and then click **Create** in the dialog.
1. In the **Create secret** dialog, specify a key and a value for your new Secret.

   ![create-variable.png](/img/_paligo/uuid-2a0854ff-b62a-6215-5c2e-09cf6b244786.png)
1. Optionally, you can [replace the key of your Secret with its value in inputs](/bitrise-ci/configure-builds/environment-variables#replacing-variables-in-inputs) by checking the option.
1. Click **Create**.

## Editing an existing Secret

Once you’ve added a new secret Env Var in the **Secrets** tab, you come back to it any time, modify its content or make it protected from curious eyes!

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. On the left, select **Secrets**.
1. Click **Edit** next to the value of your Secret.
1. Modify its content as needed.
1. Click **Save**.

## Protecting the value of a Secret

Normally, you can **show** and **hide** the value of a Secret by clicking the **eye** icon. This feature is useful if you have a long list of secret env vars in **Secrets** and you wish to check the value of only one Secret while leaving the other values hidden. If a value is hidden, it’s represented with the **crossed out eye** icon.

However, you can hide the value of a Secret permanently by making it protected. If you do so, no one, including yourself, will be able to change or even view the value again.

:::warning[A Secret's protection can't be undone]

Making a Secret protected is irreversible. If you ever need to change the value, you will have to delete the Secret and create a new one.

:::

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. On the left, select **Secrets**.
1. Click **Edit** next to the value of your Secret.

   ![edit-button-secrets.png](/img/_paligo/uuid-2de8b6b8-3fc0-5da9-9f45-1b22546e1bb2.png)
1. Check **Protected**.
1. The dialog will warn that the process is irreversible. Click **Save and protect**.

That's it. You can no longer view the value of the Secret.

## Exposing a Secret to pull requests

By default, pull requests do not have access to the values of Secrets. This means that if a pull request opened from a fork of a repository triggers a build, that build can't use the app's Secrets.

If you need to grant pull request builds access to a particular Secret, you can expose that Secret to pull requests. However, even when exposed, its value won't be visible in the logs: it will be displayed as [REDACTED].

:::important[Protected Secrets can't be exposed]

Once a Secret has been [made protected](/bitrise-ci/configure-builds/secrets#protecting-the-value-of-a-secret), you can't expose it to pull request builds.

:::

:::important[Public apps]

If your app is a public app, you can't expose the app's Secrets to pull requests builds.

:::

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. On the left, select **Secrets**.
1. Click **Edit** next to the value of your Secret.
1. Toggle the **Expose for Pull Requests?** toggle.

Once the Secret is exposed, pull request builds can access it.

## Managing Secrets across multiple apps

By default, all Secrets are handled on the app level. You can reuse Secret keys across multiple Bitrise apps, even if their corresponding values are different for each app.

However, it is possible to set up a Secret that holds the same value for all your apps, and manage that Secret from one location. For example, if all your apps need access to the same API, it makes sense to store the Secret containing the API key in a central location. If the API key ever changes, you only need to change it in that single location and the change applies to all your Bitrise apps.

There are two ways to achieve this:

- [Managing your Secrets from a Workspace](#managing-secrets-on-a-workspace-level). This is only available on Enterprise plans.
- [Managing secrets from a central location](#managing-secrets-from-a-central-vault-or-database) such as a vault or database and pulling it with a Step.

### Managing Secrets on a Workspace level

On Enterprise plans, you can store Secrets on a Workspace level. This means that the same Secret is accessible to all apps owned by that Workspace. This means increased security: only Workspace Owners and Managers can access these Secrets.

:::note[Downgrading]

If you downgrade from an Enterprise plan, Workspace Secrets will be converted to app level Secrets.

:::

When passing Secrets to your build, app level Secrets take precedence over Workspace level Secrets in the [availability order](/bitrise-ci/configure-builds/environment-variables#availability-order-of-environment-variables). This also means that if you have two Secrets with the same key, the app level Secret will be used during the build.

To add a new secret:

1. On the Bitrise main page, select **Settings** on the navigation menu on the left. It takes you to the **Workspace settings** page.
1. On the **Workspace settings** page, select **Shared resources**.

   ![shared-res.png](/img/_paligo/uuid-8b262205-594a-d6ae-9985-3c47a3df5175.png)
1. Click the **Add new** button.
1. Add a key and a value.

   ![ws-secrets.png](/img/_paligo/uuid-0d1616e8-82d6-9de7-f192-1aab7058880b.png)
1. Configure the usage details of the Secret:

   - **Replace variables in inputs**: This passes the value of the Secret as a string to the build. Use this for embedded Secrets or Environment Variables: when the value of your Secret is the key of another Secret or Environment Variable. For most use cases, you don't need this checked.
   - **Expose for pull requests**: Exposing a Secret to a PR means that the Secret is available to use in pull request builds. Depending on your repository's privacy settings, this is a potential security risk!
   - **Protected**: The value cannot be changed or viewed again. This setting is irreversible once saved.
1. When you're ready, click **Done**.

### Managing Secrets from a central vault or database

Setting up Secrets in a central location requires two things:

- A central vault or database - such as HashiCorp or Doppler - to store the Secrets. It must be accessible via a CLI.
- A **Script** Step to access the central vault/database, pull the Secret and set it to sensitive on Bitrise.

To create a new Secret and store it in a central location during a build:

1. Add the Secrets as a key-value pair to your vault or database where you want to store them.
1. Add a **Script** Step to ALL Workflows where you want to use the Secrets.
1. Add the necessary commands to access your vault and pull the Secrets. The exact commands depend on the service you’re using.
1. Use the `envman` tool to mark the Secrets as sensitive. The envman tool has the following syntax:

   `envman add --key KEY --value value --sensitive` .
1. Make sure the Step doesn’t display the value of the Secret in the build log. To do so, remove `set -x` from the Step’s `content`.

:::warning[Secret redaction]

Please note that if you have Secret redaction turned off, your Secrets will not be redacted and thus their value can still be visible in logs.

:::

**Storing your Secrets in a HashiCorp Vault**

Let’s say you have a [HashiCorp Vault](https://www.vaultproject.io/) instance called `secret/hello`. You have two Secrets in this vault instance: `foo` with the value `world` and `foo2` with the value `world2`. To use these Secrets in a Bitrise build, you need to:

- Export them from the Vault instance.
- Iterate over them and mark both of them as sensitive.

You can use this Script to achieve both:

```bash
# Exporting the Secrets
vault kv get --format=json secret/hello | jq -r '.data.data | to_entries[] | [.key, .value] | @tsv' | 
# Iterating over the Secrets and marking them as sensitive
while IFS=$'\t' read -r key value; do
    envman add --key "$key" --value "$value" --sensitive
done
```

## Redacting Secrets

The Bitrise CLI automatically redacts your Secret Env Vars and prints `[REDACTED]` with newlines after the key so that the Secret Env Vars are NOT VISIBLE in the build log. This applies to both private and public apps.

You can turn this off at any time though if you need to have your Secrets visible in logs.

:::warning

This is a potential security risk. We strongly recommend not to turn off Secret redaction.

:::

1. 1. Log in to Bitrise and select **Bitrise CI** on the left, then select your project.
1. Click the **Workflows** button on the main page.
1. On the left, select **Secrets**.
1. Click **Add new** to register the `BITRISE_SECRET_FILTERING` secret Environment Variable with false value.
1. Click **Save changes** in the top right corner.

## Secrets in self-hosted environments

You can run Bitrise builds on self-hosted infrastructure: hardware or virtualized environments that you control. If your security policy doesn't allow you to use Bitrise Secrets hosted on bitrise.io, this guide offers a different way of accessing Secrets and using them in your builds.

In a self-hosted build, your host machine is behind your virtual private cloud. As such, you can access the secret service of your choice without exposing the Secrets to the Bitrise control plane and the website. Get the Secret from your service and then add it to the Bitrise build using `envman`:

1. Optionally, create a placeholder Secret on Bitrise with any value: [Setting a Secret](/bitrise-ci/configure-builds/secrets#setting-a-secret).

   This is necessary only if you wish to use the Secret in a sensitive Step input on the GUI of the Workflow Editor. Sensitive inputs only accept Secrets and in the Workflow Editor you can only add existing Secrets as the value of a sensitive input.

   If you edit your Bitrise configuration in YAML, you don't need a placeholder as you can set any value to your input.
1. Use a **Script** Step to get your Secret from the service you use.
1. In the script, turn off debugging by setting `set +x`:

   This is very important: in debug mode, the value of the Secret might be visible in the build log!

   ```bash
   #!/usr/bin/env bash
   # fail if any commands fails
   set -e
   # make pipelines' return status equal the last command to exit with a non-zero status, or zero if all commands exit successfully
   set -o pipefail
   # debug log
   set +x
   ```
1. Fetch the Secret value from the service you use and then add it to `envman`.

   ```bash
   set +x
   GIT_PASSWORD_SECRET=TODO Your call to fetch the secret value
   envman add --key GIT_HTTP_PASSWORD --value $GIT_PASSWORD_SECRET
   ```

   The actual commands depend on the service you use. For example, if you use Bitrise on AWS and your EC2 machine can access the AWS Secrets Manager, you could get the secret with a command similar to this:

   ```bash
   set +x
   USERNAME=aws secretsmanager get-secret-value --secret-id BitriseDemoGitUsername --region eu-central-1 | jq  -r '.SecretString'
   envman add --key GIT_HTTP_USERNAME --value $USERNAME
   PASS=aws secretsmanager get-secret-value --secret-id BitriseDemoGitPassword --region eu-central-1 | jq  -r '.SecretString'
   envman add --key GIT_HTTP_PASSWORD --value $PASS
   ```
