Encryption keys

We have separate documentation on encrypting files.

A repository’s .travis.yml file can have “encrypted values”, such as environment variables, notification settings, and deploy api keys. These encrypted values can be added by anyone, but are only readable by Travis CI. The repository owner does not keep any secret key material.

Please note that encrypted environment variables are not available for pull requests from forks.

Encryption scheme #

Travis CI uses asymmetric cryptography. For each registered repository, Travis CI generates an RSA keypair. Travis CI keeps the private key private, but makes the repository’s public key available to those who have access to the repository.

Once the public key is available, anyone (including those without push access to your repository) can encrypt data which can only be decrypted by Travis CI, using the corresponding private key.

Obtaining the public keys #

The method to obtain the public key depends on where the target repository exists, and the API version you are using.

Furthermore, the request may require authorization via the Authorization: token header depending on the repository’s location and visibility, as well as the API version used.

Authorization header requirement
Repository visibility and location API server API v1 API v3
/repos/OWNER/REPO/key /v3/repo/OWNER%2fREPO/key_pair/generated
.org https://api.travis-ci.org no yes
public on .com https://api.travis-ci.com yes
yes
private on .com https://api.travis-ci.com yes
yes

Notice that API v3 endpoints above show the repository name with %2f.

If the Authorization: token header is required, you can obtain the token by visiting the account page:

Examples #

Here are some examples of curl commands to obtain the public key.

  1. A public repository on travis-ci.org using API v1

    curl https://api.travis-ci.org/repos/travis-ci/travis-build/key
    
  2. A public repository on travis-ci.org using API v3

    curl -H "Authorization: token **TOKEN**" https://api.travis-ci.org/v3/repo/travis-ci%2ftravis-build/key_pair/generated
    
  3. A private repository on travis-ci.com using API v3

    curl -H "Authorization: token **TOKEN**" https://api.travis-ci.com/v3/repo/OWNER%2fREPO/key_pair/generated
    

Usage #

The easiest way to encrypt something with the public key is to use Travis CLI. This tool is written in Ruby and published as a gem. First, you need to install the gem:

gem install travis

If you are using travis-ci.com instead of travis-ci.org, you need to login first:

travis login --pro

Then, you can use encrypt command to encrypt data (This example assumes you are running the command in your project directory. If not, add -r owner/project):

travis encrypt SOMEVAR="secretvalue"

Or, if you are using travis-ci.com, you will need to add --pro to the CLI:

travis encrypt --pro SOMEVAR="secretvalue"

This will output a string looking something like:

secure: ".... encrypted data ...."

Now you can place it in the .travis.yml file.

You can also skip the above, and add it automatically by running:

travis encrypt SOMEVAR="secretvalue" --add

Please note that the name of the environment variable and its value are both encoded in the string produced by “travis encrypt.” You must add the entry to your .travis.yml with key “secure” (underneath the “env” key). This makes the environment variable SOMEVAR with value “secretvalue” available to your program.

You may add multiple entries to your .travis.yml with key “secure.” They will all be available to your program.

Encrypted values can be used in secure environment variables in the build matrix and notifications.

Note on escaping certain symbols #

When you use travis encrypt to encrypt sensitive data, it is important to note that it will be processed as a bash statement. This means that secret you are encrypting should not cause errors when bash parses it. Having incomplete data will cause bash to dump the error statement to the log, which contains portions of your sensitive data.

Thus, you need to escape special characters such as braces, parentheses, backslashes, and pipe symbols.

For example, you would type ma&w!doc as ma\&w\!doc.

And to assign the string 6&a(5!1Ab\ to FOO:

travis encrypt "FOO=6\\&a\\(5\\!1Ab\\\\"

travis encrypts the string FOO=6\&a\(5\!1Ab\\, which then bash uses to evaluate in the build environment.

Equivalently, you can do

travis encrypt 'FOO=6\&a\(5\!1Ab\\'

Notifications Example #

We want to add campfire notifications to our .travis.yml file, but we don’t want to publicly expose our API token.

The entry should be in this format:

notifications:
  campfire:
    rooms: "[subdomain]:[api token]@[room id]"

For us, that is somedomain:abcxyz@14.

We encrypt this string

travis encrypt somedomain:abcxyz@14

Which produces something like this

Please add the following to your .travis.yml file:

  secure: "ABC5OwLpwB7L6Ca...."

We add to our .travis.yml file

notifications:
  campfire:
    rooms:
      secure: "ABC5OwLpwB7L6Ca...."

And we’re done.

Detailed Discussion #

The secure var system takes values of the form { 'secure' => 'encrypted string' } in the (parsed YAML) configuration and replaces it with the decrypted string.

So

notifications:
  campfire:
    rooms:
      secure: "encrypted string"

becomes

notifications:
  campfire:
    rooms: "decrypted string"

while

notifications:
  campfire:
    rooms:
      - secure: "encrypted string"

becomes

notifications:
  campfire:
    rooms:
      - "decrypted string"

In the case of secure env vars

env:
  - secure: "encrypted string"

becomes

env:
  - "decrypted string"

Fetching the public key for your repository #

You can fetch the public key with Travis API, using /repos/:owner/:name/key or /repos/:id/key endpoints, for example:

https://api.travis-ci.org/repos/travis-ci/travis-ci/key

You can also use the travis tool for retrieving said key:

travis pubkey

Or, if you’re not in your project directory:

travis pubkey -r owner/project

Note, travis uses travis.slug in your project to determine the endpoints if it exists (check by using git config --local travis.slug), if you rename your repo or move your repo to another user/organization, you might need to change it.