codeux.design

Flutter App Developer and UX Designer


Home Blog Contact
Teaser Secrets with Blackbox in a Continuous Integration service

Secrets with Blackbox in a Continuous Integration service

October 29, 2019

When storing your secrets in your git repository using blackbox you need a way to easily decrypt them on your CI. This can be a bit combersome if you require a gpg key. In this article we look at ways on how to do this on GitLab CI, Travis CI and CirrusCI

  1. Overview
  2. Creating a “role account”
  3. Configure your CI
    1. Travis CI
    2. Cirrus CI
    3. GitLab CI
  4. Conclusion

Overview

In a previous article we explored how to set up blackbox for your git repository for your flutter project. Now let’s look how to actually use them in your favorite CI.

To avoid having to set up a whole OpenGPG environment and import keys I have created a fork of the go implementation of blackbox which implements the command cipostdeploy which simply takes a private key and decrypts all registered blackbox files in your repository.

We can easily make use of it in a CI by downloading the required binary from the github release.

Creating a “role account”

A role account is simply a private key you can register as “admin” in your blackbox repository which is not a real user. But due to how blackbox is set up you still need a full public/private key pair which is associated with an email address.

My fork contains a script which makes this very easy called blackbox_create_role_account so I would recommend you either check out the fork or simply download the script into your $PATH. You can also follow the procedure manually.

With the blackbox_create_role_account simply create one “account” for every CI you intend to use, to make it easy to remove those accounts again.

bash$ blackbox_create_role_account travis-ci@roleaccount

This will ask you for your password and then reencrypt all files again. You should see the added role account when listing all admins:

bash$ blackbox_listadmins 
authpass-ci-cirrus-key@codeux.design
herbert@poul.at
travis-ci@roleaccount

By default the private key will be located in /var/tmp/SECRET_KEY.txt make sure to delete this key as soon as you has configured it in your CI!

If you lose the key, nothing to worry about, simply remove the admin again.

bash$ blackbox_removeadmin travis-ci@roleaccount
bash$ blackbox_update_all_files
Note!

If one of your secret keys is exposed in a leak for a public git repository, removing the admin from the current version will do no good. As an attacker could simply clone a old version of your repository and read those secrets. So in the worst case you have to delete your old encrypted files from the complete git history. Which, for open source projects cloned and forked is pretty much impossible. So you still have to protect your private keys!

Configure your CI

Travis CI

First create a new role account for travis as outlined in the previous chapter.

Unfortunately for travis we can’t simply use an encrypted variable, because the private key is too large. So we have to use encrypted files.

Travis only allows a single encrypted file. But this shouldn’t be a problem, simply store the private key for blackbox as a travis encrypted file, and everything else inside blackbox.

mv /var/tmp/SECRET_KEY.txt .travis.blackbox.key
travis encrypt-file --pro .travis.blackbox.key --add
Arguments
  • --pro use travis.com (instead of travis.org)
  • --add Immediately save to .travis.yml

The above command will:

  1. create a file called .travis.blackbox.key.enc
  2. add a line to your before_install section of your travis.yml like:
    - openssl aes-256-cbc -K $encrypted_83630750896a_key -iv $encrypted_83630750896a_iv
       -in .travis.blackbox.key.enc -out .travis.blackbox.key -d
    

All that is left to do is download the blackbox binary and call cipostdeploy. Your travis.yml should look like:

dist: xenial
# [...]
before_install:
  # autogenerated openssl decrypt line
  - openssl aes-256-cbc -K $encrypted_83630750896a_key -iv $encrypted_83630750896a_iv
      -in .travis.blackbox.key.enc -out .travis.blackbox.key -d
  # Download blackbox, run cipostdeploy
  - curl -O blackbox.go.linux.amd64 https://github.com/hpoul/blackbox/releases/download/golang-v0.1-cipostdeploy/blackbox.go.linux.amd64
  - chmod +x blackbox.go.linux.amd64
  - ./blackbox.go.linux.amd64 cipostdeploy < .travis.blackbox.key

Now make sure you commit travis.yml and .travis.blackbox.key.enc into git. (Make sure it is the encrypted .enc file you are committing).

🎉️ and you should be done. Travis should now easily decrypt the blackbox private key and then decrypt all your secrets stored in blackbox.

Cirrus CI

Cirrus CI is almost the same as travis, but easier because you do not need an ecrypted file, but we can use an encrypted environment variable.

Head to your repository main page (for example: https://cirrus-ci.com/github/my-organization/my-repository) and click on the Settings icon. There you can encrypted an environment variable. Simply paste the whole contents of the private key for blackbox into the field and hit ENCRYPT. The result will be something like:

ENCRYPTED[d2f1f20235d7abe3e22783f723700e11b0aa60733009d8f7aa15d9fc0ba5c01c09094720016c46d1136345df357e1ab0]

This value can now be added to your .cirrus.yml file:

osx_instance:
  image: mojave-xcode-10.2

task:
  environment:
    BLACKBOX_SECRET_KEY: ENCRYPTED[d2f1f20235d7abe3e22783f723700e11b0aa60733009d8f7aa15d9fc0ba5c01c09094720016c46d1136345df357e1ab0]
  install_script:
  - curl -O blackbox.go.macos https://github.com/hpoul/blackbox/releases/download/golang-v0.1-cipostdeploy/blackbox.go.macos
  - chmod +x blackbox.go.macos
  - echo "$BLACKBOX_SECRET_KEY" | ./blackbox.go.macos cipostdeploy

🎉️ and you should be done. ;-)

GitLab CI

Especially since GitLab 11.11 storing the encryption key for blackbox is particularly easy thanks to variable types. (See also the documentation provided by gitlab). We can simply create a secret variable which will be stored into a file. As with Cirrus CI copy and paste the whole contents of the secret key file into the text field. Make sure to select variable type File and choose a matching key like BLACKBOX_SECRET_KEY.

GitLab Secret Variable File

GitLab Secret Variable File

Now we can simply pass this file along to blackbox cipostdeploy.

.gitlab-ci.yml

# [...]
before_script:
  - curl -O blackbox.go.linux.amd64 https://github.com/hpoul/blackbox/releases/download/golang-v0.1-cipostdeploy/blackbox.go.linux.amd64
  - chmod +x blackbox.go.linux.amd64
  - ./blackbox.go.linux.amd64 cipostdeploy "$BLACKBOX_SECRET_KEY"

Conclusion

As you can see it is very straight forward to use blackbox in your CI process, it all boils down to three easy steps:

  1. Create Role Private/Public key pair for CI
  2. Store the private key as a secret variable with your CI
  3. Use this secret variable to decrypt blackbox files using cipostdeploy
What do you think?

Have you successfully configured your CI? Did you run into problems?

Let me know in the comments! Would apreciate any feedback.