Skip to content

Commit 618563c

Browse files
sudo-krakenCopilot
andauthored
docs: added guide for image verification (#2051)
* docs: added guide for image verification * Update verifying-signed-images.mdx Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent 8688645 commit 618563c

File tree

3 files changed

+298
-0
lines changed

3 files changed

+298
-0
lines changed

docs/getting-started/docker.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ Finally, run the container with the same parameters originally used to create th
6868
```bash
6969
docker run -d ...
7070
```
71+
:::info
72+
All official Seerr images are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/).
73+
74+
To confirm that the container image you are using is authentic and unmodified, please refer to the [Verifying Signed Images](/using-jellyseerr/advanced/verifying-signed-images) guide.
75+
:::
7176

7277
:::tip
7378
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Jellyseerr up-to-date automatically.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Advanced Features
3+
description: Advanced configuration and use cases.
4+
sidebar_position: 6
5+
---
6+
7+
# Advanced Features
8+
9+
## Advanced Configuration and Use Cases
10+
11+
Seerr currently offers advanced features for power users and specific use cases:
12+
13+
import DocCardList from '@theme/DocCardList';
14+
15+
<DocCardList />
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
---
2+
id: verifying-signed-images
3+
title: Verifying Signed Images
4+
sidebar_label: Verify Signed Images
5+
description: Learn how to verify Seerr's signed container images and SBOM attestations using Cosign, Docker, Podman, or Skopeo.
6+
---
7+
8+
import Tabs from '@theme/Tabs';
9+
import TabItem from '@theme/TabItem';
10+
11+
# Verifying Signed Images
12+
13+
All Seerr container images published to GitHub Container Registry (GHCR) are cryptographically signed using [Sigstore Cosign](https://docs.sigstore.dev/quickstart/quickstart-cosign/).
14+
This ensures that the images you pull are authentic, tamper-proof, and built by the official Seerr release pipeline.
15+
16+
Each image also includes a CycloneDX SBOM (Software Bill of Materials) attestation, generated with [Trivy](https://aquasecurity.github.io/trivy/), providing transparency about all dependencies included in the image.
17+
18+
---
19+
20+
## Prerequisites
21+
22+
You will need the following tools installed:
23+
24+
- [Cosign](https://docs.sigstore.dev/cosign/system_config/installation/)
25+
- [Docker](https://docs.docker.com/get-docker/) **or**
26+
- [Podman](https://podman.io/getting-started/installation) (including [Skopeo](https://github.com/containers/skopeo/blob/main/install.md))
27+
28+
```bash
29+
cosign version
30+
```
31+
32+
If using **Podman**, ensure `skopeo` is available:
33+
34+
```bash
35+
skopeo --version
36+
```
37+
38+
---
39+
40+
## Image Locations
41+
42+
Official Seerr images are available from:
43+
44+
- GitHub Container Registry (GHCR): `ghcr.io/seerr-team/seerr:<tag>`
45+
46+
You can view all available tags on the [Seerr Releases page](https://github.com/seerr-team/seerr/releases).
47+
48+
---
49+
50+
## Verifying a Specific Release Tag
51+
52+
Each tagged release (for example `v2.7.4`) is immutable and cryptographically signed.
53+
Verification should always be performed using the image digest (SHA256).
54+
55+
### Retrieve the Image Digest
56+
57+
<Tabs groupId="verify-methods">
58+
<TabItem value="docker" label="Docker">
59+
60+
```bash
61+
docker buildx imagetools inspect docker.io/seerr-team/seerr:v2.7.4 --format '{{json .Manifest.Digest}}' | tr -d '"'
62+
```
63+
</TabItem>
64+
65+
<TabItem value="podman" label="Podman / Skopeo">
66+
67+
```bash
68+
skopeo inspect docker://ghcr.io/seerr-team/seerr:v2.7.4 --format '{{.Digest}}'
69+
```
70+
</TabItem>
71+
</Tabs>
72+
73+
Example output:
74+
75+
```
76+
sha256:abcd1234...
77+
```
78+
79+
---
80+
81+
### Verify the Image Signature
82+
83+
<Tabs groupId="registry-methods">
84+
<TabItem value="ghcr" label="GitHub Container Registry (GHCR)">
85+
86+
```bash
87+
cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \
88+
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
89+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
90+
```
91+
</TabItem>
92+
93+
<TabItem value="dockerhub" label="Docker Hub">
94+
95+
```bash
96+
cosign verify seerr/seerr@sha256:abcd1234... \
97+
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
98+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
99+
```
100+
</TabItem>
101+
</Tabs>
102+
103+
:::info Successful Verification Example
104+
Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...`
105+
106+
The following checks were performed:
107+
108+
- Cosign claims validated
109+
- Signatures verified against the transparency log
110+
- Certificate issued by Fulcio to the expected workflow identity
111+
:::
112+
113+
---
114+
115+
## Verifying the `latest` Tag
116+
117+
:::warning Latest Tag Warning
118+
The `latest` tag is **mutable**, meaning it will change with each new release.
119+
Always verify the digest that `latest` currently points to.
120+
:::
121+
122+
### Retrieve the Digest for `latest`
123+
124+
<Tabs groupId="verify-methods">
125+
<TabItem value="docker" label="Docker">
126+
127+
```bash
128+
docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"'
129+
```
130+
</TabItem>
131+
132+
<TabItem value="podman" label="Podman / Skopeo">
133+
134+
```bash
135+
skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}'
136+
```
137+
</TabItem>
138+
</Tabs>
139+
140+
Example output:
141+
142+
```
143+
sha256:abcd1234...
144+
```
145+
146+
### Verify the Signature
147+
148+
<Tabs groupId="registry-methods">
149+
<TabItem value="ghcr" label="GHCR">
150+
151+
```bash
152+
cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \
153+
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
154+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
155+
```
156+
</TabItem>
157+
158+
<TabItem value="dockerhub" label="Docker Hub">
159+
160+
```bash
161+
cosign verify seerr/seerr@sha256:abcd1234... \
162+
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
163+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
164+
```
165+
</TabItem>
166+
</Tabs>
167+
168+
:::tip
169+
The wildcard `v.*` ensures verification works for any versioned release that `latest` represents.
170+
:::
171+
172+
---
173+
174+
## Verifying SBOM Attestations
175+
176+
Each image includes a CycloneDX SBOM attestation.
177+
178+
### Verify the Attestation
179+
180+
```bash
181+
cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \
182+
--type cyclonedx \
183+
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
184+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
185+
```
186+
:::info Successful Verification Example
187+
Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...`
188+
189+
The following checks were performed:
190+
191+
- Cosign claims validated
192+
- Signatures verified against the transparency log
193+
- Certificate issued by Fulcio to the expected workflow identity
194+
:::
195+
196+
### Extract the SBOM for Inspection
197+
198+
```bash
199+
cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \
200+
--type cyclonedx \
201+
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
202+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" | jq -r '.payload | @base64d' > sbom.json
203+
```
204+
205+
You can open `sbom.json` in a CycloneDX viewer or analyse it with [Trivy](https://aquasecurity.github.io/trivy/) or [Dependency-Track](https://dependencytrack.org/).
206+
207+
---
208+
209+
## Expected Certificate Identity
210+
211+
The expected certificate identity for all signed Seerr images is:
212+
213+
```
214+
https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v*
215+
```
216+
217+
This confirms that the image was:
218+
219+
- Built by the official Seerr Release workflow
220+
- Produced from the seerr-team/seerr repository
221+
- Signed using GitHub’s OIDC identity via Sigstore Fulcio
222+
223+
---
224+
225+
## Troubleshooting
226+
227+
| Issue | Likely Cause | Suggested Fix |
228+
|-------|---------------|----------------|
229+
| `no matching signatures` | Incorrect digest or tag | Retrieve the digest again using Docker or Skopeo |
230+
| `certificate identity does not match expected` | Workflow reference changed | Ensure your `--certificate-identity` matches this documentation |
231+
| `cosign: command not found` | Cosign not installed | Install Cosign from the official release |
232+
| `certificate expired` | Old release | Verify a newer tag or digest |
233+
234+
---
235+
236+
## Example: Full Verification Flow
237+
238+
<Tabs groupId="verify-examples">
239+
<TabItem value="docker" label="Docker">
240+
241+
```bash
242+
DIGEST=$(docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"')
243+
244+
cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \
245+
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
246+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
247+
248+
cosign verify-attestation ghcr.io/seerr-team/seerr@"$DIGEST" \
249+
--type cyclonedx \
250+
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
251+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
252+
```
253+
</TabItem>
254+
255+
<TabItem value="podman" label="Podman / Skopeo">
256+
257+
```bash
258+
DIGEST=$(skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}')
259+
260+
cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \
261+
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
262+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
263+
```
264+
</TabItem>
265+
</Tabs>
266+
267+
---
268+
269+
## Further Reading
270+
271+
- [Sigstore Documentation](https://docs.sigstore.dev)
272+
- [Cosign Verification Guide](https://docs.sigstore.dev/cosign/verifying/verify/)
273+
- [CycloneDX Specification](https://cyclonedx.org/specification/overview/)
274+
- [Trivy Documentation](https://trivy.dev/latest/docs/)
275+
- [Skopeo Documentation](https://github.com/containers/skopeo)
276+
- [Podman Documentation](https://podman.io/get-started/)
277+
- [Docker Documentation](https://docs.docker.com/)
278+
- [Seerr GitHub Repository](https://github.com/seerr-team/seerr)

0 commit comments

Comments
 (0)