Skip to content

Supply-Chain Security

Every KubeManta container image published to ghcr.io/kubemanta is cryptographically signed and ships with a Software Bill of Materials (SBOM), so you can verify — before you run it — that an image was built by our CI from our source and has not been tampered with.

Signing is keyless (Sigstore): there are no long-lived private keys to steal. Each signature is bound to the GitHub Actions OIDC identity that produced it (issued by Fulcio, logged in the Rekor public transparency log).


What is signed

Image Registry
Agent ghcr.io/kubemanta/kubemanta-agent
UI ghcr.io/kubemanta/kubemanta-ui

Both are signed by digest immediately after they are pushed, on both the staging (push to main) and production (semver tag v*.*.*) paths. An SPDX-JSON SBOM is generated per image and attached as a cosign attestation, and also published as a CI workflow artifact (90-day retention).


Verifying a signature

You need cosign (v2+).

KubeManta images are signed by this workflow identity:

Field Value
OIDC issuer https://token.actions.githubusercontent.com
Certificate identity https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/tags/<TAG> (prod) or …@refs/heads/main (staging)

Production release (semver tag)

Pin to the exact release tag you are deploying:

cosign verify \
  --certificate-identity "https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/tags/v0.12.0" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/kubemanta/kubemanta-agent:0.12.0

cosign verify \
  --certificate-identity "https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/tags/v0.12.0" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/kubemanta/kubemanta-ui:0.12.0

A successful verification prints the signed payload (with the certificate subject and Rekor transparency-log entry) and exits 0.

Any release (regex identity)

If you don't want to hard-code the tag, match any signature produced by our ci.yml workflow:

cosign verify \
  --certificate-identity-regexp "^https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/(heads/main|tags/v.*)$" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/kubemanta/kubemanta-agent:latest

Always verify the digest you actually deploy. Tags are mutable; a digest (@sha256:…) is not. cosign verify resolves the tag to its digest and checks the signature on that digest.


Verifying the SBOM attestation

The SBOM is stored as an in-toto attestation (predicate type spdxjson) signed by the same identity:

cosign verify-attestation \
  --type spdxjson \
  --certificate-identity-regexp "^https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/(heads/main|tags/v.*)$" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/kubemanta/kubemanta-agent:0.12.0

To extract the SBOM document itself (e.g. to feed it to a vulnerability scanner):

cosign download attestation \
  --predicate-type https://spdx.dev/Document \
  ghcr.io/kubemanta/kubemanta-agent:0.12.0 \
  | jq -r '.payload | @base64d | fromjson | .predicate' > agent-sbom.spdx.json

The SBOM is also downloadable from the Artifacts section of the corresponding CI run (agent-sbom-spdx / ui-sbom-spdx).


Hardened images

KubeManta images are built and hardened by our CI. Combined with signature verification and the SBOM above, you can confirm an image came from our pipeline and inspect exactly what it contains before you run it.


License-as-pull private registry

KubeManta images are served from a license-gated OCI registry (registry.kubemanta.com). Your license key is the registry password — the Helm chart auto-creates the pull secret (username license, password = your key). There is no separate registry credential to manage or leak.

Pull authorization is delegated to an auth-proxy that validates the license against the licensing service and mints a short-lived, pull-scoped token; it is deny-by-default on any error and never logs license keys. Both Free and Pro/Enterprise licenses can pull — runtime feature gating (in-cluster) separates the tiers.

helm install kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
  --version 1.0.0 \
  -n kubemanta-system --create-namespace \
  --set license.key=YOUR_KEY

For internal/dev clusters that don't use license-as-pull, override image.repository / ui.image.repository and supply a GHCR global.pullToken instead.


Enforcing signatures in-cluster (optional)

You can require a valid KubeManta signature before any KubeManta image is admitted, using a policy controller such as Sigstore Policy Controller or Kyverno. Point the policy at the same issuer + identity regexp shown above.


Notes & scope

  • Keyless / no key custody. Signatures use ephemeral Fulcio certificates tied to the GitHub OIDC identity; there is no private key for an attacker to exfiltrate, and every signature is recorded in the Rekor public transparency log.
  • Build provenance. Image build provenance and a build-time SBOM are additionally embedded by BuildKit (provenance: true / sbom: true). Standalone SLSA provenance attestation via cosign attest is a tracked follow-up.
  • Helm chart signing (oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta) is not yet covered and is a follow-up.