From 0e85b455690aca2d3b484eda2c9fc0579959ba77 Mon Sep 17 00:00:00 2001 From: Anso Date: Sat, 11 Jul 2026 20:35:13 -0400 Subject: [PATCH] docs: explain tags vs digests across security and registry pages (#1617) --- docs/features/auto-update-policies.mdx | 6 +++--- docs/features/private-registries.mdx | 2 +- docs/features/resources.mdx | 2 +- docs/features/security.mdx | 2 +- docs/features/stack-drift.mdx | 2 +- docs/features/vulnerability-scanning.mdx | 21 ++++++++++++++++++++- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/docs/features/auto-update-policies.mdx b/docs/features/auto-update-policies.mdx index 9d395fe3..40857c9e 100644 --- a/docs/features/auto-update-policies.mdx +++ b/docs/features/auto-update-policies.mdx @@ -14,7 +14,7 @@ Auto-Update Policies are the launchpad for every pending update across your stac Each card shows: -- The current tag and (for semver updates) the next tag, with the new version highlighted in cyan. For digest-only updates, the card shows the current tag with a **Rebuild available** marker instead of a version diff. +- The current tag and (for semver updates) the next tag, with the new version highlighted in cyan. For digest-only updates (same tag name, new registry content), the card shows the current tag with a **Rebuild available** marker instead of a version diff. See [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). - A **risk badge** derived from the version delta: `Safe · patch` (green), `Review · minor` (amber), `Blocked · major` (red), or `Digest rebuild` (gray) for non-semver tags. - The primary image reference, plus a count of additional services if more than one image in the stack has an update. - A one-line changelog preview when the registry publishes one. Registries that omit changelog metadata render the card with "No changelog available from the registry yet." @@ -80,7 +80,7 @@ Once the cause is resolved, the next check (on the interval, or via **Recheck**) | `Safe · patch` | Green (Shield icon) | Patch-level semver bump (e.g. `1.2.3` to `1.2.4`) | | `Review · minor` | Amber (AlertTriangle icon) | Minor semver bump (e.g. `1.2.3` to `1.3.0`) | | `Blocked · major` | Red (ShieldAlert icon) | Major semver bump (e.g. `1.2.3` to `2.0.0`). **Apply now** is disabled; the card surfaces the reason "Major version jumps require human review before applying." | -| `Digest rebuild` | Gray | Non-semver tag (e.g. `main`, `stable`) with an updated digest | +| `Digest rebuild` | Gray | Non-semver tag (e.g. `main`, `stable`) with an updated digest (tag name unchanged; content changed; see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests)) | A separate inline `Rebuild available` label replaces the version diff when only the digest changed (same tag, new image). The risk badge on those cards still reflects the underlying semver classification reported by the registry. @@ -127,7 +127,7 @@ For each stack with a pending image update, Sencho computes a preview by: 1. Parsing the compose file to enumerate every pullable image reference. 2. Calling the registry with your configured credentials to fetch the current tag list and remote digest. -3. Picking the highest semver tag greater than the current tag (keeping the same prefix and suffix). If the highest available tag matches the current one but the remote digest has changed, the card surfaces as a `Rebuild available` update. +3. Picking the highest semver tag greater than the current tag (keeping the same prefix and suffix). If the highest available tag matches the current one but the remote digest has changed, the card surfaces as a `Rebuild available` update. Sencho checks both a newer semver tag and a digest change behind the same tag; see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). 4. Scoring the overall stack by the most severe image bump. Any major bump marks the stack as blocked. 5. Normalizing Docker Hub library paths so credentials and changelog lookups resolve correctly. diff --git a/docs/features/private-registries.mdx b/docs/features/private-registries.mdx index d6b2edec..c26ddbe8 100644 --- a/docs/features/private-registries.mdx +++ b/docs/features/private-registries.mdx @@ -29,7 +29,7 @@ AWS ECR requires a Sencho **Admiral** license; Docker Hub, GHCR, and custom regi ## Browse tags from Resources -When you inspect an image on the Resources page, the detail sheet includes a **Registry tags** section for admins. Sencho lists tags from the configured registry that matches the image host (credentials come from that registry row only). Tag browsing always runs on the hub instance; local image digests still come from the active node. +When you inspect an image on the Resources page, the detail sheet includes a **Registry tags** section for admins. Sencho lists tag names from the configured registry that matches the image host (credentials come from that registry row only). Tag browsing always runs on the hub instance; local image digests still come from the active node. Digest comparison for updates and scans happens separately on that node. For how tags and digests relate, see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). If credentials are wrong, Sencho reports a registry error without signing you out of the dashboard. diff --git a/docs/features/resources.mdx b/docs/features/resources.mdx index 5054e395..af54dc8a 100644 --- a/docs/features/resources.mdx +++ b/docs/features/resources.mdx @@ -89,7 +89,7 @@ Click the eye icon on any image row to open a detail sheet with these sections: - **Overview** lists the ID, size, creation date, architecture and OS, author, and all repository tags. - **Config** shows the default `Cmd`, `Entrypoint`, `WorkingDir`, `User`, exposed ports, environment variables, and labels. Env vars and labels are collapsible. - **Layers** lists the layer history in build order. Each row shows the layer index, size, age, and the build command (`CreatedBy`). Empty layers (metadata-only, zero bytes) are dimmed. -- **Registry tags** (admins) lists remote tags from a matching configured registry. See [Private registries](/features/private-registries) for credential and failure behavior. +- **Registry tags** (admins) lists remote tag names from a matching configured registry. See [Private registries](/features/private-registries#browse-tags-from-resources) for credential and failure behavior. Vulnerability history and caching use the image digest when available; see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). The inspect sheet is available to all roles. Registry tag browsing is admin-only. diff --git a/docs/features/security.mdx b/docs/features/security.mdx index 39c26863..2491bfda 100644 --- a/docs/features/security.mdx +++ b/docs/features/security.mdx @@ -88,7 +88,7 @@ export the fleet's triage decisions as an OpenVEX document for use with other to ## History -The History tab lists completed scans for the active node in an inline table. Prefer digest identity when a digest is stored (short digest as the primary label, image reference as the subtitle); config and other scans without a digest show the image reference. Search matches image references or digests. Select two scans to compare. The **Scan history** button in the [Resources Hub](/features/resources) is a shortcut to the same place. +The History tab lists completed scans for the active node in an inline table. Prefer digest identity when a digest is stored (short digest as the primary label, image reference as the subtitle); config and other scans without a digest show the image reference. Search matches image references or digests. Select two scans to compare. The **Scan history** button in the [Resources Hub](/features/resources) is a shortcut to the same place. For how tags and digests relate, see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). ## Scanner setup diff --git a/docs/features/stack-drift.mdx b/docs/features/stack-drift.mdx index 5ac91651..77018165 100644 --- a/docs/features/stack-drift.mdx +++ b/docs/features/stack-drift.mdx @@ -75,7 +75,7 @@ Image references are normalized before comparison, so equivalent forms do not pr If a service has multiple replicas, any replica running a different image than the declared one triggers an image finding. This catches stacks that are mid-update with mixed versions running simultaneously. -If the Compose file declares a tag (`:latest`, `:1.25`) and the running container was pulled from a digest pin, the two forms are compared as-is. A digest-pinned container reads as an image mismatch against a tag declaration. This is intentional: the two references are not equivalent. +If the Compose file declares a tag (`:latest`, `:1.25`) and the running container was pulled from a digest pin, the two forms are compared as-is. A digest-pinned container reads as an image mismatch against a tag declaration. This is intentional: the two references are not equivalent. Sencho uses the same distinction in scan history and update detection; see [Tags vs digests](/features/vulnerability-scanning#tags-vs-digests). ### Port ranges diff --git a/docs/features/vulnerability-scanning.mdx b/docs/features/vulnerability-scanning.mdx index 118bbf7c..8cb43eab 100644 --- a/docs/features/vulnerability-scanning.mdx +++ b/docs/features/vulnerability-scanning.mdx @@ -63,7 +63,7 @@ Hovering a badge reveals the breakdown by severity and the scan timestamp. The b | **LOW** (muted) | Only low-severity vulnerabilities | | **Clean** (green) | Scan completed with zero findings | -Scan results are cached by image digest. If the same digest is scanned again within 24 hours, Sencho returns the cached result instantly instead of re-running Trivy. To force a fresh scan, open the drawer and click **Re-scan**. +Scan results are cached by image digest (see [Tags vs digests](#tags-vs-digests)). If the same digest is scanned again within 24 hours, Sencho returns the cached result instantly instead of re-running Trivy. To force a fresh scan, open the drawer and click **Re-scan**. ## The scan results drawer @@ -345,6 +345,25 @@ Typical upload flow for GitHub code scanning: sarif_file: sencho-scan.sarif.json ``` + +## Tags vs digests + +A **tag** is a mutable name for an image (`nginx:1.25`, `app:latest`). Compose files and day-to-day updates usually pin by tag because the name is easy to read and bump. + +A **digest** is the immutable content hash of that image (`sha256:…`, often written as `image@sha256:…`). The registry can move a tag to a new digest without changing the tag name, so two pulls of `app:latest` can be different builds. + +Sencho keys security work on digest when Docker provides one: + +- The 24-hour scan cache +- History primary labels and per-identity retention +- Apples-to-apples scan comparison + +When no digest is stored (for example a compose config scan), History falls back to the image reference. + +Tags still drive operations: compose pins, Resources row labels, semver auto-update, and the admin **Registry tags** browser (remote tag names only; see [Private registries](/features/private-registries#browse-tags-from-resources)). + +When the tag name is unchanged but the remote content changed, auto-update surfaces **Rebuild available** / **Digest rebuild**, and a new scan gets its own History row under the new digest. Comparing across digests is allowed but flagged. If compose declares a tag while the running container is digest-pinned, [Stack drift](/features/stack-drift#image-comparison) treats them as different references on purpose. + ## Scan history Every scan Sencho runs is stored with its full vulnerability detail. History retention keeps a configurable number of scans per image digest (or per image reference when no digest is stored; default 50). Configure the cap under **Settings → Operations → Data Retention**. The history powers two things: digest caching (skip re-scanning a digest already scanned within 24 hours) and trend insight (compare a new scan to its predecessor to see what changed).