Skip to content

Updating cosign signing docs#419

Open
steiza wants to merge 4 commits intosigstore:mainfrom
steiza:update_cosign_signing
Open

Updating cosign signing docs#419
steiza wants to merge 4 commits intosigstore:mainfrom
steiza:update_cosign_signing

Conversation

@steiza
Copy link
Member

@steiza steiza commented Mar 6, 2026

Summary

Making progress on #418

Release Note

  • Updated cosign signing documentation to reflect Cosign v3 commands

Documentation

N/A

Signed-off-by: Zach Steindler <steiza@github.com>
@netlify
Copy link

netlify bot commented Mar 6, 2026

Deploy Preview for docssigstore ready!

Name Link
🔨 Latest commit 6194ae3
🔍 Latest deploy log https://app.netlify.com/projects/docssigstore/deploys/69b1612d54356a0008eb1fb4
😎 Deploy Preview https://deploy-preview-419--docssigstore.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Signed-off-by: Zach Steindler <steiza@github.com>
Copy link
Contributor

@Hayden-IO Hayden-IO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thank you for cleaning this up!

Any updates we need to make to https://github.com/sigstore/docs/blob/main/content/en/quickstart/quickstart-cosign.md? You made an update here to not use ttl.sh, should we make the same change in the quickstart guide?

@Hayden-IO Hayden-IO requested a review from cmurphy March 9, 2026 18:18
Signed-off-by: Zach Steindler <steiza@github.com>
Hayden-IO
Hayden-IO previously approved these changes Mar 9, 2026
```shell
$ cosign signing-config create \
--fulcio="url=https://fulcio.example.com,api-version=1,start-time=2024-01-01T00:00:00Z,operator=example.com" \
--rekor="url=https://rekor.example.com,api-version=2,start-time=2024-01-01T00:00:00Z,operator=example.com" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also have a --tsa=... if the example is using Rekor v2.

Then sign an image with your custom signing config:

```shell
$ cosign sign --signing-config custom.signingconfig.json \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently (this might change with one in-flight refactoring PR) I think this also needs --trusted-root if there is a CT log involved.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran this command as-is on main and it seemed to work for me.

## SBOMs (Software Bill Of Materials)

SBOMs can also be stored in an OCI registry, using this [specification](https://github.com/sigstore/cosign/blob/main/specs/SBOM_SPEC.md).
There's a couple of different approaches SBOMs, depending on if you're working with container images or not.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
There's a couple of different approaches SBOMs, depending on if you're working with container images or not.
SBOMs can be treated as either standalone OCI objects, or as container image attestations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I wanted to get across here (and maybe you can help me wordsmith) is that you can use SBOMs with Cosign both if you're working with container images (sign, attest), as well as if you're using files on disk (sign-blob, attest-blob).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I got it, how about just that:

You can use SBOMs with Cosign both if you're working with container images (sign, attest), as well as if you're using files on disk (sign-blob, attest-blob).

SBOMs can also be stored in an OCI registry, using this [specification](https://github.com/sigstore/cosign/blob/main/specs/SBOM_SPEC.md).
There's a couple of different approaches SBOMs, depending on if you're working with container images or not.

Cosign can attach these using the `cosign attach sbom` command. In the following example, we'll be generating an SBOM for our sample container image by using the [syft](https://github.com/anchore/syft) tool created by Anchore community, then we'll be storing it in an OCI registry, once we store it, then we'll be signing the image tag that includes the SBOM itself, and verifying it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know about syft, if it's still a useful tool then I think it would be nice to keep some reference to it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't get syft to work to create an attested SBOM 😞 Their usage of Cosign is also quite out of date (v1.12.0).

```

Note that, attaching SBOMs this way does not sign them. If you want to sign the SBOM, you can use the following command:
Another option is to use `cosign attest` when signing your container image to include information about the SBOM:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly what cosign is useful for, I think? Maybe move this option to the top?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, maybe you can help me wordsmith here. What I'm trying to get across is that if you're signing something, and are thinking "I'd like to add some metadata to this signature" you should really consider doing attest instead of sign.

I'm sort of torn on which approach is "better". I think for container images, you might be better off signing the SBOM separately, instead of including it as metadata in the container image signature. But that's not a strongly held belief, and this is certainly one of the issues folks are having with Cosign today - they are looking for more prescriptive guidance on how to use it with container images and SBOMs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I don't think I have useful input here, I don't mind leaving it as-is

{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
```

## Tag signing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we want these sections removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tag signing the use case doesn't make a lot of sense to me. I think today if you want the release name to digest mapping to have integrity you'd use something like https://github.com/in-toto/attestation/blob/main/spec/predicates/release.md, which leads to a second point that I think if you find yourself doing cosign sign -a what you really should be doing is cosign attest --predicate, especially since now a Cosign OCI signature is an attestation (with predicate type https://sigstore.dev/cosign/sign/v1).

For base image signing there's no reason you couldn't do that, but I don't think it needs special mention - you would sign the base image URI. You definitely would not sign each layer - how the heck would you verify that? This is sort of typical of early Cosign "sign everything now, figure out verification later" approach.

Countersigning I was more on the fence. There's no reason why you can't cosign sign targeting a protobuf bundle in the registry, but I don't think that's a use-case we necessarily want to encourage. If you want to do it, and you know what you're doing, go ahead, but I'm not sure it needs to be part of our documentation.


```shell
$ echo "my first artifact" > artifact
$ cosign upload blob -f artifact gcr.io/user/demo/artifact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an equivalent crane or oras command to help people with this use case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I sort of struggle with what's in scope for Cosign (or not), especially when it comes to OCI. I think if you want to upload blobs into a container registry, we can't stop you, but that's really between you and your container registry, not something Cosign needs to walk you through in its documentation. 🤷

$ cosign sign $IMAGE
```

## Add annotations with a signature
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like annotations are deprecated, why don't we want to include examples of it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned this above, but I think it's difficult to answer "when should I use cosign sign -a vs when should I use cosign attest --predicate. I personally would strongly recommend people use cosign attest --predicate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be wrong but I think one difference is people can verify that individual annotations are present, but for attestations you have to have more complex policy files to verify their contents. I lean slightly more on the side of keeping documentation and explaining the difference versus letting people discover it in the command line help and not have a good base for understanding it.

}
}
$ echo '{"sbom_path": "example.com/...", "sbom_hash": "sha256:0a1b2c..."}' > sbom.predicate.json
$ cosign attest --type custom --predicate sbom.predicate.json $IMAGE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why use a custom type with an arbitrary predicate instead of keeping the SPDX example for SBOMs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really want folks to move away from things like https://github.com/in-toto/attestation/blob/main/spec/predicates/cyclonedx.md and https://github.com/in-toto/attestation/blob/main/spec/predicates/spdx2.md.

SBOMs range from 1 - 100 MBs, and if you stuff the entire SBOM into the Sigstore protobuf bundle (using those predicates) then your Sigstore bundle can be 100 MBs. Not only does this cause problems with Rekor (mostly v1 I think), this also means that anytime you want to verify the container image signature you might have to download 100 MBs of data.

Instead, I think folks should use https://github.com/in-toto/attestation/blob/main/spec/predicates/reference.md, and indeed, this is what we at GitHub are moving things like https://github.com/actions/attest-sbom to. Unfortunately, cosign attest today doesn't let you reference arbitrary predicate types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I got it, that makes a lot of sense and I wasn't aware we were trying to move people off of the individual predicate types.

Should we be more explicit about why we're recommending using the custom predicate type and a hash instead of the whole SBOM? Or is there a place we could talk about the advantages (searchability) and disadvantages (size) of using the more explicit predicates?

Copy link
Member Author

@steiza steiza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of great questions! I added some opinionated answers on my current perspective.

## SBOMs (Software Bill Of Materials)

SBOMs can also be stored in an OCI registry, using this [specification](https://github.com/sigstore/cosign/blob/main/specs/SBOM_SPEC.md).
There's a couple of different approaches SBOMs, depending on if you're working with container images or not.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I wanted to get across here (and maybe you can help me wordsmith) is that you can use SBOMs with Cosign both if you're working with container images (sign, attest), as well as if you're using files on disk (sign-blob, attest-blob).

```

Note that, attaching SBOMs this way does not sign them. If you want to sign the SBOM, you can use the following command:
Another option is to use `cosign attest` when signing your container image to include information about the SBOM:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, maybe you can help me wordsmith here. What I'm trying to get across is that if you're signing something, and are thinking "I'd like to add some metadata to this signature" you should really consider doing attest instead of sign.

I'm sort of torn on which approach is "better". I think for container images, you might be better off signing the SBOM separately, instead of including it as metadata in the container image signature. But that's not a strongly held belief, and this is certainly one of the issues folks are having with Cosign today - they are looking for more prescriptive guidance on how to use it with container images and SBOMs.

}
}
$ echo '{"sbom_path": "example.com/...", "sbom_hash": "sha256:0a1b2c..."}' > sbom.predicate.json
$ cosign attest --type custom --predicate sbom.predicate.json $IMAGE
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really want folks to move away from things like https://github.com/in-toto/attestation/blob/main/spec/predicates/cyclonedx.md and https://github.com/in-toto/attestation/blob/main/spec/predicates/spdx2.md.

SBOMs range from 1 - 100 MBs, and if you stuff the entire SBOM into the Sigstore protobuf bundle (using those predicates) then your Sigstore bundle can be 100 MBs. Not only does this cause problems with Rekor (mostly v1 I think), this also means that anytime you want to verify the container image signature you might have to download 100 MBs of data.

Instead, I think folks should use https://github.com/in-toto/attestation/blob/main/spec/predicates/reference.md, and indeed, this is what we at GitHub are moving things like https://github.com/actions/attest-sbom to. Unfortunately, cosign attest today doesn't let you reference arbitrary predicate types.

{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
```

## Tag signing
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tag signing the use case doesn't make a lot of sense to me. I think today if you want the release name to digest mapping to have integrity you'd use something like https://github.com/in-toto/attestation/blob/main/spec/predicates/release.md, which leads to a second point that I think if you find yourself doing cosign sign -a what you really should be doing is cosign attest --predicate, especially since now a Cosign OCI signature is an attestation (with predicate type https://sigstore.dev/cosign/sign/v1).

For base image signing there's no reason you couldn't do that, but I don't think it needs special mention - you would sign the base image URI. You definitely would not sign each layer - how the heck would you verify that? This is sort of typical of early Cosign "sign everything now, figure out verification later" approach.

Countersigning I was more on the fence. There's no reason why you can't cosign sign targeting a protobuf bundle in the registry, but I don't think that's a use-case we necessarily want to encourage. If you want to do it, and you know what you're doing, go ahead, but I'm not sure it needs to be part of our documentation.


```shell
$ echo "my first artifact" > artifact
$ cosign upload blob -f artifact gcr.io/user/demo/artifact
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I sort of struggle with what's in scope for Cosign (or not), especially when it comes to OCI. I think if you want to upload blobs into a container registry, we can't stop you, but that's really between you and your container registry, not something Cosign needs to walk you through in its documentation. 🤷

$ cosign sign $IMAGE
```

## Add annotations with a signature
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned this above, but I think it's difficult to answer "when should I use cosign sign -a vs when should I use cosign attest --predicate. I personally would strongly recommend people use cosign attest --predicate.

Signed-off-by: Zach Steindler <steiza@github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants