Skip to content

Supply-Chain Security

Every KubeManta release image is cryptographically signed and ships with a Software Bill of Materials (SBOM). The signatures and SBOMs are served by registry.kubemanta.com next to the images, so you verify them from the same registry you install from, with the same licence login.

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


What is signed

Image Registry
Agent registry.kubemanta.com/kubemanta/kubemanta-agent
UI registry.kubemanta.com/kubemanta/kubemanta-ui

Both are signed by digest when a release is tagged (vX.Y.Z), which is the only path that produces a release. An SPDX-JSON SBOM is generated per image and attached as a signed cosign attestation.


Verifying a signature

You need cosign 2.x, and a login to registry.kubemanta.com. cosign reads Docker's credential store, so log in with docker (a helm registry login alone is not enough):

echo 'YOUR_LICENSE_KEY' | docker login registry.kubemanta.com \
  --username license --password-stdin

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/v<VERSION>

One release (exact identity)

Pin the identity to the release you are deploying. The examples use 1.5.0; replace both the tag and the image version with the release you run:

cosign verify \
  --certificate-identity "https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/tags/v1.5.0" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  registry.kubemanta.com/kubemanta/kubemanta-agent:1.5.0

cosign verify \
  --certificate-identity "https://github.com/kubemanta/kubemanta/.github/workflows/ci.yml@refs/tags/v1.5.0" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  registry.kubemanta.com/kubemanta/kubemanta-ui:1.5.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 the release workflow:

cosign verify \
  --certificate-identity-regexp '^https://github.com/kubemanta/kubemanta/\.github/workflows/ci\.yml@refs/tags/v' \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  registry.kubemanta.com/kubemanta/kubemanta-agent:1.5.0

Keep the identity pattern anchored to .../ci.yml@refs/tags/v. A looser pattern such as ^https://github.com/kubemanta/ would accept a signature from any workflow in the organisation, which is not the guarantee you want.

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 — or pass registry.kubemanta.com/kubemanta/kubemanta-agent@sha256:… directly.

On an air-gapped network, verify the mirrored copy with cosign verify --offline; see Air-gapped install.


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/tags/v' \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  registry.kubemanta.com/kubemanta/kubemanta-agent:1.5.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 \
  registry.kubemanta.com/kubemanta/kubemanta-agent:1.5.0 \
  | jq -r '.payload | @base64d | fromjson | .predicate' > agent-sbom.spdx.json

The SBOM travels with the image as an attestation, which is where to read it from.


Pin the exact image you deploy

Tags are mutable; a digest is not. Pin the digest you verified, so what runs is exactly what you checked:

helm upgrade --install kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
  --version CHART_VERSION -n kubemanta-system --create-namespace \
  --set license.key=YOUR_KEY \
  --set image.digest=sha256:… \
  --set ui.image.digest=sha256:…

Read the digest for the release you are deploying with any OCI client — for example, after the docker login above:

crane digest registry.kubemanta.com/kubemanta/kubemanta-agent:1.5.0
crane digest registry.kubemanta.com/kubemanta/kubemanta-ui:1.5.0

When a digest is set the chart renders repository@sha256:… and drops the tag entirely, so what runs cannot change under a re-pointed tag.


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 release pipeline and inspect exactly what it contains before you run it.

Both images carry the inventory of the third-party components they ship, with their licences, at /licenses/THIRD_PARTY_LICENSES.md.


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 CHART_VERSION \
  -n kubemanta-system --create-namespace \
  --set license.key=YOUR_KEY

Which version?

Replace CHART_VERSION with the release you are installing. The newest is at the top of the Changelog, or read it from the registry once you are logged in:

helm show chart oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta | grep '^version:'

Always pin it. An unpinned install resolves to whatever stable points at today, which is not necessarily the release you tested against.


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, and give it the registry pull secret so it can read the signatures from registry.kubemanta.com.


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. SLSA build provenance is not published today; the guarantees are the signature and the SBOM attestation described above.
  • Helm chart signing (oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta) is not covered: the chart itself is not signed.