Secrets with Blackbox in a Continuous Integration service
29 October 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
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
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.
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.
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 email@example.com firstname.lastname@example.org travis-ci@roleaccount
By default the private key will be located in
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
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!
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
--prouse travis.com (instead of travis.org)
--addImmediately save to
The above command will:
- create a file called
- add a line to your
before_installsection of your
- 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
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
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 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:
This value can now be added to your
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. ;-)
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
Now we can simply pass this file along to
# [...] 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"
As you can see it is very straight forward to use blackbox in your CI process, it all boils down to three easy steps:
- Create Role Private/Public key pair for CI
- Store the private key as a secret variable with your CI
- Use this secret variable to decrypt blackbox files using
Have you successfully configured your CI? Did you run into problems?
Let me know in the comments! Would apreciate any feedback.