Code signing
  • 25 Apr 2024
  • 9 Minutes to read
  • PDF

Code signing

  • PDF

Article Summary

Traceable publishes many artifacts that run in your environment, such as docker images, archives, installers, and helm charts. To make sure that you are running the right and secure artifacts, Traceable provides you with an option to check the authenticity of such artifacts. The steps detailed in this topic are optional, and you should use them only when you wish to check the authenticity of artifacts.

Traceable provides the option to check the following artifacts:

  • JAR

  • Archive or any arbitrary file types

  • Debian package

  • RPM package

  • Docker image

  • Terraform archives

  • Helm charts

GPG key

Traceable provides a GPG public key that is available at https://packages.traceable.ai/public-key.asc. You can use the GPG public key to verify JARs, Debian distributions(apt, deb), rpm for centos7/8.


Signing JARs

Traceable signs and publishes maven jar, which is signed via the Gradle Publish plugin. The Maven central server makes it mandatory to upload only signed JARs. The public key is available in key servers: keyserver.ubuntu.com, keys.openpgp.org, pgp.mit.edu.


Archive checksum verification

Signing

With each archive, Traceable uploads its signature, for example:

Archive-name — traceable-cli-1.8.7-macosx-x86_64.tar.gz

Signature — traceable-cli-1.8.7-macosx-x86_64.tar.gz.sig

Note that it has the same path and name as the .tar.gz file it corresponds to but has the extension .sig

Following is a typical command to create a detached signature interactively:

$ gpg --detach-sign -o traceable-cli-1.8.7-macosx-x86_64.tar.gz.sig traceable-cli-1.8.7-macosx-x86_64.tar.gz

Verification

Download and install the gpg command using your package manager. For more information about GnuPG, see the GnuPG website.

Import the Traceable AI GPG public key with the following commands:

# Download TraceableAI's public PGP key.
$ curl https://packages.traceable.ai/public-key.asc -o traceableai.asc

# Import the public key as referenced above, or available in full below.
$ gpg --import traceableai.asc
gpg: key CFFAC4BBE2B0C74E: public key "Traceable Inc. <support@traceable.ai>" imported
gpg: Total number processed: 1
gpg:               imported: 1

# Verify the public key ID and fingerprint with gpg
$ gpg --list-keys "Traceable"
pub   rsa4096 2023-12-27 [SC]
      95014EA2C6FC41273BC758DBCFFAC4BBE2B0C74E
uid           [unknown] Traceable Inc. <support@traceable.ai>

Download the signature file for the package you downloaded. It has the same path and name as the package it corresponds to but has the extension .sig . For example:

# Download the archive and signature files.
$ curl -Os https://downloads.traceable.ai/cli/release/1.8.7/traceable-cli-1.8.7-macosx-x86_64.tar.gz
$ curl -Os https://downloads.traceable.ai/cli/release/1.8.7/traceable-cli-1.8.7-macosx-x86_64.tar.gz.sig

Verify the signature by providing both the downloaded .sig and package names as parameters to the gpg command as shown below:

$ gpg --verify traceable-cli-1.8.7-macosx-x86_64.tar.gz.sig traceable-cli-1.8.7-macosx-x86_64.tar.gz

The output should look similar to the following:

gpg: Signature made Mon Jan 22 12:40:42 2024 IST
gpg:                using RSA key 95014EA2C6FC41273BC758DBCFFAC4BBE2B0C74E
gpg: Good signature from "Traceable Inc. <support@traceable.ai>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 9501 4EA2 C6FC 4127 3BC7 58DB CFFA C4BB E2B0 C74E

Note

The warning in the output is expected and doesn't indicate a problem. It occurs because there is a chain of trust missing between your personal PGP key (if you have one) and the Traceable AI PGP key. For more information, see Web of trust.


Linux package checksum verification

Traceable’s Linux repositories and packages are signed with the same GPG key. Follow the same procedure of key import as described in Releases Archive Checksum Verification.

Debian/Ubuntu

Verification

.deb binaries

The Debian packages are signed using debsigs. You will need to install the program debsig-verify to verify the packages. Complete the following steps:

  1. Install debsigs. Enter the following command:

    sudo apt install debsig-verify 
  2. Download Traceable’s public key. Enter the following command:

    curl https://packages.traceable.ai/public-key.asc -o traceableai.asc
  3. Create directories to store debsigs policies and keyrings for Traceable’s public key. Enter the following command:

    sudo mkdir -p /usr/share/debsig/keyrings/CFFAC4BBE2B0C74E/
    sudo mkdir -p /etc/debsig/policies/CFFAC4BBE2B0C74E/
  4. Initialize an empty keyring. Enter the following command:

    sudo touch /usr/share/debsig/keyrings/CFFAC4BBE2B0C74E/debsig.gpg
  5. Import Slack’s public key into the corresponding debsigs keyring. Enter the following command:

    sudo gpg --no-default-keyring --keyring /usr/share/debsig/keyrings/CFFAC4BBE2B0C74E/debsig.gpg --import traceableai.asc
  6. Create a new file in your editor of choice. Enter the following command:

    /etc/debsig/policies/CFFAC4BBE2B0C74E/traceable.pol
  7. Paste the following in the file that you created in the previous step. Save the file and exit the editor.

    <?xml version="1.0"?>
    <!DOCTYPE Policy SYSTEM "https://www.debian.org/debsig/1.0/policy.dtd">
    <Policy xmlns="https://www.debian.org/debsig/1.0/">
    <Origin Name="Traceable Inc" id="CFFAC4BBE2B0C74E" Description="Traceable Inc. support@traceable.ai"/>
    <Selection>
        <Required Type="origin" File="debsig.gpg" id="CFFAC4BBE2B0C74E"/>
    </Selection>
    <Verification MinOptional="0">
        <Required Type="origin" File="debsig.gpg" id="CFFAC4BBE2B0C74E"/>
    </Verification>
    </Policy>
  8. Check the package signature. Enter the following command:

    debsig-verify traceable-cli-1.8.7.deb

The output should be similar:

debsig: Verified package from 'Traceable Inc. support@traceable.ai' (Traceable Inc)

APT

For all existing users, if the following changes are not done or yet to be done, they will see:

W: GPG error: https://packages.traceable.ai/ubuntu focal InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY CFFAC4BBE2B0C74E

To avoid the above problem and start verifying traceable apt repo, set the repository using the following:

$ sudo apt-get update
$ sudo apt-get install -y ca-certificates
# Download the public GPG key to /usr/share/keys/traceable.gpg
$ curl https://packages.traceable.ai/public-key.asc | gpg --dearmor -o /usr/share/keyrings/traceable.gpg

Install the Debian artifacts using the following sources.list, so that apt can only install verified packages.

sudo echo "deb [signed-by=/usr/share/keyrings/traceable.gpg] https://packages.traceable.ai/ubuntu/ focal main" | sudo tee -a /etc/apt/sources.list.d/traceable.list

Update apt again and install Traceable:

sudo apt-get update
sudo apt-get install -y traceable

Red Hat/CentOS/Amazon Linux 2

.rpm binaries

On RedHat-based Linux systems, validation is built into the rpm command; however, rpm does not use the GnuPG key store, so you first need to import the public key.

You can validate the signature as follows:

# Import the Public PGP key
$ rpm --import https://packages.traceable.ai/public-key.asc

# Verify the binary
$ rpm -qip traceable-1.0.0-1.el8.src.rpm
Name        : traceable
Version     : 1.0.0
Release     : 1.el8
Architecture: x86_64
Install Date: (not installed)
Group       : Unspecified
Size        : 477669023
License     : Traceable
Signature   : RSA/SHA256, Mon Jan  8 15:32:47 2024, Key ID cffac4bbe2b0c74e
Source RPM  : traceable-1.0.0-1.el8.src.rpm
Build Date  : Mon Jan  8 15:28:24 2024
Build Host  : 96d89d3a0cf4
Relocations : /etc /var/traceable/log /var/traceable/persistence 
Summary     : traceable agent
Description :
traceable agent

$ rpm --checksig -v traceable-1.0.0-1.el8.x86_64.rpm
traceable-1.0.0-1.el8.x86_64.rpm:
    Header V3 RSA/SHA256 Signature, key ID e2b0c74e: OK
    Header SHA1 digest: OK (2c4e67d8688a3ff4b2e500248a9fea416912c1d0)
    V3 RSA/SHA256 Signature, key ID e2b0c74e: OK
    MD5 digest: OK (b5e3e88056c2a7d5418fb596e0fa28ba)

yum

If you are installing the packages using yum, it uses configuration files in /etc/yum.repos.d to specify a URL for the GPG key used to verify packages in that repository. If the key is not already available for verification, the utilities can import it.

Create a file named /etc/yum.repos.d/traceable.repo with the following content:

[traceable]
name=Traceable repository
baseurl=https://packages.traceable.ai/centos[7|8]/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.traceable.ai/public-key.asc

Make sure to change the base to match your OS. Replace [7|8] with the version of CentOS you are using. Execute rpm -E %{rhel} to fetch the CentOS version.

[traceable]
name=Traceable repository
baseurl=https://packages.traceable.ai/centos7/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.traceable.ai/public-key.asc

Install Traceable

Enter the following command:

sudo yum install traceable

Docker image signing validation

This section describes how to use Cosign to validate the provenance of Traceable’s image artifacts.

Cosign is a tool developed as part of the sigstore project. It simplifies signing and validating signed Open Container Initiative (OCI) artifacts, such as container images.

We sign all officially published container images as part of our release process. End users can then verify these images using the process described below.

This process is suitable for either manual execution or integration with build or deployment pipelines to automate artifact verification.

Before you begin

Complete the following steps:

  1. Download the latest Cosign build for your architecture, as well as its signature.

  2. Validate the cosign binary signature:

    $ openssl dgst -sha256 \
        -verify <(curl -ssL https://raw.githubusercontent.com/sigstore/cosign/main/release/release-cosign.pub) \
        -signature <(cat /path/to/cosign.sig | base64 -d) \
        /path/to/cosign-binary
  3. Make the binary executable (chmod +x) and move to a location on the PATH

Validating image

To validate a container image, do the following:

$ ./cosign verify --key "https://packages.traceable.ai/cosign.pub" traceableai/section-io-nginx:0.1.48 | jq .


This process will work for any released image or release candidate built with the Traceable’s build infrastructure.

Following is an example with output:

Verification for index.docker.io/traceableai/section-io-nginx:0.1.48 --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key
[
  {
    "critical": {
      "identity": {
        "docker-reference": "index.docker.io/traceableai/section-io-nginx"
      },
      "image": {
        "docker-manifest-digest": "sha256:661671eec49bb224603dcbe32c54c0bda18afbd2803af8aa78fb9888ec6b496b"
      },
      "type": "cosign container image signature"
    },
    "optional": {
      "Bundle": {
        "SignedEntryTimestamp": "MEQCIB/HA/V6kxekBKHLWhZQ0h7K5d1gO1SgnOawM8DIJv3vAiAmgqpQEa8PuIk8KzdFPYqQdXp/+R/kIMyLmzfNOWHf7w==",
        "Payload": {
          "body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1MjgzMjJkZmYxMTVmYTZiNjMyZWIxNmU0NDk4MDU5MWJjNmE2YjQ2YjUxYzkzOTZkNzg1ZGM4NThmMDdjMzVkIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJRGpGZ3JMY2ZkeE55MzFGVDROazllNE1jTC9oYlovT1dDYk5tK2pOTDVCbEFpQmxGVmd1ZEFldVArenEvbDZkRFVBQTFwQ000WHBiTmdWUHVKS1k2Z3VybFE9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGY2xwMFZsRlBhWEZMYm0wck5qaHdlR05EY214RWFYWnNlamxhS3dwYU5EWjZkM2ROTnprMmNWaGFNVUZUZGsxRGRXaFhVelJ4T0c0eldscDRkRmxSY25KdVpsUndlWEUyYVdkWWNEWnNhbFJZVkhZelMwRkJQVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0=",
          "integratedTime": 1706695456,
          "logIndex": 67976224,
          "logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
        }
      },
      "SignedBy": "Traceable Inc. <support@traceable.ai>"
    }
  }
]

Helm charts provenance

Traceable’s helm charts are signed using the same PGP key shared above. Import the Public PGP key using the following method:

# Download TraceableAI's public PGP key.
$ curl https://packages.traceable.ai/public-key.asc -o traceableai.asc
# Import the public key.
$ gpg --import traceableai.asc
$ gpg --export 'Traceable Inc' > ~/.gnupg/pubring.gpg

Alternatively, you may download and import Traceable’s public key from the Ubuntu keyserver with a command like this:

$ gpg --recv-keys --keyserver keyserver.ubuntu.com 95014EA2C6FC41273BC758DBCFFAC4BBE2B0C74E

Verification

Integrity is established by comparing a chart to a provenance record. Provenance records are stored in provenance files, which are stored alongside a packaged chart. For example, if a chart is named traceable-agent-1.42.1.tgz, its provenance file will be traceable-agent-1.42.1.tgz.prov 

Provenance files are generated at packaging time (helm package --sign ...) and pushed to our chart repository, which can be checked by multiple commands (The following steps assume you have the public key in binary format in ~/.gnupg/pubring.gpg).

# Add traceableai helm repo
$ helm repo add traceableai https://helm.traceable.ai

# Update repositories
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "traceableai" chart repository
Update Complete. ⎈Happy Helming!⎈

$ helm pull traceableai/traceable-agent
$ helm verify traceable-agent-1.41.2.tgz
Signed by: Traceable Inc. <support@traceable.ai>
Using Key With Fingerprint: 95014EA2C6FC41273BC758DBCFFAC4BBE2B0C74E
Chart Hash Verified: sha256:82c1614bb161084454cb9f7a41be91013c0ba8569a9af3da440a4b2c98cb80ac

The verification phase can also be integrated into the regular Helm commands we used so far. For example, to verify when we download a chart from the Internet or when installing a chart, we add the --verify parameter to the commands:

$ helm pull --verify NAME_OF_REPO/NAME_OF_CHART
$ helm pull --verify traceableai/traceable-agent
Signed by: Traceable Inc. <support@traceable.ai>
Using Key With Fingerprint: 95014EA2C6FC41273BC758DBCFFAC4BBE2B0C74E
Chart Hash Verified: sha256:cc550494ca57f2d00defc28db9b6d7a62dbc29442711b5e8b0524701fe33e35d

$ helm install --verify NAME_OF_RELEASE NAME_OF_CHART

Failed verification

If the signature verification fails, the installation phase is abandoned. In such a case, do not install charts you do not trust.

A failed verification may look like this:

$ helm verify --keyring ~/.gnupg/pubring.gpg altered-traceable-agent-1.32.1.tgz
Error: sha256 sum does not match for traceable-agent-1.32.1.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a"

Or if the chart is unsigned/Provenance file is missing: 

$ helm verify traceable-agent-1.40.1.tgz
Error: could not load provenance file traceable-agent-1.40.1.tgz.prov: stat traceable-agent-1.40.1.tgz.prov: no such file or directory

For more information, see Helm | Helm Provenance and Integrity.


Terraform modules checksum verification

Traceable’s terraform modules are signed the same way as any other archive provided by Traceable. Follow Releases Archive Checksum Signing & Verification instructions to sign and check integrity of the terraform modules.

# Download TraceableAI's public PGP key.
$ curl https://packages.traceable.ai/public-key.asc -o traceableai.asc

# Import the public key as referenced above, or available in full below.
$ gpg --import traceableai.asc

# Download a terraform module
$ curl -O https://downloads.traceable.ai/install/traceable-agent/terraform/kubernetes/latest/traceable-agent-tf-k8s.tar.gz

# Download the signature of the terraform archive
$ curl -O https://downloads.traceable.ai/install/traceable-agent/terraform/kubernetes/latest/traceable-agent-tf-k8s.tar.gz.sig

# Verify the signature
$ gpg --verify traceable-agent-tf-k8s.tar.gz.sig traceable-agent-tf-k8s.tar.gz

Windows artifacts signing verification

The best way to verify if a Windows artifact is signed is via UI: right-click on the artifact and select the properties option. If the artifact is signed, there will be a digital signature tab in the properties dialog box. Check if the name of the signer is Traceable Inc.


In case you want to verify via command line tools, you can do so using Powershell.

$file = "C:\path\to\your\file.exe"

$signature = Get-AuthenticodeSignature $file
if ($signature -eq $null) {
    Write-Host "The file '$file' is not signed."
} else {
    Write-Host "The file '$file' is signed by:"
    $organization = $signature.SignerCertificate.Subject.Split(',')[1].TrimStart('O=')
    Write-Host $organization
}


Was this article helpful?