Skip to main content

Overview

CPLN Trivy automates vulnerability scanning for every image in your Control Plane image registry. A scheduled daemon queries the registry for unscanned images, runs Trivy against each one, and stores an HTML report in S3 or an Azure File Share. After each scan, the image is tagged with a direct link to its report — visible in the Control Plane console.

Architecture

  • daemon (cron workload) — Runs on a configurable schedule, queries the registry for images that do not yet have a cpln/trivy-scan tag, and orchestrates scanning. Includes a trivy-api sidecar that wraps the Trivy CLI and returns HTML vulnerability reports.
  • web-server (serverless workload) — Receives scan reports from the daemon, stores them in the configured storage backend, and serves them publicly via URL.
After each scan, the daemon writes two tags to the image:
TagValue
cpln/trivy-scanURL to the HTML vulnerability report
cpln/trivy-scan-timeTimestamp of the scan
Only images without an existing cpln/trivy-scan tag are scanned. To re-scan an image, remove that tag first.

What Gets Created

  • Cron Daemon Workload — Trivy daemon with trivy-api sidecar, runs on a cron schedule.
  • Serverless Web-Server Workload — Report storage and serving, autoscales from 1–3 replicas.
  • Identity & Policy — Identity bound to each workload with access to the configured storage cloud account and the service account secret.
  • Secret — Opaque secret storing the service account key used to authenticate Trivy against the Control Plane image registry.
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

Service Account

Trivy authenticates against the Control Plane image registry using a service account key.
1

Create or select a service account

Create a Control Plane service account (or use an existing one) that has read access to images in your org. Set serviceAccountName in values.yaml to its name.
2

Generate a key

Generate a key for the service account and copy the key value.
3

Set the key in values.yaml

Set trivyPassword to the key value. The template stores it as an opaque secret named by trivyPasswordSecretName (default: trivy-password).

Storage

1

Create an S3 bucket

Create an S3 bucket in your AWS account to store scan reports. Set storage.s3.bucket and storage.s3.region.
2

Register a Cloud Account

If you do not have one, create an AWS Cloud Account in Control Plane with AmazonS3FullAccess permissions. Set storage.s3.cloudAccountName to its name.
To install, follow the instructions for your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations
Pulumi Icon Streamline Icon: https://streamlinehq.com

Pulumi

Declare templates in your Pulumi programs

Configuration

The default values.yaml for this template:
# Storage backend for vulnerability reports. Options: "s3" or "azureFileshare"
storage:
  type: s3

  s3:
    cloudAccountName: my-aws-cloud-account
    bucket: trivy-reports-bucket
    region: us-east-1

  azureFileshare:
    cloudAccountName: my-azure-cloud-account
    accountName: mystorageaccount
    fileShare: trivy-reports
    scope: "" # /subscriptions/<id>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<name>

# Bearer token shared between the daemon and web-server. Change before deploying to production.
postToken: changeme

# Service account key used by Trivy to authenticate against the Control Plane image registry
trivyPassword: my-service-account-key
trivyPasswordSecretName: trivy-password

# Control Plane service account that Trivy uses to pull images
serviceAccountName: trivy-service-account

# Cron schedule for the scanning daemon
schedule: "*/59 * * * *"

daemon:
  image: ghcr.io/controlplane-com/cpln-trivy-daemon:1.0.0
  resources:
    cpu: 1
    memory: 1Gi
  firewall:
    outboundAllowCIDR:
      - 0.0.0.0/0

trivyApi:
  image: ghcr.io/controlplane-com/cpln-trivy-trivy-api:1.0.0
  resources:
    cpu: 2
    memory: 4Gi

webServer:
  image: ghcr.io/controlplane-com/cpln-trivy-web-server:1.0.0
  resources:
    cpu: 150m
    memory: 128Mi
  autoscaling:
    minScale: 1
    maxScale: 3
  firewall:
    inboundAllowCIDR:
      - 0.0.0.0/0
    outboundAllowCIDR:
      - 0.0.0.0/0

Configuration Reference

ParameterDefaultDescription
storage.types3Storage backend for reports. Options: s3, azureFileshare
storage.s3.cloudAccountNameAWS Cloud Account name registered in Control Plane
storage.s3.bucketS3 bucket name
storage.s3.regionAWS region (e.g. us-east-1)
storage.azureFileshare.cloudAccountNameAzure Cloud Account name registered in Control Plane
storage.azureFileshare.accountNameAzure storage account name
storage.azureFileshare.fileShareAzure file share name
storage.azureFileshare.scopeFull Azure resource scope for role assignment
postTokenchangemeShared bearer token between daemon and web-server
trivyPasswordService account key for Trivy registry authentication
trivyPasswordSecretNametrivy-passwordName of the Control Plane secret storing the key
serviceAccountNamecpln-trivy-service-accountService account Trivy uses to pull images
schedule*/59 * * * *Cron schedule for the scanning daemon
daemon.resources.cpu1CPU for the daemon container
daemon.resources.memory1GiMemory for the daemon container
trivyApi.resources.cpu2CPU for the trivy-api sidecar
trivyApi.resources.memory4GiMemory for the trivy-api sidecar
webServer.autoscaling.minScale1Minimum web-server replicas
webServer.autoscaling.maxScale3Maximum web-server replicas
Change postToken from its default changeme value before any production deployment. This token authenticates report submissions from the daemon to the web-server.

Viewing Reports

Once the daemon has run, navigate to any scanned image in the Control Plane console. The cpln/trivy-scan tag on the image contains a direct URL to the HTML vulnerability report. Opening that URL serves the report from the web-server. To list all scanned images via CLI:
cpln image query --tag cpln/trivy-scan -o json | jq '.items[].name'

Maintenance

Force a Full Re-Scan

To reset all scan tags and trigger a full re-scan on the next daemon run:
cpln image query --tag cpln/trivy-scan -o json | jq -r '.items[].name' | \
  xargs -I{} cpln image tag {} --remove cpln/trivy-scan --remove cpln/trivy-scan-time

Re-Scan a Single Image

To re-scan one image, remove its scan tags:
cpln image tag my-image:latest --remove cpln/trivy-scan --remove cpln/trivy-scan-time
The daemon will pick it up on its next scheduled run.

External References

Trivy Documentation

Official Trivy vulnerability scanner documentation

Create a Cloud Account

Set up AWS or Azure cloud accounts for storage access