CircleCI logo

How to manage secrets in CircleCI

This guide shows you how you can use the SecretHub CircleCI Orb for your pipeline secrets. You’ll be able to define the required secrets in the .circleci/config.yml without exposing their plaintext value.

Before you begin

To follow along, you will need to:

Step 1: Write your secrets

If you haven’t done so already, store your secrets on SecretHub. You can use the following commands to get everything set up:

In the examples we’ll be using two AWS secrets: company/app/aws/access_key_id and company/app/aws/secret_access_key, but the same principle applies to all secrets.

Step 2: Importing the SecretHub Orb

Before you can start using the SecretHub Orb, you first have to import it. First of all, you have to set the version of the .circleci/config.yml file to 2.1 by including the following line:

version: 2.1

Then you can import the SecretHub orb by adding the following to .circleci/config.yml (replacing x.y.z with the latest version of the SecretHub Orb):

orbs:
  secrethub: secrethub/cli@x.y.z

Step 3: Using the Orb

Now you can start using the SecretHub Orb in your CircleCI configuration. This guide will show you the simplest step-by-step use case first: how to provide secrets to a command with the Orb.

For more use cases like loading secrets into other orbs or using the CLI directly, scroll down to the end of this guide.

version: 2.1
jobs:
  build:
    docker:
      - image: 'cimg/base:stable'
    environment:
      AWS_REGION: us-east-1
      AWS_ACCESS_KEY_ID: secrethub://company/app/aws/access_key_id
      AWS_SECRET_ACCESS_KEY: secrethub://company/app/aws/secret_access_key
    steps:
      - checkout
      - secrethub/exec:
          - command: ./deploy-my-app.sh
orbs:
  secrethub: secrethub/cli@x.y.z
workflows:
  deploy:
    jobs:
      - deploy

The first thing to note in this example is the environment section. The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY variables use a secret reference (secrethub://) to refer to a secret in SecretHub. By using the secrethub/exec step, these references are automatically replaced with their corresponding secret value and passed as environment variables to the ./deploy-my-app.sh command at runtime. Reference tags can be declared at any level in the file and in CircleCI contexts, depending on how restrictively you want to provide them to steps.

All other steps only see the references to these secrets in the environment. Also, any secrets printed on stdout or stderr will be masked automatically, so they don’t end up in CircleCI’s logs. This is also the case for all the other use cases.

Step 4: Create a SecretHub service account

SecretHub uses service accounts to grant non-human parties (such as CIs) access to secrets.

To create a service account, run the secrethub service init command:

secrethub service init --permission read company/app

This command will output the generated account credential. Make sure to copy it as it will be needed in the next step.

The --permission read flag will grant the service read access to the specified repo.

Note that you can use the --clip flag to write the output of the command to your clipboard:

secrethub service init --clip --permission read company/app

Step 5: Provide the credential to CircleCI

  1. Open the CircleCI web app and go to your project’s settings page
    Go to the settings page in the CircleCI web app
  2. Click on Environment Variables under Build Settings
    Go to Environment Variables under Build Settings
  3. Click on Add Variable
  4. Set the variable name to SECRETHUB_CREDENTIAL and paste the key from the previous step into the value field
    Fill in the dialog
  5. Click on Add Variable

You have now successfully configured your CircleCI pipeline to fetch secrets from SecretHub. Moreover, you can now rotate your secrets and the pipeline will automatically use their latest version.

Alternative use cases

Using secrets in other orbs

If you need to access secrets in other Orbs, you can use the second option which overrides the job’s shell:

version: 2.1
jobs:
  deploy:
    environment:
      AWS_REGION: us-east-1
      AWS_ACCESS_KEY_ID: secrethub://company/app/aws/access_key_id
      AWS_SECRET_ACCESS_KEY: secrethub://company/app/aws/secret_access_key
    executor: aws-cli/default
    shell: secrethub run -- /bin/bash
    steps:
      - secrethub/install
      - checkout
      - aws-cli/setup
      - run: aws s3 sync . s3://my-app-bucket
orbs:
  aws-cli: circleci/aws-cli@x.y.z
  secrethub: secrethub/cli@x.y.z
workflows:
  deploy:
    jobs:
      - deploy

Just like before, you set reference to the required secrets in the environment section of the configuration.

By setting the shell to secrethub run -- /bin/bash, all following commands (including those in Orbs) will be wrapped in secrethub run --. This means they all get access to the secrets as defined in the environment section and secret values are redacted on stdout and stderr. For this override to work, it is important that the first item in the list of steps is secrethub/install.

Note: similar to the other use cases, you’ll need to provide this job with a SecretHub credential too.

Using the SecretHub CLI

For more control, you can also use secrethub/install to install the SecretHub CLI and use it directly in your commands. This is especially handy if you have to pass a secret as an argument or flag:

version: 2.1
jobs:
  build:
    docker:
      - image: 'cimg/base:stable'
    steps:
      - checkout
      - setup_remote_docker
      - secrethub/install
      - run: >
          docker login -u $(secrethub read company/app/docker/username) -p $(secrethub read company/app/docker/password)
          docker build -t company/app:${CIRCLE_SHA1:0:7} .
          docker push company/app:${CIRCLE_SHA1:0:7}
orbs:
  secrethub: secrethub/cli@x.y.z
workflows:
  deploy:
    jobs:
      - deploy

First you install the secrethub/install. You can then use any CLI command in the following commands.

Note: similar to the other use cases, you’ll need to provide this job with a SecretHub credential too.

See also

Happy coding!