Cosign Overview
Cosign is part of the Sigstore project. It is primarily targeted at the open source community, allowing individual developers to sign container images using OpenID user accounts from GitHub, Google or Microsoft. For those developers, Sigstore eliminates the need for certificates or locally storeed private keys.
Sigstore architecture
Sigstore combines the Cosign tool, the Fulcio certificate authority and the Rekor transparency log as follows:
- Cosign creates a metadata file for signing
- Fulcio authenticates the user account using OpenID Connect (OIDC)
- Fulcio creates a short-lived certificate for the OIDC identity using an ephemeral key and signs the metadata digest
- Rekor logs the signature in its public transparency log
- Cosign uploads signature and metadata to the image’s repository
Advantages of using SignPath for Cosign
While this works well for individual developers, organizations often have different requirements, including
- Control issuing of certificates and key management
- Using automated CI/CD build system that do not support 3rd party OICD authentication
- Do not use individual OICD user accounts for signing
- No public signature logging (or operating their own Fulcio CA)
SignPath supports Cosign signing using an organization’s certificate and keys.
Additionally, SignPath allows to process the entire metadata file. Metadata files contain
- The container image’s identity (e.g. Docker Hub namespace/repository identifiers)
- The container image’s hash digest
- Optional data
Submitting full metadata files instead of their hash codes has several advantages:
- Full auditing of signed data
- Additional verifications (e.g. image identity) can be performed before signing
- Additional information (e.g. source and build metadata and attestations) can be inserted before signing
SignPath will offer advanced verification and information features in the near future.
X.509 certificate chains in Cosign
Cosign builds upon X.509 certificate chains, but requires specific additional attributes to be set in each certificate. The sigstore project is actively working on supporting custom certificates from traditional PKIs.
How to use Cosign with SignPath
When Cosign is used directly, it creates the metadata, signs it, and upload the signature. You can use Cosign with SignPath’s Cryptoki provider.
When SignPath is used to sign Cosign metadata files, you need to perform each step separately:
- Use
cosign
to create the metadata file - Use SignPath to create a signature for the metadata
- Use
cosign
to upload metadata and signature to your repository
Prerequisites
Required components on the client:
- Cosign in version 2.0.0 or higher
In your SignPath organization, you need the following entities:
- A project with an artifact configuration of type Detached raw signatures
- A certificate (only the public/private key pair will be used)
The Docker container image must be pushed to an OCI-compliant container registry.
Step 1: create the metadata file
# Extract the repository digest identifier for the given FQN
export IMAGE_DIGEST=`docker inspect --format='{{index .RepoDigests 0}}' "$FQN:$TAG"`
# Generate a metadata file to be signed
cosign generate $IMAGE_DIGEST > payload.json
# Package the metadata file for SignPath
zip payload.json.zip payload.json
FQN and TAG
For images hosted on Docker Hub, the FQN is
docker.io/$namespace/$repository
, e.g.docker.io/jetbrains/teamcity-server
.If you are using your own registry, specify the value you would use for Docker CLI commands, but without tag or digest values. E.g. when using
docker pull myreg.jfrog.io/> myrepo/myimage:latest
, the FQN would bemyreg.jfrog.io/myrepo/myimage
.
$TAG
refers the specific image tag (e.g.latest
)
Step 2: create a signature for the metadata
Upload the payload.json.zip
file to SignPath for signing. Use the artifact configuration “Detached raw signatures” for a single container image or extend it according to your needs. See detached raw signatures for more details. The following step expects the signed artifact to be stored as payload.json.signed.zip
.
Step 3: attach the signature to the image
Finally, the following snippet will unzip the signed artifact, encode the signature in base64 for cosign and upload the signature to the repository:
# Extract the detached signature
unzip -n payload.json.signed.zip
# Encode the signature using base64 for cosign
cat payload.json.sig | base64 > payload.json.base64.sig
# Upload the signature to the registry
cosign attach signature --payload payload.json --signature payload.json.base64.sig $IMAGE_DIGEST