Supply chain security

Package signing

Cloudsmith uses GPG or RSA signatures (where applicable) in addition to package checksums to detect tampering.

We calculate a signature for every file that is uploaded, but only some of the package formats make it available or use it. Only some of the formats also offer metadata signing.

For increased trust, you can also provide your own GPG key or RSA key for signing.

Key support by package format

Package FormatKey TypeKey Use
AlpineRSAIndex
CargoNot Supported by Format
CocoaPodsNot Supported by Format
ComposerGPG
ConanNot Supported by Format
CRAN
DartNot Supported by Format
DebianGPGIndex
DockerRSAIndex
GenericNot Supported by Format
Go
GradleGPGIndex Package
Helm ChartsGPG
LuaRocks
MavenGPGIndex Package
NixED25519Package
npmGPG
NuGet
PythonGPG
RawGPG
RPMGPGIndex Package
sbtGPGIndex Package
Terraform ModulesNot Supported by Format
UnityGPG
VagrantGPG

Docker and Cosign

When a Docker image is uploaded to a repository, Cloudsmith automatically generates a Cosign signature using the repository’s ECDSA private key. Customers can download the corresponding ECDSA public key to verify the specific image, as below:

docker push docker.cloudsmith.io/<org>/<repo>/alpine:<sha256-checksum>

cosign verify --private-infrastructure=true --key public-ecdsa-key.key docker.cloudsmith.io/<org>/<repo>/alpine:<sha256-checksum>

See Docker Images: Signing and Verifying SBOMs with Cosign for more.

Docker image verification

Cloudsmith does not log to Rekor when generating signatures on image upload. When verifying these using cosign verify pass --private-infrastructure=true to prevent cosign querying the Rekor log.

As Docker images within Cloudsmith are predominantly private, when a cosign signature is automatically generated on image upload, Cloudsmith does not add any data to the Rekor log. The Rekor log contains a record of image names and corresponding public keys, and is used to enable software maintainers to record signed metadata, and for verifiers to monitor and query the log for an appropriate identity. When using cosign verify to verify cosign signatures generated by Cloudsmith, pass --private-infrastructure=true to ensure cosign does not query the Rekor log. If this parameter is not passed, the following warning will be displayed:

WARNING: "docker.cloudsmith.io/<org>/<repo>/alpine:<sha256-checksum>
appears to be a private repository, please confirm
uploading to the transparency log at "https://rekor.sigstore.dev"

Please note customers who create their own signatures using the cosign sign command, will be asked if they wish to upload a transparency log to Rekor.

Supported Keys

If a key is used which is not supported by Cosign, it will not be possible to generate the associated OCI image signature.

Cosign supports the following ECDSA curves:

  • NIST P-224 (secp224r1)
  • NIST P-256 (secp256r1, prime256v1)
  • NIST P-384 (secp384r1)
  • NIST P-521 (secp521r1)

If a key is used which is not supported by Cosign, Cloudsmith will not be able to generate the associated OCI image signature.

Manage a repository GPG key with the CLI

Use the Cloudsmith CLI to view, upload, or regenerate the GPG key used to sign a repository's package indexes.

To upload or regenerate a key, you need Admin privileges on the repository. To view the active key in a private repository, you need at least Read privileges.

In the following examples, WORKSPACE is your workspace slug and REPOSITORY is your repository slug. The CLI help shows these as OWNER/REPO.

View the active key

shell
cloudsmith repos gpg get WORKSPACE/REPOSITORY

The output includes the full and short fingerprints, whether the key is active, whether it is the default, any comment, and the armored public key block. For machine-readable output, add -F json after the subcommand, for example cloudsmith repos gpg get WORKSPACE/REPOSITORY -F json. list and ls are aliases for get.

Upload a GPG key

Provide an armored private key through a file:

shell
cloudsmith repos gpg upload WORKSPACE/REPOSITORY \
  --private-key-file repository-signing-key.asc

If you omit --passphrase-file in an interactive terminal, the CLI prompts for the passphrase without echoing it. Leave the prompt blank if the key is not encrypted. For unattended use with an encrypted key, provide the passphrase through a protected file:

shell
cloudsmith repos gpg upload WORKSPACE/REPOSITORY \
  --private-key-file repository-signing-key.asc \
  --passphrase-file /secure/path/gpg-passphrase

With no terminal attached, the CLI does not prompt. It treats the key as unencrypted, so an encrypted key uploaded without --passphrase-file fails with the provided key is not valid.

Use - as the value of either --private-key-file or --passphrase-file to read that value from standard input. If --private-key-file is -, then --passphrase-file is required and must be a file path.

Protect private key material

The CLI does not accept the private key or passphrase as command-line values because they could be exposed in shell history or process listings. Passing --debug to the upload command fails with an error, because debug output would include the private key and passphrase.

Add --dry-run to check the inputs and the key currently in place without uploading anything. A dry run:

  • Reads the private key file.
  • Reads the passphrase file, if one is provided.
  • Confirms that the current credentials can access the repository.
  • Shows the fingerprint that would be replaced.

A dry run does not prompt for a passphrase, and does not verify that the private key and passphrase form a valid pair.

shell
cloudsmith repos gpg upload WORKSPACE/REPOSITORY \
  --private-key-file repository-signing-key.asc \
  --dry-run

Regenerate the GPG key

To replace the active key with a new key generated by Cloudsmith:

shell
cloudsmith repos gpg regenerate WORKSPACE/REPOSITORY

The CLI asks you to type regenerate before replacing the key. In unattended scripts, pass --yes. If no terminal is attached and --yes is not set, the command fails with an error instead of waiting for input. Use --dry-run to show the fingerprint that would be replaced without regenerating the key.

Regenerating a GPG key

Regenerating retains the old public key and deletes its private key. Existing packages are not re-signed, but repository indexes use the new key. This cannot be undone.

There is no delete subcommand, because the Cloudsmith API does not support deleting a repository's GPG key. Upload a replacement key or regenerate the current key instead.