> ## Documentation Index
> Fetch the complete documentation index at: https://docs.odigos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Verifying Odigos Images

All Odigos container images are signed at build time with [Sigstore cosign](https://docs.sigstore.dev/)
(keyless), and each carries a CycloneDX SBOM attestation. Signatures are stored in the
registry next to the image and recorded in the public
[Rekor transparency log](https://search.sigstore.dev/), so you can verify that any image
you pull was published by the Odigos release pipeline — no keys involved.

## Verify an image

Verification needs [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) v3+.
Always verify by digest:

<Note>
  Verify against the canonical registry, `us-central1-docker.pkg.dev/odigos-cloud/components`.
  `registry.odigos.io` is a pull alias: images resolve through it, but signature
  discovery for retroactively signed versions does not currently surface there.
</Note>

```bash theme={null}
IMG=us-central1-docker.pkg.dev/odigos-cloud/components/odigos-odiglet
DIGEST=$(docker buildx imagetools inspect "${IMG}:<version>" --format '{{.Manifest.Digest}}')

cosign verify \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github\.com/odigos-io/(odigos/\.github/workflows/publish-modules\.yml@refs/tags/v.*|ci-core/\.github/workflows/backfill-sign\.yml@refs/heads/main)$' \
  "${IMG}@${DIGEST}"
```

The identity accepts two workflows on purpose: new releases are signed by the
release pipeline, while versions published before signing went live were signed
retroactively by the audited backfill workflow. A single-identity pattern would
fail on one era or the other.

To verify and inspect the attached SBOM (same identity rules):

```bash theme={null}
cosign verify-attestation --type cyclonedx \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github\.com/odigos-io/(odigos/\.github/workflows/publish-modules\.yml@refs/tags/v.*|ci-core/\.github/workflows/backfill-sign\.yml@refs/heads/main)$' \
  "${IMG}@${DIGEST}" | jq -r .payload | base64 -d | jq '.predicate.components'
```

The SBOM attestation is attached to the **multi-arch index digest** — always pass
the digest from `imagetools inspect` as above, not a per-platform child digest
(children carry signatures but no attestation).

<Accordion title="Full worked example: verifying odigos-scheduler v1.35.0">
  Run as-is — no placeholders to fill in:

  ```bash theme={null}
  IMG=us-central1-docker.pkg.dev/odigos-cloud/components/odigos-scheduler
  TAG=v1.35.0
  DIGEST=$(docker buildx imagetools inspect "${IMG}:${TAG}" --format '{{.Manifest.Digest}}')
  IDENTITY='^https://github\.com/odigos-io/(odigos/\.github/workflows/publish-modules\.yml@refs/tags/v.*|ci-core/\.github/workflows/backfill-sign\.yml@refs/heads/main)$'

  cosign verify \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity-regexp "$IDENTITY" \
    "${IMG}@${DIGEST}"

  cosign verify-attestation --type cyclonedx \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity-regexp "$IDENTITY" \
    "${IMG}@${DIGEST}" | jq -r .payload | base64 -d | jq '.predicate.components | length'
  ```

  Expected output (trimmed):

  ```text theme={null}
  Verification for us-central1-docker.pkg.dev/odigos-cloud/components/odigos-scheduler@sha256:f46fa614… --
  The following checks were performed on each of these signatures:
    - The cosign claims were validated
    - Existence of the claims in the transparency log was verified offline
    - The code-signing certificate was verified using trusted certificate authority certificates
  [{"critical":{"identity":{"docker-reference":"…/odigos-scheduler"},
    "image":{"docker-manifest-digest":"sha256:f46fa614…"},"type":"cosign container image signature"}, …}]

  1022
  ```

  The 1022 components are the SBOM contents — inspect them with
  `jq '.predicate.components'` instead of `length`, e.g. the first entries here are
  `base-files 13.8+deb13u6` and `github.com/argoproj/argo-rollouts v1.9.1`. Because
  v1.35.0 predates release-time signing, the certificate for this version names the
  audited backfill workflow (`ci-core/.github/workflows/backfill-sign.yml`) — that is
  the expected identity for retroactively signed history, and the reason the identity
  regexp accepts both workflows.
</Accordion>

## Signing identities

Each artifact is signed by its own release workflow — never verify with a broad
pattern like `.*odigos-io.*`. The canonical list of identities and the version each
artifact is signed from lives in
[`SIGNING.md`](https://github.com/odigos-io/ci-core/blob/main/SIGNING.md).

| Artifact                                  | Release identity (regexp)                                                                                                      |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Component images (`odigos-*`)             | `^https://github\.com/odigos-io/odigos/\.github/workflows/publish-modules\.yml@refs/tags/v.*$`                                 |
| CLI image + `odigos-victoria-metrics`     | `^https://github\.com/odigos-io/odigos/\.github/workflows/release\.yml@refs/heads/main$`                                       |
| Enterprise images (`odigos-enterprise-*`) | `^https://github\.com/odigos-io/odigos-enterprise/\.github/workflows/release-images\.yml@refs/(tags/.*\|heads/.*)$`            |
| `wasp-init`                               | `^https://github\.com/odigos-io/ebpf-core/\.github/workflows/build-sender\.yml@refs/(heads/main\|heads/releases/.*\|tags/.*)$` |
| `odigos-cli-offsets`                      | `^https://github\.com/odigos-io/enterprise-go-instrumentation/\.github/workflows/offsets-push\.yml@refs/heads/.*$`             |
| `odigos-vmagent-instrumentations`         | `^https://github\.com/odigos-io/vm-agent/\.github/workflows/publish-agents\.yml@refs/(heads/.*\|tags/agents/.*)$`              |

To also cover retroactively signed history, combine the release identity with the
backfill identity in one pattern, as the commands above do:
`^https://github\.com/odigos-io/(<release workflow path>@<ref>|ci-core/\.github/workflows/backfill-sign\.yml@refs/heads/main)$`

Two more certificate details are expected and legitimate:

* **Backfill**: historical releases were signed retroactively by
  `odigos-io/ci-core/.github/workflows/backfill-sign.yml` — the certificate honestly
  records the backfill identity and date, and it is auditable in Rekor.
* **Stable `x.y.0` tags** verify against the release-candidate tag identity: the stable
  tag is a retag of the exact RC digest, so the certificate names the RC that built it.

## Attestable images

Every image below is signed and carries a CycloneDX SBOM attestation, from the
version listed in [`SIGNING.md`](https://github.com/odigos-io/ci-core/blob/main/SIGNING.md):

* **Odigos platform**: `odigos-autoscaler`, `odigos-scheduler`, `odigos-instrumentor`,
  `odigos-collector`, `odigos-odiglet`, `odigos-ui`, `odigos-operator`, `odigos-agents`,
  `odigos-cli`, `odigos-victoria-metrics`
* **Odigos Enterprise**: `odigos-enterprise-odiglet`, `odigos-enterprise-instrumentor`,
  `odigos-enterprise-ui`, `odigos-enterprise-collector`, `odigos-enterprise-central-proxy`,
  `odigos-enterprise-central-backend`, `odigos-enterprise-central-ui`, `odigos-enterprise-agents`,
  `odigos-enterprise-connector-runtime`, `odigos-enterprise-connector-aws`,
  `odigos-enterprise-connector-azure`, `odigos-enterprise-connector-gcp` — `odiglet`
  and `agents` also publish `-extended` variants (separate digests, same identity)
* **Supporting images**: `wasp-init`, `odigos-cli-offsets`, and
  `odigos-vmagent-instrumentations` (signed for publishes after 2026-08-12)

## Air-gapped verification

The Rekor proof travels inside the signature bundle, so verification works offline:
supply `--trusted-root` with a Sigstore trusted-root file instead of relying on
`--offline` (removed in cosign 3.x).
