Verifying image signatures¶
Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user.
To verify image signatures, zot supports the following tools:
Cosign v3 Sigstore bundles¶
zot recognizes the Sigstore bundle format emitted by cosign v3, with artifact media type application/vnd.dev.sigstore.bundle.v0.3+json. These signatures are discovered through the OCI referrers API and are included in zot's signature verification and search metadata alongside legacy cosign signatures.
Cosign v3 bundles are verified against uploaded cosign public keys in the same way as other key-based cosign signatures. No additional zot configuration is required beyond enabling cosign verification and uploading the corresponding public key.
Signatures, attestations, and metadata storage¶
Cosign attestations are OCI referrers, not image signatures. An attestation by itself does not cause zot to report an image as signed.
Beginning with zot v2.1.22, signature verification reads signature payloads from blob storage. zot no longer copies those layer bytes into MetaDB.
Older MetaDB records may still contain that duplicated content until the repository record is updated again (for example after a pull or a signature change). Verification keeps working either way. You do not need to reclaim disk space for correctness.
If you use a local BoltDB MetaDB (meta.db under storage.rootDirectory) and the file is large, reclaiming space is optional. Redis and DynamoDB MetaDB backends are not affected by this BoltDB file-size behavior.
Option A — compact meta.db (keeps existing search metadata and user data):
bbolt compact copies every live key and value. It only reclaims space from freelist pages left behind after repository records were rewritten without the old signature payloads. Untouched legacy records still contain those payloads and survive compaction. Prefer this option after normal registry traffic has rewritten the large repos, or use Option B when you need to drop every leftover payload in one step.
- Install the
bboltCLI if needed:go install go.etcd.io/bbolt/cmd/bbolt@latest(seego.etcd.io/bbolt). - Stop zot so nothing is writing the database.
- Change to the storage root directory that contains
meta.db. - Create a compacted copy:
bbolt compact -o meta.db.new meta.db. - Keep a backup, then replace the original:
mv meta.db meta.db.bak && mv meta.db.new meta.db. - Ensure the new file is owned by the zot process user (for example
chown zot:zot meta.db). - Start zot and confirm the registry is healthy.
- After you are satisfied, remove
meta.db.bak.
Option B — recreate meta.db (forces a full metadata rebuild):
Removing
meta.dbalso deletes data that storage cannot rebuild, including API keys, user stars and bookmarks, and download statistics. Keep the backup until you confirm you do not need that state. On start, zot walks storage and rebuilds repository metadata before it becomes ready, so the registry is unavailable for that time. On a large registry the walk can take long enough that aType=notifysystemd unit hits its startup timeout; raiseTimeoutStartSecor useType=simplefor that restart if needed.
- Stop zot.
- Rename or move
meta.dbaside as a backup (for examplemv meta.db meta.db.bak). - Start zot. It creates a new
meta.dband rebuilds repository metadata from storage before serving traffic. - After you are satisfied, remove the backup.
Avoid downgrading after the metadata has been rewritten by v2.1.22. Earlier releases can expect signature content to be embedded in MetaDB.
Enabling image signature verification¶
To enable image signature verification, add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:
The following table lists the configurable attributes of the trust extension.
| Attribute | Description |
|---|---|
enable | If this attribute is missing, signature verification is disabled by default. Signature verification is enabled by including this attribute and setting it to true. You must also enable at least one of the verification tools. |
cosign | Set to true to enable signature verification using the cosign tool. |
notation | Set to true to enable signature verification using the notation tool. |
What is needed for verifying signatures¶
To verify the validity of a signature for an image, zot makes use of two types of files:
-
A public key file that pairs with the private key used to sign an image with
cosign -
A certificate file that is used to sign an image with
notation
Upload these files using an extension of the zot API, as shown in the following examples:
-
To upload a public key for cosign:
API path
Example request ResultThe uploaded file is stored in the
_cosigndirectory under therootDirspecified in the zot configuration file or in the Secrets Manager. -
To upload a certificate for notation:
API path
When uploading a certificate, you should specify the
truststoreType. If the truststore is a certificate authority, the value isca. This is the default if this attribute is omitted.Example request
ResultThe uploaded file is stored in the
_notation/truststore/x509/{truststoreType}/defaultdirectory under therootDirspecified in the zot configuration file or in the Secrets Manager.
Where needed files are stored¶
Uploaded public keys and certificates are stored in the local filesystem, in specific directories named _cosign and _notation under $rootDir, or in the Secrets Manager.
-
The
_cosigndirectory contains uploaded public key files in the following structure: -
The
_notationdirectory contains a set of files in the following structure:_notation ├── trustpolicy.json └── truststore └── x509 └── $truststoreType └── default └── $certificateIn this directory, the
trustpolicy.jsonfile contains content that is updated automatically whenever a new certificate is added to a new truststore. This content cannot be changed by the user. An example of thetrustpolicy.jsonfile content is shown below:{ "version": "1.0", "trustPolicies": [ { "name": "default-config", "registryScopes": [ "*" ], "signatureVerification": { "level" : "strict" }, "trustStores": ["ca:default", "signingAuthority:default", "tsa:default"], "trustedIdentities": [ "*" ] } ] }-
By default, the
trustpolicy.jsonfile sets thesignatureVerification.levelproperty tostrict, which enforces all validations. For example, a signature is not trusted if its certificate has expired, even if the certificate verifies the signature. -
The
trustpolicy.jsonfile contains three default truststores:ca:default,signingAuthority:default, andtsa:default. The TSA truststore enables verification of signatures that use a trusted timestamp authority. This list of truststores is not updated when a new certificate is uploaded. -
The content of the
trustStoresfield will match the content of the_notation/truststoredirectory.
-
How signature verification works¶
Based on the uploaded files and the information about images stored in zot's database, signature verification is performed for all signed images. The verification result for each signed image is stored in the database and is visible from GraphQL. The stored information about a signature includes:
- The tool that was used to generate the signature, such as
cosignornotation - The trustworthiness of the signature, such as whether a certificate or public key exists that can successfully verify the signature
-
The author of the signature, which can be either:
- The public key, for signatures generated using
cosign - The subject of the certificate, for signatures generated using
notation
- The public key, for signatures generated using
Example of GraphQL output¶
Sample request
Sample response
{
"data": {
"Image": {
"Digest":"sha256:6c19fba547b87bde9a45df2f8563e0c61826d098dd30192a2c8b86da1e1a6360",
"IsSigned": true,
"Tag": "latest",
"SignatureInfo":[
{
"Tool":"cosign",
"IsTrusted":false,
"Author":""
},
{
"Tool":"cosign",
"IsTrusted":false,
"Author":""
},
{
"Tool":"cosign",
"IsTrusted": true,
"Author":"-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9pN+/hGcFlh4YYaNvZxNvuh8Qyhl\npURz77qScOHe3DqdmiWiuqIseyhEdjEDwpL6fHRwu3a2Nd9wbKqm0la76w==\n-----END PUBLIC KEY-----\n"
},
{
"Tool":"notation",
"IsTrusted": false,
"Author":"CN=v4-test,O=Notary,L=Seattle,ST=WA,C=US"
},
{
"Tool":"notation",
"IsTrusted": true,
"Author":"CN=multipleSig,O=Notary,L=Seattle,ST=WA,C=US"
}
]
}
}
}