-
Notifications
You must be signed in to change notification settings - Fork 0
feat(e9): publish signed hub OCI image #170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,7 +4,9 @@ Sith releases are immutable, tag-driven builds from `main`. Stable releases use | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| the beta channel uses `vMAJOR.MINOR.PATCH-beta.N` and never replaces the latest stable release. The release job creates a draft, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| builds four archives with GoReleaser, emits an SPDX 2.3 SBOM for each archive with Syft, signs the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| archives, SBOMs, and checksum manifest with keyless Cosign, and creates GitHub SLSA provenance plus | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| one SBOM attestation per platform. The draft becomes public only after every step succeeds. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| one SBOM attestation per platform. It also publishes the tag's multi-architecture hub image by its | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| manifest digest, signs it with keyless Cosign, and creates separate provenance and SPDX SBOM | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| attestations for that digest. The draft becomes public only after every step succeeds. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The workflow follows the primary guidance for [GitHub artifact attestations](https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [GoReleaser reproducible Go builds](https://goreleaser.com/customization/builds/builders/go/#reproducible-builds), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -29,6 +31,45 @@ URLs or hashes. The release workflow signs the formula itself. The tap's own rep | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| verifies that signature and the signed checksum manifest before importing the formula, so the Sith | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| release token never needs cross-repository write access. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Verify a hub OCI image | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Hub images are published only by a signed Sith release tag and must be consumed by immutable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| manifest digest. A release includes a signed `sith_<version>_hub.image` file whose only line is the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| digest address; do not substitute the convenient version tag or add `latest` to a Helm value. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tag=vX.Y.Z # use a tag released after hub-image publication is enabled | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version=${tag#v} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gh release download "$tag" --repo ArdurAI/sith \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --pattern "sith_${version}_hub.image" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --dir "sith-$version" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| image=$(cat "sith-$version/sith_${version}_hub.image") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "$image" in ghcr.io/ardurai/sith-hub@sha256:*) ;; *) exit 1 ;; esac | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Verify the keyless image signature against the exact tag workflow identity, then verify GitHub | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provenance and the SPDX SBOM attestation. These commands require registry access; the later air-gap | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow consumes mirrored, pre-verified material rather than weakening this verification boundary. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| identity="https://github.com/ArdurAI/sith/.github/workflows/release.yml@refs/tags/${tag}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cosign verify \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --certificate-identity "$identity" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$image" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gh attestation verify "oci://$image" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --repo ArdurAI/sith \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --signer-workflow ArdurAI/sith/.github/workflows/release.yml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gh attestation verify "oci://$image" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --repo ArdurAI/sith \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --signer-workflow ArdurAI/sith/.github/workflows/release.yml \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --predicate-type https://spdx.dev/Document/v2.3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The existing Helm chart remains fail-closed: it accepts this digest and names of pre-materialized | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runtime and migration Secrets only. It neither creates secret data nor supplies a KMS provider, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| database, ingress, or mutable image reference. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+34
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win Verify the signed digest evidence before consuming it. The workflow emits Suggested verification gh release download "$tag" --repo ArdurAI/sith \
--pattern "sith_${version}_hub.image" \
+ --pattern "sith_${version}_hub.image.sigstore.json" \
--dir "sith-$version"
image=$(cat "sith-$version/sith_${version}_hub.image")
+cosign verify-blob \
+ --bundle "sith-$version/sith_${version}_hub.image.sigstore.json" \
+ --certificate-identity "https://github.com/ArdurAI/sith/.github/workflows/release.yml@refs/tags/${tag}" \
+ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
+ "sith-$version/sith_${version}_hub.image"
case "$image" in ghcr.io/ardurai/sith-hub@sha256:*) ;; *) exit 1 ;; esac📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Verify a release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Set the release and platform, then download its assets: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -98,14 +139,15 @@ No network is an isolated image-check constraint, not the operational hub policy | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| must allow only narrowly scoped egress to configured runtime dependencies, including the database | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and, where enabled, the pinned OIDC discovery and JWKS endpoints. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| No OCI image is published by this repository yet. Consumers must not infer a mutable image tag | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from a release archive. The [`charts/sith-hub`](../charts/sith-hub) chart accepts only an explicit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| immutable `repository@sha256:...` reference, and its defaults intentionally fail until an operator | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provides that reference and existing Secret names. Image publishing/signing/attestation will be | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| added as a separate release-boundary change before any public deployment guidance. Its fixed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `light` and `heavy` profiles alter only the reviewed resource envelope; both preserve the same | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| digest, Secret-reference, migration, RBAC, and workload-hardening contract. This first F9.3a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| slice is not a claim of the parent feature's future in-chart database, HA, or cloud-KMS topology. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Hub OCI images are published only as a release-boundary artifact, never by a pull request or local | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| build. Consumers must not infer a mutable image tag from a release archive. The | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [`charts/sith-hub`](../charts/sith-hub) chart accepts only an explicit immutable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `repository@sha256:...` reference, and its defaults intentionally fail until an operator provides | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| that reference and existing Secret names. Older releases can lack the hub-image assets; use the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| digest address attached to a release that includes them. Its fixed `light` and `heavy` profiles | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alter only the reviewed resource envelope; both preserve the same digest, Secret-reference, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| migration, RBAC, and workload-hardening contract. This first F9.3a slice is not a claim of the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parent feature's future in-chart database, HA, or cloud-KMS topology. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Maintainer release procedure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -190,6 +232,6 @@ Homebrew token is stored in Sith. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Cost and operational notes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The incremental cost is GitHub-hosted runner time for four cross-builds, two snapshot builds on | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| each PR, Syft scans, and five attestations on a tag. Fulcio and Rekor use Sigstore's public-good | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| each PR, Syft scans, and seven attestations on a tag. Fulcio and Rekor use Sigstore's public-good | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| service for this public repository. Releases create no runtime cloud service, NAT egress path, or | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| persistent signing infrastructure. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,94 @@ | ||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||
|
|
||||||||||||||
| # SPDX-License-Identifier: Apache-2.0 | ||||||||||||||
|
|
||||||||||||||
| set -euo pipefail | ||||||||||||||
|
|
||||||||||||||
| usage() { | ||||||||||||||
| printf 'usage: %s --dist <release-distribution-directory>\n' "${0##*/}" >&2 | ||||||||||||||
| exit 2 | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if [[ "$#" != 2 || "$1" != "--dist" ]]; then | ||||||||||||||
| usage | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| readonly REPOSITORY_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" | ||||||||||||||
| readonly DIST_DIRECTORY="$(cd "$2" && pwd -P)" | ||||||||||||||
|
Comment on lines
+16
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Split Under 🔧 Suggested fix-readonly REPOSITORY_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
-readonly DIST_DIRECTORY="$(cd "$2" && pwd -P)"
+REPOSITORY_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
+readonly REPOSITORY_ROOT
+DIST_DIRECTORY="$(cd "$2" && pwd -P)"
+readonly DIST_DIRECTORY📝 Committable suggestion
Suggested change
🧰 Tools🪛 Shellcheck (0.11.0)[warning] 16-16: Declare and assign separately to avoid masking return values. (SC2155) [warning] 17-17: Declare and assign separately to avoid masking return values. (SC2155) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||
| readonly DOCKER_BIN="${DOCKER_BIN:-docker}" | ||||||||||||||
|
|
||||||||||||||
| command -v "$DOCKER_BIN" >/dev/null | ||||||||||||||
| command -v python3 >/dev/null | ||||||||||||||
|
|
||||||||||||||
| shopt -s nullglob | ||||||||||||||
| amd64_archives=("${DIST_DIRECTORY}"/sith_*_linux_amd64.tar.gz) | ||||||||||||||
| arm64_archives=("${DIST_DIRECTORY}"/sith_*_linux_arm64.tar.gz) | ||||||||||||||
| if [[ "${#amd64_archives[@]}" != 1 || "${#arm64_archives[@]}" != 1 ]]; then | ||||||||||||||
| printf 'expected exactly one Linux archive per supported architecture in %s\n' "$DIST_DIRECTORY" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| context_directory="$(mktemp -d)" | ||||||||||||||
| builder="sith-release-hub-${RANDOM}-$$" | ||||||||||||||
| cleanup() { | ||||||||||||||
| "$DOCKER_BIN" buildx rm --force "$builder" >/dev/null 2>&1 || true | ||||||||||||||
| rm -rf "$context_directory" | ||||||||||||||
| } | ||||||||||||||
| trap cleanup EXIT | ||||||||||||||
| install -d -m 0755 "$context_directory/bin/linux/amd64" "$context_directory/bin/linux/arm64" | ||||||||||||||
| tar -xzf "${amd64_archives[0]}" -C "$context_directory/bin/linux/amd64" sith | ||||||||||||||
| tar -xzf "${arm64_archives[0]}" -C "$context_directory/bin/linux/arm64" sith | ||||||||||||||
| install -m 0644 "$REPOSITORY_ROOT/Containerfile" "$context_directory/Containerfile" | ||||||||||||||
| test -x "$context_directory/bin/linux/amd64/sith" | ||||||||||||||
| test -x "$context_directory/bin/linux/arm64/sith" | ||||||||||||||
|
|
||||||||||||||
| oci_layout="$context_directory/sith-hub.oci" | ||||||||||||||
| "$DOCKER_BIN" buildx create --driver docker-container --name "$builder" >/dev/null | ||||||||||||||
| "$DOCKER_BIN" buildx inspect --builder "$builder" --bootstrap >/dev/null | ||||||||||||||
| "$DOCKER_BIN" buildx build \ | ||||||||||||||
| --builder "$builder" \ | ||||||||||||||
| --platform linux/amd64,linux/arm64 \ | ||||||||||||||
| --provenance=false \ | ||||||||||||||
| --sbom=false \ | ||||||||||||||
| --file "$context_directory/Containerfile" \ | ||||||||||||||
| --output "type=oci,dest=${oci_layout}" \ | ||||||||||||||
| "$context_directory" | ||||||||||||||
|
|
||||||||||||||
| oci_directory="$context_directory/oci-layout" | ||||||||||||||
| install -d -m 0755 "$oci_directory" | ||||||||||||||
| tar -xf "$oci_layout" -C "$oci_directory" | ||||||||||||||
| python3 - "$oci_directory" <<'PY' | ||||||||||||||
| import json | ||||||||||||||
| import sys | ||||||||||||||
| from pathlib import Path | ||||||||||||||
|
|
||||||||||||||
| root = Path(sys.argv[1]) | ||||||||||||||
| index_media_types = { | ||||||||||||||
| "application/vnd.oci.image.index.v1+json", | ||||||||||||||
| "application/vnd.docker.distribution.manifest.list.v2+json", | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| def indexed_platforms(index): | ||||||||||||||
| platforms = set() | ||||||||||||||
| for manifest in index.get("manifests", []): | ||||||||||||||
| if manifest.get("mediaType") in index_media_types: | ||||||||||||||
| algorithm, digest = manifest["digest"].split(":", 1) | ||||||||||||||
| with (root / "blobs" / algorithm / digest).open(encoding="utf-8") as nested_file: | ||||||||||||||
| platforms.update(indexed_platforms(json.load(nested_file))) | ||||||||||||||
| continue | ||||||||||||||
| platform = manifest.get("platform", {}) | ||||||||||||||
| os_name = platform.get("os") | ||||||||||||||
| architecture = platform.get("architecture") | ||||||||||||||
| if os_name is not None and architecture is not None: | ||||||||||||||
| platforms.add((os_name, architecture)) | ||||||||||||||
| return platforms | ||||||||||||||
|
|
||||||||||||||
| with (root / "index.json").open(encoding="utf-8") as index_file: | ||||||||||||||
| platforms = indexed_platforms(json.load(index_file)) | ||||||||||||||
|
|
||||||||||||||
| expected = {("linux", "amd64"), ("linux", "arm64")} | ||||||||||||||
| if platforms != expected: | ||||||||||||||
| raise SystemExit(f"OCI layout platforms = {sorted(platforms)!r}, want {sorted(expected)!r}") | ||||||||||||||
| PY | ||||||||||||||
|
|
||||||||||||||
| printf 'release hub OCI layout verified from release archives\n' | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: ArdurAI/sith
Length of output: 4225
🌐 Web query:
Syft default behavior when analyzing a multi-arch image index with no --platform flag documented default linux/amd64💡 Result:
When analyzing a multi-architecture container image index without an explicitly provided --platform flag, Syft defaults to analyzing the linux/amd64 manifest [1]. While Syft provides a --platform flag to allow users to specify a target architecture (e.g., linux/arm64) [2][3], in the absence of this configuration, the tool automatically targets the linux/amd64 architecture for unspecific image references [1]. Historically, this behavior has been a point of discussion in the community regarding how Syft handles multi-platform images and OCI layouts [4][5][6], but the documented default remains linux/amd64 for multi-arch image indexes [1].
Citations:
application/vnd.oci.image.index.v1+jsonmanifests in root OCI layout anchore/syft#1545🏁 Script executed:
Repository: ArdurAI/sith
Length of output: 38044
🌐 Web query:
Syft analyze multi-platform image index without --platform which manifest is selected default linux/amd64 or current platform💡 Result:
When analyzing a multi-platform container image index without specifying the --platform flag, Syft does not strictly default to linux/amd64. Instead, Syft uses the architecture of the host machine (the environment where the tool is being executed) as the default platform [1][2]. While some older documentation or specific contexts may have referenced linux/amd64, updates to Syft and its underlying library, stereoscope, have aligned the default behavior to match the host architecture [1][2]. If your host machine is running on an arm64 architecture, Syft will attempt to pull the linux/arm64 manifest by default [1]. Key points regarding this behavior: - Host-based selection: Syft detects the host platform and uses that for manifest selection unless explicitly overridden by the --platform flag [1][2]. - Explicit override: To ensure a specific platform is analyzed, you must use the --platform flag (e.g., --platform linux/amd64), which forces Syft to target that specific manifest regardless of the host environment [3][4]. - Limitations: Syft currently analyzes only the single manifest resolved by the platform selection (either the default host-based one or the user-specified one); it does not automatically aggregate dependencies from all manifests within a multi-platform index into a single SBOM [5][6].
Citations:
🌐 Web query:
anchore syft platform flag image index default platform documentation💡 Result:
When scanning container images with Anchore Syft, the --platform flag is used to specify the operating system and architecture of the image to be analyzed [1][2]. Default Behavior: When scanning multi-platform images or image references that do not specify a platform, Syft defaults to targeting the linux/amd64 manifest [1]. Using the --platform Flag: The --platform flag allows you to override this default and target a specific architecture or OS/architecture combination [1][3]. The flag accepts values in formats similar to those used by Docker, such as: - Architecture only: --platform arm64 - OS/Architecture combination: --platform linux/arm64 - Architecture variants: --platform linux/arm/v8 Configuration: You can also set the platform via the configuration file or an environment variable (SYFT_PLATFORM) [2][4]. Important Limitations: Syft currently analyzes a single specific platform's manifest at a time when scanning an image index (or multi-arch manifest list) [5][6]. It is unable to automatically combine multiple architectures into a single unified SBOM in one command [5]. If you need an SBOM that covers all architectures in a multi-platform image, you must perform separate scans for each desired platform and manage the resulting SBOMs accordingly [7].
Citations:
application/vnd.oci.image.index.v1+jsonmanifests in root OCI layout anchore/syft#1545Generate separate SBOMs for each hub platform
syft "${HUB_IMAGE}@${HUB_DIGEST}"resolves and scans only one platform from the multi-arch hub index, but the attestation is published against the index digest itself. That makes the SBOM appear to cover bothlinux/amd64andlinux/arm64when it only describes a single manifest. Generate and attest one SBOM per platform instead, matching the existing per-arch release pattern.🤖 Prompt for AI Agents