MCPcopy Index your code
hub / github.com/ckotzbauer/vulnerability-operator

github.com/ckotzbauer/vulnerability-operator @0.28.16

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.28.16 ↗ · + Follow
88 symbols 234 edges 16 files 2 documented · 2%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

vulnerability-operator

Scans SBOMs and Images for vulnerabilities

test

<img src="https://github.com/ckotzbauer/vulnerability-operator/raw/0.28.16/deploy/grafana-dashboard.png" width="900">

Overview

This operator scans all SBOMs from a git-repository for vulnerabilities using Grype. The result-list can be emitted as JSON-file served via an endpoint and/or as Prometheus metrics. There may be more targets in the future. The scans are done periodically.

Kubernetes Compatibility

The image contains versions of k8s.io/client-go. Kubernetes aims to provide forwards & backwards compatibility of one minor version between client and server:

vulnerability-operator k8s.io/{api,apimachinery,client-go} expected kubernetes compatibility
main v0.30.0 1.29.x, 1.30.x, 1.31.x
0.24.0 v0.30.0 1.29.x, 1.30.x, 1.31.x
0.23.0 v0.29.3 1.28.x, 1.29.x, 1.30.x
0.22.0 v0.28.4 1.27.x, 1.28.x, 1.29.x
0.19.0 v0.27.4 1.26.x, 1.27.x, 1.28.x
0.17.0 v0.26.3 1.25.x, 1.26.x, 1.27.x
0.13.0 v0.25.4 1.24.x, 1.25.x, 1.26.x
0.8.0 v0.24.3 1.23.x, 1.24.x, 1.25.x
0.5.0 v0.23.5 1.22.x, 1.23.x, 1.24.x

However, the operator will work with more versions of Kubernetes in general.

Installation

Manifests

kubectl apply -f deploy/

Helm-Chart

Create a YAML file first with the required configurations or use helm-flags instead.

helm repo add ckotzbauer https://ckotzbauer.github.io/helm-charts
helm install ckotzbauer/vulnerability-operator -f your-values.yaml

Configuration

All parameters are cli-flags.

Parameter Required Default Description
verbosity false info Log-level (debug, info, warn, error, fatal, panic)
cron false @hourly Backround-Service interval (CRON). All options from github.com/robfig/cron are allowed
sources false git Comma-delimited list of sources to gather SBOMs from. Possible source currently only git
targets false json Comma-delimited list of targets to sent vulnerability-data to. Possible targets json, metrics, policyreport
grype-config-file false "" Path to grype-config-file to specify ignore-rules.
filter-config-file false "" Path to filter-config-file to specify ignore- and audit-rules. (yaml formatted)
only-fixed false false Only report CVEs where a fix is available.
min-severity false medium Only report CVEs with a severity greater or equal (negligible, low, medium, high, critical).
git-workingtree false /work Directory to place the git-repo.
git-repository true when git target is used. "" Git-Repository-URL (HTTPS).
git-branch false main Git-Branch to checkout.
git-path false "" Folder-Path inside the Git-Repository.
git-access-token false "" Git-Personal-Access-Token with read-permissions.
git-username false "" Git-Username
git-password false "" Git-Password
github-app-id false "" GitHub App-ID.
github-app-installation-id false "" GitHub App-Installation-ID.
reports-dir false /reports Directory to place the reports.
report-auth-token false "" Bearer-token required to access the /report/ endpoint. Empty disables authentication (directory-listing stays disabled regardless). Set it via the VULN_REPORT_AUTH_TOKEN env-var from a secret.

The flags can be configured as args or as environment-variables prefixed with VULN_ to inject sensitive configs as secret values.

Example Helm-Config

args:
  targets: metrics
  min-severity: low
  git-repository: https://github.com/XXX/XXX
  git-path: dev-cluster/sboms
  verbosity: debug
  cron: "0 0 * * * *"

envVars:
  - name: VULN_GIT_ACCESS_TOKEN
    valueFrom:
      secretKeyRef:
        name: "vulnerability-operator"
        key: "accessToken"

servicemonitor:
  enabled: true

Sources

Git

The contents of this git-repository are typically generated from the sbom-generator. All files named sbom.json, sbom.txt, sbom.xml or sbom.spdx are gathered regarding the git-* config-flags. You can use a token-based authentication (e.g. a PAT for GitHub) with --git-access-token, BasicAuth with username and password (--git-username, --git-password) or Github App Authentication (--github-app-id, --github-app-installation-id, env: VULN_GITHUB_APP_PRIVATE_KEY) The private-key has to be Base64 encoded.

Targets

JSON

All found vulnerabilities can be requested as file from the /report/report.json endpoint (audited ones from /report/audited.json). Only these two files are served; directory-listing is disabled. When report-auth-token is set, the endpoint requires an Authorization: Bearer <token> header. The data is structured like this:

Example JSON

json [ { "ID": "CVE-2019-19924", "Severity": "Medium", "Type": "rpm", "Package": "sqlite", "Installed": "3.7.17-8.el7_7.1", "FixedIn": [], "FixState": "wont-fix", "URLs": [ "https://access.redhat.com/security/cve/CVE-2019-19924" ], "ImageID": "docker.elastic.co/beats/filebeat@sha256:e418d12e08a1b74140c9edc6bdc773110b0f802340e25e2716950bac86ae14ce", "Containers": [ { "PodNamespace": "elastic-system", "PodName": "filebeat-filebeat-6xkf4", "ContainerName": "filebeat" }, { "PodNamespace": "elastic-system", "PodName": "filebeat-filebeat-g6zbh", "ContainerName": "filebeat" }, { "PodNamespace": "elastic-system", "PodName": "filebeat-filebeat-jkgnh", "ContainerName": "filebeat" } ] }, { "ID": "CVE-2020-16250", "Severity": "Critical", "Type": "go-module", "Package": "github.com/hashicorp/vault/api", "Installed": "v1.3.1", "FixedIn": [], "FixState": "unknown", "URLs": [ "https://www.hashicorp.com/blog/category/vault/", "https://github.com/hashicorp/vault/blob/master/CHANGELOG.md#151", "http://packetstormsecurity.com/files/159478/Hashicorp-Vault-AWS-IAM-Integration-Authentication-Bypass.html" ], "ImageID": "ghcr.io/kyverno/kyverno@sha256:4fc715e9287446222bf12b1245899b195ecea8beda54c6f6a3587373c376cad1", "Containers": [ { "PodNamespace": "kyverno", "PodName": "kyverno-555dcf9f66-csmq5", "ContainerName": "kyverno" }, { "PodNamespace": "kyverno", "PodName": "kyverno-555dcf9f66-gsphr", "ContainerName": "kyverno" } ] } ]

Metrics

Every CVE is exported with a Prometheus vuln_operator_cves gauge-metric for each container it appears in.

vuln_operator_cves{container_name="kyverno", cve="CVE-2020-16250", fix_state="unknown", image_id="ghcr.io/kyverno/kyverno@sha256:4fc715e9287446222bf12b1245899b195ecea8beda54c6f6a3587373c376cad1", package="github.com/hashicorp/vault/api", k8s_name="kyverno", k8s_namespace="kyverno", k8s_kind="Deployment", severity="Critical", type="go-module", version="v1.3.1"}

Note: The operator removes all metrics from the vector before re-populating it. In the meanwhile the data is not expressive.

Grafana Dashboard

There's a dashboard for Grafana to view the collected vulnerability metrics.

PolicyReport

With the policyreport target set, the operator stores the scan-results as PolicyReport CRs inside the cluster. Each PolicyReport object is owned by the corresponding pod to enable autocleanup by Kubernetes.

Example PolicyReport

yaml apiVersion: wgpolicyk8s.io/v1alpha2 kind: PolicyReport metadata: creationTimestamp: "2022-06-18T14:57:27Z" generation: 3 labels: kubernetes.io/created-by: vulnerability-operator name: vuln-kyverno-688464bd95-55drc namespace: kyverno ownerReferences: - apiVersion: v1 kind: Pod name: kyverno-688464bd95-55drc uid: 24bdccbb-653a-4005-8463-cf511a919037 resourceVersion: "160903586" uid: e3cd1447-49ef-481d-b44b-cc38239ea870 results: - category: github.com/theupdateframework/go-tuf message: 'github.com/theupdateframework/go-tuf: GHSA-66x3-6cw3-v5gj' policy: GHSA-66x3-6cw3-v5gj properties: FixedVersion: 0.3.0 InstalledVersion: v0.0.0-20220211205608-f0c3294f63b9 URL: https://github.com/advisories/GHSA-66x3-6cw3-v5gj resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 - category: google.golang.org/protobuf message: 'google.golang.org/protobuf: CVE-2015-5237' policy: CVE-2015-5237 properties: FixedVersion: "" InstalledVersion: v1.28.0 URL: https://github.com/google/protobuf/issues/760 resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 - category: google.golang.org/protobuf message: 'google.golang.org/protobuf: CVE-2021-22570' policy: CVE-2021-22570 properties: FixedVersion: "" InstalledVersion: v1.28.0 URL: https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0 resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 - category: google.golang.org/protobuf message: 'google.golang.org/protobuf: CVE-2015-5237' policy: CVE-2015-5237 properties: FixedVersion: "" InstalledVersion: v1.28.0 URL: https://github.com/google/protobuf/issues/760 resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 - category: google.golang.org/protobuf message: 'google.golang.org/protobuf: CVE-2021-22570' policy: CVE-2021-22570 properties: FixedVersion: "" InstalledVersion: v1.28.0 URL: https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0 resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 - category: github.com/theupdateframework/go-tuf message: 'github.com/theupdateframework/go-tuf: GHSA-66x3-6cw3-v5gj' policy: GHSA-66x3-6cw3-v5gj properties: FixedVersion: 0.3.0 InstalledVersion: v0.0.0-20220211205608-f0c3294f63b9 URL: https://github.com/advisories/GHSA-66x3-6cw3-v5gj resources: - kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 result: fail severity: high source: vulnerability-operator timestamp: nanos: 728434599 seconds: 1655564847 scope: kind: Pod name: kyverno-688464bd95-55drc namespace: kyverno uid: 24bdccbb-653a-4005-8463-cf511a919037 summary: error: 0 fail: 6 pass: 0 skip: 0 warn: 0

Context-based vulnerability filtering

You can apply filter rules to either ignore certain vulnerabilities or to move them into a separate metric. This is useful if you want to exclude vulnerabilities from your metric, for example false positives or issues that are outside of the applications execution path.

Filter rules support the following properties: - CVE - package name - container context (with the following subset) - image - namespace - kind - name

Container context properties support glob patterns * and ?, while CVE and package only match its exact value. The container context only applies, if all of its properties are matching (AND condition).

The filter rules are provided through a yaml formatted file. Its path is configured with --filter-config-file.

Example filter configuration

```yaml ignore: # Ignore any vulnerabilities in ruby gem rdoc - package: rdoc # Ignore CVE GHSA-8cr8-4vfw-mr7h - vulnerability: GHSA-8cr8-4vfw-mr7h audit: # If GHSA-fp4w-jxhp-m23p was found in gitlab-ce images, move it the "audit" metric

Extension points exported contracts — how you extend this code

ScanItem (Interface)
(no doc) [2 implementers]
internal/vuln/source/source.go
Source (Interface)
(no doc) [2 implementers]
internal/vuln/source/source.go

Core symbols most depended-on inside this repo

secureReports
called by 4
main.go
matchesContainer
called by 4
internal/vuln/filter/filter.go
getOwnerKindAndName
called by 3
internal/vuln/kubernetes/kubernetes.go
printNextExecution
called by 3
internal/vuln/daemon/daemon.go
New
called by 3
internal/vuln/grype/grype.go
ScanItem
called by 3
internal/vuln/grype/grype.go
IsMatch
called by 2
internal/vuln/util.go
NewClient
called by 2
internal/vuln/kubernetes/kubernetes.go

Shape

Function 35
Method 32
Struct 19
Interface 2

Languages

Go100%

Modules by API surface

internal/vuln/source/source.go16 symbols
internal/vuln/grype/grype.go12 symbols
internal/vuln/kubernetes/kubernetes.go8 symbols
internal/vuln/filter/filter.go8 symbols
internal/vuln/source/git/git_source.go7 symbols
internal/vuln/daemon/daemon.go6 symbols
main_test.go5 symbols
main.go5 symbols
internal/vuln/source/kubernetes/kubernetes_source.go5 symbols
internal/vuln/grype/grype_test.go5 symbols
internal/vuln/filter/type.go3 symbols
internal/vuln/util_test.go2 symbols

For agents

$ claude mcp add vulnerability-operator \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page