Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions content/en/cosign/container_registry/_index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
type: docs
title: "Container Registries"
description: "Documentation for working with container registries"
lead: ""
date: 2020-10-06T08:49:15+00:00
lastmod: 2020-10-06T08:49:15+00:00
draft: false
images: []
weight: 80
---



230 changes: 230 additions & 0 deletions content/en/cosign/container_registry/oci_referrers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
---
type: docs
category: Container Registries
title: OCI and Referrers
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for double checking the tag fallback option and updating the doc.

Taking a step back, I'm wondering who the audience for this page is meant to be? This is pretty in-depth for a user-facing document. In an ideal world (which I admit is not where we are yet), a cosign user shouldn't really have to know what the referrer's API is, it should "just work" (hence the tag fallback - the user may not even know what OCI version their registry supports, and that's fine). The changes you made in the signing and verification docs cover the user-facing issues of the referrer's API really well already.

Where I think a dedicated page like this could be useful is if it went into more depth on using oras or crane to discover and fetch bundles and attestations in ways that cosign doesn't do (or that we want to discourage and deprecate), so that folks using other tooling to examine their attestations have a resource for building their automation around referrers vs tags.

If you don't want to make any other changes, at a minimum I would suggest that the examples for the new bundle format come first and the legacy format come later. I think we want to be encouraging people to always use the new format - but to come here for workarounds if they have older images or older tooling that only support the old format.

Copy link
Author

Choose a reason for hiding this comment

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

No problem, I'm glad you highlighted it as I had missed this in my tests.

I'm happy to change this in any way that's useful, the PR was only intended to document the current state and to provide some background for those who wanted to understand more. I can switch the examples around, to focus first on the new format, and we can decide what else needs to be documented after that.

Copy link
Author

Choose a reason for hiding this comment

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

@cmurphy I've moved the sections around, otherwise no significant changes. They are now in the order of new > old format and OCI 1.1 > 1.0.

weight: 750
---

Cosign supports the OCI 1.1 specification, which introduces the **referrers API** for discovering artifacts associated with a container image. This page explains how cosign uses the referrers API and how to configure signature and attestation storage modes.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest having an opening section called "Who is this for?" or something similar that gives a preface for who the target audience is for this section. I think this is mainly needed for developers trying to create tooling to examine the bundles that cosign is producing, while most developers just trying to use cosign don't need to be bogged down by this background knowledge.


## What is the Referrers API?

The OCI Distribution Specification 1.1 introduced the referrers API as a standardized way to discover artifacts (like signatures, attestations, and SBOMs) associated with a container image.

Instead of relying on tag naming conventions (e.g., `sha256-<digest>.sig`), the referrers API uses a `subject` field in the artifact manifest to create a direct relationship between the artifact and the image it references. Registries that support OCI 1.1 expose a `/referrers/<digest>` endpoint that returns all artifacts linked to a given image digest.

## Valid Format and Storage Combinations

| Bundle Format | Storage Mode | Signatures | Attestations | Notes |
|--------------|--------------|------------|--------------|-------|
| New (`--new-bundle-format=true`) | Referrers (OCI 1.1) | Yes | Yes | **Default in cosign 3.0+** |
| New (`--new-bundle-format=true`) | Tag-based (OCI 1.0) | Yes | Yes | Uses referrers tag fallback (`sha256-<digest>`) |
| Old (`--new-bundle-format=false`) | Referrers (OCI 1.1) | Yes | No | Signatures only; attestations always use tags |
| Old (`--new-bundle-format=false`) | Tag-based (OCI 1.0) | Yes | Yes | Legacy mode |

### Key Constraints

1. **Old format requires disabling signing config**: When using `--new-bundle-format=false`, you must also set `--use-signing-config=false`. The default TUF-based signing config requires the new bundle format.

2. **Old format attestations always use tags**: When using `--new-bundle-format=false`, attestations are always stored using tag-based storage, regardless of any `--registry-referrers-mode` flag.

## Scenario 1: New Format + OCI 1.1 Referrers
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be good to have a brief explanation of what "new format" even means, as someone who is not a cosign developer probably doesn't have that context.


When using the default new bundle format against a registry that supports the OCI 1.1 specification, cosign will store signatures and attestations using the OCI 1.1 referrers API.

### Signing

```shell
# Key-based signing
cosign sign --key cosign.key $IMAGE

# Keyless signing (default)
cosign sign $IMAGE
```

The signature is stored as an OCI 1.1 referrer with the new sigstore bundle format.
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about adding a crane or oras command for each of these examples that does a lookup of the bundle in the registry, to demonstrate what this means in practice?

Copy link
Author

Choose a reason for hiding this comment

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

I can take a look, I did have something earlier but took them out before submitting because I thought it was diving too deep.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess I'm suggesting it because I still feel like this page is taking a middle ground approach to the point where I'm still not sure who it's for. If it's just meant to be a high-level overview of how to use cosign sign, then the other examples in the other pages already take care of it and this whole page could be removed. If it's meant to be a deeper dive into the underlying mechanics of cosign and OCI, then it should lean in and really show what it's talking about.


### Verification

```shell
# Key-based verification
cosign verify --key cosign.pub $IMAGE

# Keyless verification
cosign verify \
--certificate-identity=name@example.com \
--certificate-oidc-issuer=https://accounts.example.com \
$IMAGE
```

### Attestations

```shell
# Create attestation
cosign attest \
--key cosign.key \
--type slsaprovenance \
--predicate predicate.json \
$IMAGE

# Verify attestation
cosign verify-attestation \
--key cosign.pub \
--type slsaprovenance \
$IMAGE
```

The attestation is stored as an OCI 1.1 referrer.

## Scenario 2: New Format + OCI 1.0 (Referrers Tag Schema Fallback)

When using the default new bundle format against a registry that does not support the OCI 1.1 referrers API, cosign automatically falls back to the **referrers tag schema** defined in the OCI Distribution Specification. Artifacts are stored under a `sha256-<digest>` index tag, and both signing and verification work transparently.

> **Note:** This fallback only works for clients that implement the OCI Distribution Specification 1.1 referrers tag schema. Tools written to look for old-format `.sig` tags will not find new-format signatures stored this way.

### Signing

```shell
# Key-based signing
cosign sign --key cosign.key $IMAGE

# Keyless signing
cosign sign $IMAGE
```

The signature is stored under a `sha256-<digest>` index tag (not a `.sig` tag).

### Verification

```shell
# Key-based verification
cosign verify --key cosign.pub $IMAGE

# Keyless verification
cosign verify \
--certificate-identity=name@example.com \
--certificate-oidc-issuer=https://accounts.example.com \
$IMAGE
```

### Attestations

```shell
# Create attestation
cosign attest \
--key cosign.key \
--type slsaprovenance \
--predicate predicate.json \
$IMAGE

# Verify attestation
cosign verify-attestation \
--key cosign.pub \
--type slsaprovenance \
$IMAGE
```

The attestation is stored under the same `sha256-<digest>` index tag alongside the signature.

## Scenario 3: Old Format + OCI 1.1 Referrers (Signatures Only)

This mode stores signatures using the OCI 1.1 referrers API while using the old bundle format. Note that **attestations are not supported** with OCI 1.1 in this mode, they will fall back to tag-based storage.

### Signing

```shell
# Requires COSIGN_EXPERIMENTAL=1 environment variable
COSIGN_EXPERIMENTAL=1 cosign sign \
--key cosign.key \
--new-bundle-format=false \
--use-signing-config=false \
--registry-referrers-mode=oci-1-1 \
$IMAGE
```

The signature is stored as an OCI 1.1 referrer (discoverable via `/referrers/<digest>` endpoint).

### Verification

```shell
cosign verify \
--key cosign.pub \
--new-bundle-format=false \
--experimental-oci11=true \
$IMAGE
```

> **Important:** The `--experimental-oci11` flag is required for verification to discover signatures stored via the referrers API.

## Scenario 4: Old Format + Tag-based (OCI 1.0)

Use this mode with registries that don't support OCI 1.1.

### Signing

```shell
# With key-based signing (uploads to Rekor transparency log)
cosign sign --key cosign.key \
--new-bundle-format=false \
--use-signing-config=false \
$IMAGE

# With keyless signing
cosign sign \
--new-bundle-format=false \
--use-signing-config=false \
$IMAGE
```

The signature is stored at a tag: `sha256-<digest>.sig`

### Verification

```shell
# Key-based verification
cosign verify --key cosign.pub \
--new-bundle-format=false \
$IMAGE

# Keyless verification
cosign verify \
--new-bundle-format=false \
--certificate-identity=name@example.com \
--certificate-oidc-issuer=https://accounts.example.com \
$IMAGE
```

### Attestations

```shell
# Create attestation (uploads to Rekor)
cosign attest \
--key cosign.key \
--new-bundle-format=false \
--use-signing-config=false \
--type slsaprovenance \
--predicate predicate.json \
$IMAGE

# Verify attestation
cosign verify-attestation \
--key cosign.pub \
--new-bundle-format=false \
--type slsaprovenance \
$IMAGE
```

The attestation is stored as a tag: `sha256-<digest>.att`


## Discovering Referrers

You can discover all artifacts associated with an image using the OCI referrers API:

```shell
# Using curl
curl https://registry.example.com/v2/myrepo/referrers/sha256:abc123...

# Using oras
oras discover registry.example.com/myrepo@sha256:abc123...
```
91 changes: 87 additions & 4 deletions content/en/cosign/signing/signing_with_containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,53 @@ $ cosign generate $IMAGE | openssl... | cosign attach signature --signature - $I
Pushing signature to: user/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def.sig
```

## Signature location and management
## Container registry storage options

Signatures are uploaded to an OCI artifact stored with a predictable name.
This name can be located with the `cosign triangulate` command:
Cosign supports two options for storing and discovering signatures in container registries:

- **Referrers API (OCI 1.1)**: Signatures are linked to images via the `subject` field in the artifact manifest, enabling discovery through the container registry's referrers API. This is the default in cosign 3.0+. On registries without OCI 1.1 support, cosign will automatically fall back to the referrers tag schema.
- **Tag-based (OCI 1.0)**: Signatures are stored as separate images with a predictable tag name: `sha256-<digest>.sig`. Use this when you need compatibility with older tooling that does not implement the OCI 1.1 referrers tag schema.

For more information about cosign's support for OCI and the referrers API, see [OCI and Referrers]({{< relref "cosign/container_registry/oci_referrers">}}).

## Signing with OCI 1.1 (default)

In cosign 3.0+, the default behavior uses the new bundle format which stores signatures via the OCI 1.1 referrers API:

```shell
$ cosign sign $IMAGE
```

## New format on OCI 1.0 registries

When signing with the new bundle format against a registry that does not support the OCI 1.1 referrers API, cosign automatically falls back to the **referrers tag schema** defined in the OCI Distribution Specification. The signature is stored under a `sha256-<digest>` tag (an OCI image index listing all referrers), and signing and verification will both work transparently.

> **Note:** This fallback is only available to clients that implement the OCI 1.1 referrers tag schema. Tools written to look for old-format `.sig` tags will not find new-format signatures stored this way.

## Signing with OCI 1.0 (tag-based)

To explicitly use the old bundle format with tag-based storage (i.e. for maximum compatibility with older tooling):

```shell
$ cosign sign --new-bundle-format=false --use-signing-config=false $IMAGE
```

The signature is stored at a tag (`sha256-<digest>.sig`).

> **Note:** The `--use-signing-config=false` flag is required when using `--new-bundle-format=false`. The default signing config (from TUF) requires the new bundle format, so it must be disabled for old format signing.

### Locating signatures

Use the `cosign triangulate` command to find the signature tag:

```shell
$ cosign triangulate $IMAGE
index.docker.io/user/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8.sig
```

They can be reviewed with `crane`:
### Inspecting the signature manifest

The signature manifest can be reviewed with `crane`:

```shell
$ crane manifest $(cosign triangulate $IMAGE) | jq .
Expand Down Expand Up @@ -347,3 +383,50 @@ Some registries support deletion too (DockerHub does not):
```shell
$ cosign clean $IMAGE
```

## Discovering OCI 1.1 signatures

With OCI 1.1 (the default in cosign 3.0+), signatures are linked to the image via the `subject` field and discovered through the referrers API. Use [ORAS](https://oras.land/) to list all artifacts referencing an image:

```shell
$ oras discover $IMAGE
<image>@sha256:1882fa4569e0c591ea092d3766c4893e19b8901a8e649de7067188aba3cc0679
├── application/vnd.dev.cosign.artifact.sig.v1+json
│ └── sha256:441a6e4fcf6131ea979df3ec34c141f55eb5c371e7e81bc90860e460eecaa5fb
└── application/vnd.dev.sigstore.bundle.v0.3+json
└── sha256:9a8458d9d9dda45bdf230e901eeb9695ec3c64c3750f76ee7beab59c0978193c
```

### Inspecting the signature manifest

Retrieve the signature manifest using the referrers endpoint or `oras`:

```shell
$ oras manifest fetch $REGISTRY/$REPO@sha256:441a6e4fcf6131ea979df3ec34c141f55eb5c371e7e81bc90860e460eecaa5fb | jq .
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.dev.cosign.artifact.sig.v1+json",
"size": 233,
"digest": "sha256:da96469741fd76728fb29c10514f722ea0c38c0a275d30b38231591216c0f99e"
},
"layers": [
{
"mediaType": "application/vnd.dev.cosign.simplesigning.v1+json",
"size": 242,
"digest": "sha256:4af22300d43719854f07d484efbfbabd4c31f5e7cbd0362cd1a8f9ec4c0f052c",
"annotations": {
"dev.cosignproject.cosign/signature": "MEYCIQDIg1nynEQPoxYS77beWo0iRn2V8oJg2RaNJzVA/YR3cAIhAOATaFrEonE2r7eUVS2fJStPOWO00InIruhsXHcvw1OT"
}
}
],
"subject": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 1022,
"digest": "sha256:1882fa4569e0c591ea092d3766c4893e19b8901a8e649de7067188aba3cc0679"
}
}
```

The `subject` field links the signature back to the original image.
27 changes: 27 additions & 0 deletions content/en/cosign/verifying/verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,33 @@ AcxvLtLEgRjRI4TKnMAXtIGp8K4X4CTWPEXMqSYZZUa2I1YvHyLLY2bEzA==
-----END PUBLIC KEY-----
```

## Container registry discovery options

Cosign can discover signatures stored in a container registry using two options:

1. **Referrers API (OCI 1.1)**: Queries the container registry's referrers endpoint to find linked artifacts.
2. **Tag-based (OCI 1.0)**: Looks for signatures stored with predictable tags like `sha256-<digest>.sig`

### Default verification

By default (cosign 3.0+), verification first checks for OCI 1.1 signatures via the referrers API, then falls back to tag-based discovery for OCI 1.0 signatures:

```shell
cosign verify $IMAGE \
--certificate-identity=... --certificate-oidc-issuer=...
```

### Force OCI 1.0 discovery

To skip the OCI 1.1 referrers check and use only the OCI 1.0 tag-based discovery:

```shell
cosign verify --new-bundle-format=false $IMAGE \
--certificate-identity=... --certificate-oidc-issuer=...
```

For more information about cosign's support for OCI and the referrers API, see [OCI and Referrers]({{< relref "cosign/container_registry/oci_referrers">}}).

## Custom Components

For configuring Cosign to work with custom components, checkout the [Configuring Cosign with Custom Components]({{< relref "cosign/system_config/custom_components">}}) docs to find out how to achieve this.
Expand Down
Loading