Sign your software with Travis CI

Image (500 × 500 px) (1)

Software Supply Chain security is the act of securing the components, activities, and practices involved in creating and deploying software. One of these practices is digitally signing the software by the developers before releasing it. The digital certificate serves the purpose of ensuring that the software has not been tampered with and the receiver can safely download it.

Now, before you deploy your software with a CI/CD system, you can securely sign it using Travis CI.

After the President of the United States issued the Executive Order in May 2021, the software development industry, and CI/CD community in particular, are experiencing a significant rise in security awareness and features that improve software vendors’ ability to comply with the Secure Software Supply Chain initiative. Whether you are a small software team or a large, established software provider, you may face the following requirements:

  • A Software Bill of Materials (SBOM) along with your releases.
  • Regular security scan reports must be executed.
  • Software release, be it binary files, source code package, or container image(s) with your application or system, must be securely signed.

Modern CI/CD systems, to ease and automate satisfying the above requirements, integrate with tooling that allows the generation of the required elements in your CI/CD process. Travis CI is no different.

What is securely signing software? (Server Side)

Let’s take a Docker image for example, signing is the process of digitally signing the Docker images to confirm the software author’s identity, think of it as a PGP key to a degree. It provides assurance that the code has not been altered or compromised. There’s two ways Image Singing can work:

  • At the client side.
  • At the server side.

Let’s take you through the process in a graphic of how it would work on the server side:

Screenshot 2022-12-29 at 6 26 54 PM

Any registry or runtime that claims to have a certain Docker distribution image specification support will be interacting with the various manifest types. Now that you have an idea of how it works on the server-side, it’s worth taking you step-by-step on just how it is the server-side works once more:

  • The original image (sometimes called the manifest), is firstly hashed by a hashing algorithm, this is usally called ‘salting’. Salting is simply a randomly chosen bit pattern that is combined with the image before it is hashed by a hashing algorithm, the flow is as follows, if equal then image is not tampered.
  • The hashed Docker image we get is then signed by the private key of the developer themselves.
  • The signed hash docker image is then packed with the original image and digital certificate, which together are also known as an image signing certificate.
  • Now, it can be uploaded or transferred to the customer.

You can in fact query DockerHub about the signatures and signatories status of a repository with:

docker trust inspect --pretty travisci/signatures

This will list the notaries behind the image.

Client Side

Now, let’s go through how the process takes place on the client side:

Screenshot 2022-12-29 at 6 22 27 PM

  • The original Docker image is passed through a hashing algorithm, to get the hash of the image, in other words at this point the image is being “salted.”
  • The public key is extracted from the certificate and applied to the signed hash of the Docker image to extract the hash of the image, at this point you can see the notaries.
  • Both the hashes created from steps 1 and 2 are compared, and if both the hashes are the same then the image has not been changed and the signature is considered valid.
  • At the same time, the image signing certificate is checked to ensure it was signed by a trusted CA. The expiry date of the image signing certificate is checked, and the certificate is also checked against the revocation lists to ensure it is valid.

How to sign your software with Travis CI

Travis CI offers the ability to sign your software using the cosign tool and a key.

Cosign is a part of the Sigstore project, which helps to ensure the tooling required for the Secure Software Supply Chain.

Have a dedicated key for signing the software ready

To sign your software with Travis CI, you need to have a dedicated key ready. To obtain a dedicated key, you have two options:

  • You can upload a passwordless SSH key in PEM format to Travis CI account (either personal or organization settings) - there’s a new option called ‘SSH Key for build jobs’ in the settings tab; scroll down to the bottom.
  • The second option is, you can have a self-managed Hashicorp Vault, to which Travis CI can have access and store key there, available for obtaining by a user associated with Travis CI.

Sign the container image during the build job

If you are using a key uploaded to Travis CI, use the following examples:

keys:
  - SSH_KEY_FOR_SIGNING # must match the key identifier set in the UI
env:
  secret: “...” # encrypted COSIGN_PASSWORD=...  string; see cosign doc
before_script: 
  - travis_key SSH_KEY_FOR_SIGNING cosign.key  # cosign requires the key to be in a file
script: 
  - cosign sign --key cosign.key [whatever_the_image_identifier_is]

If you prefer to obtain the key directly from Hashicorp Vault during the build job, try the following:

vault:
  api_url: [single value endpoint address:port] #mandatory
  token:
    secure: “...” #mandatory
    # This will make the default VAULT_ADDR and VAULT_TOKEN available for cosign.
script:
  - cosign sign --key hashivault://some-key-identifier [whatever_the_image_identifier_is]

Deploy the release or container image

Once the file or container image is signed, you can deploy it to the designated location, much like you did up until now.

Considerations

Since the Securely Signing Software is meant to authenticate the release, it is very important to protect the key used for signing. There are certain security considerations, especially for cloud CI/CD systems, which are a surface of attack for malicious actors. The details will vary between CI/CD providers, e.g., depending on whether the build logs are public or private, the exact mechanisms used to deliver a key to the jobs, access control, and specific settings.

Please make sure you familiarize yourself with the respective section of our documentation page for Securely Signing Software whenever you consider securely signing your software using Travis CI.

Read more: