diff --git a/docs/getting-started/docker.mdx b/docs/getting-started/docker.mdx index 69d01632d..acc6257aa 100644 --- a/docs/getting-started/docker.mdx +++ b/docs/getting-started/docker.mdx @@ -68,6 +68,11 @@ Finally, run the container with the same parameters originally used to create th ```bash docker run -d ... ``` +:::info +All official Seerr images are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/). + +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. +::: :::tip 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. diff --git a/docs/using-jellyseerr/advanced/index.mdx b/docs/using-jellyseerr/advanced/index.mdx new file mode 100644 index 000000000..f0ffdc92f --- /dev/null +++ b/docs/using-jellyseerr/advanced/index.mdx @@ -0,0 +1,15 @@ +--- +title: Advanced Features +description: Advanced configuration and use cases. +sidebar_position: 6 +--- + +# Advanced Features + +## Advanced Configuration and Use Cases + +Seerr currently offers advanced features for power users and specific use cases: + +import DocCardList from '@theme/DocCardList'; + + diff --git a/docs/using-jellyseerr/advanced/verifying-signed-images.mdx b/docs/using-jellyseerr/advanced/verifying-signed-images.mdx new file mode 100644 index 000000000..b05b2d255 --- /dev/null +++ b/docs/using-jellyseerr/advanced/verifying-signed-images.mdx @@ -0,0 +1,278 @@ +--- +id: verifying-signed-images +title: Verifying Signed Images +sidebar_label: Verify Signed Images +description: Learn how to verify Seerr's signed container images and SBOM attestations using Cosign, Docker, Podman, or Skopeo. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Verifying Signed Images + +All Seerr container images published to GitHub Container Registry (GHCR) are cryptographically signed using [Sigstore Cosign](https://docs.sigstore.dev/quickstart/quickstart-cosign/). +This ensures that the images you pull are authentic, tamper-proof, and built by the official Seerr release pipeline. + +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. + +--- + +## Prerequisites + +You will need the following tools installed: + +- [Cosign](https://docs.sigstore.dev/cosign/system_config/installation/) +- [Docker](https://docs.docker.com/get-docker/) **or** +- [Podman](https://podman.io/getting-started/installation) (including [Skopeo](https://github.com/containers/skopeo/blob/main/install.md)) + +```bash +cosign version +``` + +If using **Podman**, ensure `skopeo` is available: + +```bash +skopeo --version +``` + +--- + +## Image Locations + +Official Seerr images are available from: + +- GitHub Container Registry (GHCR): `ghcr.io/seerr-team/seerr:` + +You can view all available tags on the [Seerr Releases page](https://github.com/seerr-team/seerr/releases). + +--- + +## Verifying a Specific Release Tag + +Each tagged release (for example `v2.7.4`) is immutable and cryptographically signed. +Verification should always be performed using the image digest (SHA256). + +### Retrieve the Image Digest + + + + +```bash +docker buildx imagetools inspect docker.io/seerr-team/seerr:v2.7.4 --format '{{json .Manifest.Digest}}' | tr -d '"' +``` + + + + +```bash +skopeo inspect docker://ghcr.io/seerr-team/seerr:v2.7.4 --format '{{.Digest}}' +``` + + + +Example output: + +``` +sha256:abcd1234... +``` + +--- + +### Verify the Image Signature + + + + +```bash +cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \ + --certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + + +```bash +cosign verify seerr/seerr@sha256:abcd1234... \ + --certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + +:::info Successful Verification Example +Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...` + +The following checks were performed: + +- Cosign claims validated +- Signatures verified against the transparency log +- Certificate issued by Fulcio to the expected workflow identity +::: + +--- + +## Verifying the `latest` Tag + +:::warning Latest Tag Warning +The `latest` tag is **mutable**, meaning it will change with each new release. +Always verify the digest that `latest` currently points to. +::: + +### Retrieve the Digest for `latest` + + + + +```bash +docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"' +``` + + + + +```bash +skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}' +``` + + + +Example output: + +``` +sha256:abcd1234... +``` + +### Verify the Signature + + + + +```bash +cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \ + --certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + + +```bash +cosign verify seerr/seerr@sha256:abcd1234... \ + --certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + +:::tip +The wildcard `v.*` ensures verification works for any versioned release that `latest` represents. +::: + +--- + +## Verifying SBOM Attestations + +Each image includes a CycloneDX SBOM attestation. + +### Verify the Attestation + +```bash +cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \ + --type cyclonedx \ + --certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` +:::info Successful Verification Example +Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...` + +The following checks were performed: + +- Cosign claims validated +- Signatures verified against the transparency log +- Certificate issued by Fulcio to the expected workflow identity +::: + +### Extract the SBOM for Inspection + +```bash +cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \ + --type cyclonedx \ + --certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" | jq -r '.payload | @base64d' > sbom.json +``` + +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/). + +--- + +## Expected Certificate Identity + +The expected certificate identity for all signed Seerr images is: + +``` +https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v* +``` + +This confirms that the image was: + +- Built by the official Seerr Release workflow +- Produced from the seerr-team/seerr repository +- Signed using GitHub’s OIDC identity via Sigstore Fulcio + +--- + +## Troubleshooting + +| Issue | Likely Cause | Suggested Fix | +|-------|---------------|----------------| +| `no matching signatures` | Incorrect digest or tag | Retrieve the digest again using Docker or Skopeo | +| `certificate identity does not match expected` | Workflow reference changed | Ensure your `--certificate-identity` matches this documentation | +| `cosign: command not found` | Cosign not installed | Install Cosign from the official release | +| `certificate expired` | Old release | Verify a newer tag or digest | + +--- + +## Example: Full Verification Flow + + + + +```bash +DIGEST=$(docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"') + +cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \ + --certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" + +cosign verify-attestation ghcr.io/seerr-team/seerr@"$DIGEST" \ + --type cyclonedx \ + --certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + + +```bash +DIGEST=$(skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}') + +cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \ + --certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" +``` + + + +--- + +## Further Reading + +- [Sigstore Documentation](https://docs.sigstore.dev) +- [Cosign Verification Guide](https://docs.sigstore.dev/cosign/verifying/verify/) +- [CycloneDX Specification](https://cyclonedx.org/specification/overview/) +- [Trivy Documentation](https://trivy.dev/latest/docs/) +- [Skopeo Documentation](https://github.com/containers/skopeo) +- [Podman Documentation](https://podman.io/get-started/) +- [Docker Documentation](https://docs.docker.com/) +- [Seerr GitHub Repository](https://github.com/seerr-team/seerr)