Quickstart: Sign and validate a non-image artifact

Quickly set up an OCI-based registry and use notation to sign and validate an SBOM for a container image

Prerequisites

Before you begin, you need:

Create an OCI-compatible registry

Create and run an OCI-compatible registry on your development computer using the distribution/distribution with the image deletion enabled. The following command creates a registry that is accessible at localhost:5001.

docker run -d -p 5001:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true --name registry registry

If you want to use Notation with other registries, refer to which registries are compatible with the Notary Project for more alternatives. See Authenticate with OCI-compliant registries when you log in to another OCI registry.

Add an image to the OCI-compatible registry

The following commands build and push the wabbit-networks/net-monitor container image to your container registry.

docker build -t localhost:5001/net-monitor:v1 https://github.com/wabbit-networks/net-monitor.git#main
docker push localhost:5001/net-monitor:v1

Get the digest value of the localhost:5001/net-monitor:v1 image using docker inspect. For example:

docker inspect --format='{{index .RepoDigests 0}}' localhost:5001/net-monitor:v1

Output:

localhost:5001/net-monitor@sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a

In the above example, the digest value is sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a. The reference to the container image using the digest value is localhost:5000/net-monitor@sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a.

Use an environment variable to store the digest value of the container image. This environment variable is used in later steps. For example:

IMAGE=localhost:5001/net-monitor@sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a

Generate an SBOM for the container image

Use docker sbom to generate an SBOM for the container image. For example:

docker sbom --output SBOM.txt $IMAGE

Attach the SBOM to the container image

Use oras attach to attach the SBOM to the container image. For example:

oras attach $IMAGE SBOM.txt --artifact-type example/sbom

Use oras discover to confirm the SBOM is attached to the container image. For example:

oras discover $IMAGE -o tree

Confirm the SBOM is attached to the container image. For example:

localhost:5000/net-monitor@sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a
└── example/sbom
    └── sha256:6cbf7cc5ffa82b030b57ff820d49a86c143d8c6ac483b8e5eead81be8b223fc4

Use an environment variable to store the digest value of the SBOM. This environment variable is used in later steps. For example:

SBOM=localhost:5000/net-monitor@sha256:6cbf7cc5ffa82b030b57ff820d49a86c143d8c6ac483b8e5eead81be8b223fc4

List the signatures associated with the SBOM

Use notation ls to show any signatures associated with the SBOM you attached in the previous section.

notation ls $SBOM

Confirm there are no signatures shown in the output.

Generate a test key and self-signed certificate

Use notation cert generate-test to generate a test RSA key for signing artifacts, and a self-signed X.509 test certificate for verifying artifacts.

The following command generates a test key and a self-signed X.509 certificate. With the --default flag, the test key is set as a default signing key. The self-signed X.509 certificate is added to a named trust store wabbit-networks.io of type ca.

notation cert generate-test --default "wabbit-networks.io"

Use notation key ls to confirm the signing key is correctly configured. Key name with a * prefix is the default key.

notation key ls

Use notation cert ls to confirm the certificate is stored in the trust store.

notation cert ls

Sign the SBOM

Use notation sign to sign the SBOM.

notation sign $SBOM

By default, the signature format is JWS. Use --signature-format to use COSE signature format.

notation sign --signature-format cose $SBOM

The generated signature is pushed to the registry and the digest of the SBOM is returned.

Use notation ls to show the signature associated with the SBOM.

notation ls $SBOM

Confirm there is one signature, for example:

$ notation ls $SBOM
localhost:5001/net-monitor@sha256:073b75987e95b89f187a89809f08a32033972bb63cda279db8a9ca16b7ff555a
└── application/vnd.cncf.notary.signature
    └── sha256:ba3a68a28648ba18c51a479145fca60d96b43dc96c6ab22f412c89ac56a9038b

Create a trust policy

To verify the SBOM, configure the trust policy to specify trusted identities that sign the artifacts, and level of signature verification to use. For more details, see trust policy spec.

Create a JSON file with the following trust policy, for example:

cat <<EOF > ./trustpolicy.json
{
    "version": "1.0",
    "trustPolicies": [
        {
            "name": "wabbit-networks-images",
            "registryScopes": [ "*" ],
            "signatureVerification": {
                "level" : "strict" 
            },
            "trustStores": [ "ca:wabbit-networks.io" ],
            "trustedIdentities": [
                "*"
            ]
        }
    ]
}
EOF

Use notation policy import to import the trust policy configuration from a JSON file. For example:

notation policy import ./trustpolicy.json

Use notation policy show to view the applied policy configuration. For example:

notation policy show

The above JSON creates a trust policy named wabbit-networks-images. The policy has registryScopes set to *, which applies the policy to all the artifacts of any registry. The signatureVerification is set to strict, which checks all validations and any failure will fail the signature verification. This policy uses the wabbit-networks.io trust store of type ca which was created in the previous step. For more details on trust policies, see trust policy spec.

To enable trust policy for specific repositories, set the registryScopes to those specific repositories. For example:

"registryScopes": [ 
    "localhost:5001/net-monitor",
    "localhost:5001/nginx",
    "localhost:5001/hello-world"
]

Verify the container image

Use notation verify to verify signatures associated with the SBOM.

notation verify $SBOM

The digest of the supplied artifact is returned upon successful verification.

Cleanup

To remove the sample registry running on your development computer:

docker rm -f registry

To reset your notation configuration, remove the notation configuration directory. For more details, see Remove the configuration files.