suppline logo

suppline

Self-hosted image intake gateway for Kubernetes

Your cluster runs dozens of third-party images you didn't build — each one a pull from someone else's registry, on someone else's uptime, with a CVE list nobody has reviewed since the day it was deployed. suppline is the gate in front of that.

  1. Mirror
  2. Scan
  3. Gate
  4. Attest
  5. Run

Apache 2.0 · one Go binary · SQLite state · no SaaS dependency · air-gap compatible

Used in production at SocialHub

Used in production

“Before suppline, every third-party image meant another glue script — mirror here, scan there, hope admission catches up. Now we have one gate: our registry, our policy, signed attestations. Clusters only run what passed.”

Platform Engineering SocialHub · maloon GmbH www.socialhub.io

SocialHub runs suppline as the intake gate for third-party images — continuous mirror → Trivy scan → CEL policy → Sigstore attestations, with cluster admission verifying the verdict.

How it works

suppline continuously mirrors upstream images into your registry, scans every digest, evaluates a policy you wrote, and publishes signed attestations. Clusters then pull only from the mirror — and can refuse to run anything without a valid, fresh attestation.

  1. Mirror

    Your suppline.yml sync rules drive regsync, which keeps your registry in step with the upstream repositories you chose.

  2. Scan

    The watcher spots new or changed digests and enqueues them. Trivy produces an SBOM and the vulnerability set.

  3. Gate

    Active VEX exemptions are applied, then your CEL policy decides: passed, failed, or pending.

  4. Attest

    cosign signs SBOM, vulnerability, VEX and SCAI attestations into the registry, right next to the image.

  5. Run

    Your cluster pulls from the mirror, and Kyverno or OPA verifies the attestation before a pod starts.

Unchanged digests are rescanned on an interval, so an image that was clean last month gets re-judged against today's vulnerability data. See the full image lifecycle

Core Features

Continuous Mirroring

Keep third-party images in your own registry with regsync, so upstream outages, rate limits and deleted tags stop breaking deploys.

Scanning & SBOMs

Trivy scans every digest and generates an SBOM. Smart rescanning reacts to digest changes and configurable intervals.

CEL Policy Engine

Express your gate as a CEL expression, with per-repository overrides and an optional hold on images that are too freshly released to trust.

Expiring VEX Exemptions

Exempt a CVE with a state, justification and an expiry date, so accepted risks resurface for review instead of living forever.

Sigstore Attestations

cosign signs SBOM, vulnerability, VEX and SCAI attestations with your own key — and suppline generates the matching Kyverno policy for you.

Runtime Awareness

An optional cluster agent reports which images are actually running, so you can tell a backlog item from a live incident.

REST API & Dashboard

Query scans, vulnerabilities, repositories and VEX state, trigger rescans, or re-evaluate policy — from the UI or straight over HTTP.

Auditable History

SQLite keeps every scan, verdict and exemption, so you can show what was known about an image at the moment it was admitted.

Observability

Prometheus metrics, structured JSON logs and component health checks, including how many failing images are live in your clusters.

Air-Gap Compatible

No external service is required at runtime. Mirror once, then scan, gate and attest entirely inside an isolated network.

Why Run an Intake Gateway?

Availability you control

Clusters pull from your registry, not from a vendor's. An upstream outage or a rate limit is no longer your outage.

Every image reviewed, continuously

Not once at onboarding. Digests are rescanned on an interval, and new upstream tags enter the same gate automatically.

Policy as code

A CEL expression in version control beats a wiki page. Exemptions carry a justification and an expiry date.

A verdict that holds

Admission control verifies a signed attestation, so the gate keeps working even when suppline itself is down.

Audit answers on hand

Which images fail policy, which of those are running in production, and what was known at the time — all in your own database.

Air-gap and egress friendly

Mirror once and deploy into isolated networks, while cutting repeated egress traffic to public registries.

Dashboard Preview

Architecture

suppline architecture diagram: regsync mirrors remote registries into a local registry, the watcher and queue feed a worker pipeline that scans with Trivy, evaluates CEL policy and signs cosign attestations back into the registry, results are persisted in SQLite and exposed through the API, dashboard and metrics, while Kubernetes pulls verified images and an optional cluster agent reports what is actually running

Pipeline Components

  • Mirror: regsync syncs the source and target pairs defined in suppline.yml into your registry
  • Watcher: polls the local registry and decides what needs scanning from digest, scan history and rescan interval
  • Queue: holds scan tasks, deduplicated by digest
  • Scanner: Trivy produces the SBOM and vulnerability set for each digest
  • Policy Engine: applies active VEX exemptions, then evaluates your CEL expression
  • Attestor: cosign signs SBOM, vulnerability, VEX and SCAI attestations into the registry
  • State Store: SQLite keeps scan history, verdicts and runtime usage
  • Interfaces: REST API with Swagger, web dashboard, Prometheus metrics and health checks
  • Admission: Kyverno or OPA verifies the SCAI attestation in your cluster, using a policy suppline generates

One Go binary runs the watcher, queue, workers and API. The only required companions are a Trivy server and your registry.

Policy as Code

Mirroring rules and security policy live in one file, so what you mirror and what you allow are reviewed together. Vulnerability counts exclude anything an active VEX statement exempts.

Gate images in suppline.yml

defaults:
  x-rescanInterval: 7d
  x-policy:
    expression: "criticalCount == 0"
    failureMessage: "critical vulnerabilities found"

sync:
  - source: nginx
    target: myregistry.com/nginx
    type: repository
    x-policy:
      expression: "criticalCount == 0 && highCount <= 5"
      minimumReleaseAge: "72h"
    x-vex:
      - id: CVE-2024-56171
        state: not_affected
        justification: vulnerable_code_not_present
        detail: "Not reachable in our configuration"
        expires_at: 2026-12-31T23:59:59Z

minimumReleaseAge holds brand-new images as pending until they have been public long enough to trust — useful when an upstream release is compromised and pulled within hours.

Enforce the verdict in your cluster

curl -s localhost:8080/api/v1/integration/kyverno/policy \
  > suppline-policy.yaml

kubectl apply -f suppline-policy.yaml

The generated ClusterPolicy admits a pod only when the SCAI attestation is signed by your key, reports a passing scan status, and has not expired — a stale verdict fails closed. It ships in Audit mode so you can watch before you block.

Only block what you can act on

expression: |
  vulnerabilities.filter(v,
    v.severity == "CRITICAL" &&
    v.fixedVersion != "" &&
    !v.exempted
  ).size() == 0

Available variables include criticalCount, highCount, mediumCount, lowCount, exemptedCount, vulnerabilities and imageRef.

Try it in one afternoon

No credentials required. Bundled throwaway registry, demo pass + fail policies, and auto-generated cosign keys. Watch one image pass (with attestations) and one fail.

  1. Clone and start

    First boot pulls images and Trivy’s DB — give it a few minutes.

    git clone https://github.com/daimoniac/suppline.git && cd suppline
    docker compose up --build -d
  2. Open the UI

    Go to http://localhost:3000 and log in with API key demo.

  3. Confirm the gate

    Wait until repositories demo-pass and demo-fail appear. demo-pass should be policy-passed with attestations; demo-fail should be blocked.

    curl -s http://localhost:8081/health
    curl -s -H "Authorization: Bearer demo" \
      http://localhost:8080/api/v1/scans | head

Full checklist (semver, VEX, attestation gate POC): Eval quick start . Production installs use Helm with your own registry — REGISTRY.md .

Full eval checklist