Supply-Chain Security¶
Every KubeManta release image is cryptographically signed and ships with a Software Bill of Materials (SBOM).
Signature verification is not yet available to customers
Images are signed in our build registry, which is private. The commands
on this page therefore require credentials you do not have, and will fail
with 403 if you run them today. We are working on exposing verification
through registry.kubemanta.com, the registry you actually pull from.
Until then, the control you can use is digest pinning — see Pin the exact image you deploy below. A digest is immutable, so pinning one guarantees you run the exact bytes you reviewed, whether or not you can check a signature.
The commands below are documented so you can see what we sign and how, and so they are ready the moment verification is reachable.
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 on the production path (a semver tag v*.*.*), which is the only path that produces a release. An SPDX-JSON SBOM is generated per image and attached as a cosign attestation.
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> |
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/tags/v" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/kubemanta/kubemanta-agent:1.2.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 verifyresolves 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/tags/v" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/kubemanta/kubemanta-agent:1.2.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 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. Pinning the digest is the strongest control available to you today, and it does not depend on signature verification:
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 docker login registry.kubemanta.com -u license:
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 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 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:
Always pin it. An unpinned install resolves to whatever stable points at
today, which is not necessarily the release you tested against.
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. SLSA build provenance is a tracked follow-up; 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 yet covered and is a follow-up.