{"id":13717709,"url":"https://github.com/ckotzbauer/vulnerability-operator","last_synced_at":"2025-04-06T21:15:06.945Z","repository":{"id":37004937,"uuid":"454686393","full_name":"ckotzbauer/vulnerability-operator","owner":"ckotzbauer","description":"Scans SBOMs for vulnerabilities with Grype","archived":false,"fork":false,"pushed_at":"2024-10-11T22:26:21.000Z","size":1763,"stargazers_count":79,"open_issues_count":13,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-16T08:16:51.451Z","etag":null,"topics":["cve","grype","kubernetes","policyreport","sbom","security","vulnerabilities"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckotzbauer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-02T07:52:40.000Z","updated_at":"2024-09-08T08:45:39.000Z","dependencies_parsed_at":"2023-10-15T02:13:56.710Z","dependency_job_id":"5dcd8b90-f6de-4146-8cc7-86d4faffaa08","html_url":"https://github.com/ckotzbauer/vulnerability-operator","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckotzbauer%2Fvulnerability-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckotzbauer%2Fvulnerability-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckotzbauer%2Fvulnerability-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckotzbauer%2Fvulnerability-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckotzbauer","download_url":"https://codeload.github.com/ckotzbauer/vulnerability-operator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247550690,"owners_count":20956987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cve","grype","kubernetes","policyreport","sbom","security","vulnerabilities"],"created_at":"2024-08-03T00:01:25.922Z","updated_at":"2025-04-06T21:15:06.897Z","avatar_url":"https://github.com/ckotzbauer.png","language":"Go","funding_links":[],"categories":["Point-of-use validations"],"sub_categories":["Vulnerability information exchange"],"readme":"\n# vulnerability-operator\n\n\u003e Scans SBOMs and Images for vulnerabilities\n\n[![test](https://github.com/ckotzbauer/vulnerability-operator/actions/workflows/test.yml/badge.svg)](https://github.com/ckotzbauer/vulnerability-operator/actions/workflows/test.yml)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./deploy/grafana-dashboard.png\" width=\"900\"\u003e\n\u003c/p\u003e\n\n## Overview\n\nThis 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\nmetrics. There may be more targets in the future. The scans are done periodically.\n\n\n## Kubernetes Compatibility\n\nThe image contains versions of `k8s.io/client-go`. Kubernetes aims to provide forwards \u0026 backwards compatibility of one minor version between client and server:\n\n| vulnerability-operator   | k8s.io/{api,apimachinery,client-go} | expected kubernetes compatibility |\n|--------------------------|-------------------------------------|-----------------------------------|\n| main                     | v0.30.0                             | 1.29.x, 1.30.x, 1.31.x            |\n| 0.24.0                   | v0.30.0                             | 1.29.x, 1.30.x, 1.31.x            |\n| 0.23.0                   | v0.29.3                             | 1.28.x, 1.29.x, 1.30.x            |\n| 0.22.0                   | v0.28.4                             | 1.27.x, 1.28.x, 1.29.x            |\n| 0.19.0                   | v0.27.4                             | 1.26.x, 1.27.x, 1.28.x            |\n| 0.17.0                   | v0.26.3                             | 1.25.x, 1.26.x, 1.27.x            |\n| 0.13.0                   | v0.25.4                             | 1.24.x, 1.25.x, 1.26.x            |\n| 0.8.0                    | v0.24.3                             | 1.23.x, 1.24.x, 1.25.x            |\n| 0.5.0                    | v0.23.5                             | 1.22.x, 1.23.x, 1.24.x            |\n\n\nHowever, the operator will work with more versions of Kubernetes in general.\n\n\n## Installation\n\n#### Manifests\n\n```\nkubectl apply -f deploy/\n```\n\n#### Helm-Chart\n\nCreate a YAML file first with the required configurations or use helm-flags instead.\n\n```\nhelm repo add ckotzbauer https://ckotzbauer.github.io/helm-charts\nhelm install ckotzbauer/vulnerability-operator -f your-values.yaml\n```\n\n## Configuration\n\nAll parameters are cli-flags.\n\n| Parameter | Required | Default | Description |\n|-----------|----------|---------|-------------|\n| `verbosity` | `false` | `info` | Log-level (debug, info, warn, error, fatal, panic) |\n| `cron` | `false` | `@hourly` | Backround-Service interval (CRON). All options from [github.com/robfig/cron](https://github.com/robfig/cron) are allowed |\n| `sources` | `false` | `git` | Comma-delimited list of sources to gather SBOMs from. Possible source currently only `git` |\n| `targets` | `false` | `json` | Comma-delimited list of targets to sent vulnerability-data to. Possible targets `json`, `metrics`, `policyreport` |\n| `grype-config-file` | `false` | `\"\"` | Path to grype-config-file to specify ignore-rules. |\n| `filter-config-file` | `false` | `\"\"` | Path to filter-config-file to specify ignore- and audit-rules. (yaml formatted) |\n| `only-fixed` | `false` | `false` | Only report CVEs where a fix is available. |\n| `min-severity` | `false` | `medium` | Only report CVEs with a severity greater or equal (negligible, low, medium, high, critical). |\n| `git-workingtree` | `false` | `/work` | Directory to place the git-repo. |\n| `git-repository` | `true` when `git` target is used. | `\"\"` | Git-Repository-URL (HTTPS). |\n| `git-branch` | `false` | `main` | Git-Branch to checkout. |\n| `git-path` | `false` | `\"\"` | Folder-Path inside the Git-Repository. |\n| `git-access-token` | `false` | `\"\"` | Git-Personal-Access-Token with read-permissions. |\n| `git-username` | `false` | `\"\"` | Git-Username |\n| `git-password` | `false` | `\"\"` | Git-Password |\n| `github-app-id` | `false` | `\"\"` | GitHub App-ID. |\n| `github-app-installation-id` | `false` | `\"\"` | GitHub App-Installation-ID. |\n| `reports-dir` | `false` | `/reports` | Directory to place the reports. |\n\n\nThe flags can be configured as args or as environment-variables prefixed with `VULN_` to inject sensitive configs as secret values.\n\n#### Example Helm-Config\n\n```yaml\nargs:\n  targets: metrics\n  min-severity: low\n  git-repository: https://github.com/XXX/XXX\n  git-path: dev-cluster/sboms\n  verbosity: debug\n  cron: \"0 0 * * * *\"\n\nenvVars:\n  - name: VULN_GIT_ACCESS_TOKEN\n    valueFrom:\n      secretKeyRef:\n        name: \"vulnerability-operator\"\n        key: \"accessToken\"\n\nservicemonitor:\n  enabled: true\n```\n\n## Sources\n\n#### Git\n\nThe contents of this git-repository are typically generated from the [sbom-generator](https://github.com/ckotzbauer/sbom-operator). \nAll files named `sbom.json`, `sbom.txt`, `sbom.xml` or `sbom.spdx` are gathered regarding the `git-*` config-flags.\nYou 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\nGithub App Authentication (`--github-app-id`, `--github-app-installation-id`, env: `VULN_GITHUB_APP_PRIVATE_KEY`) The private-key has to be Base64 encoded. \n\n\n## Targets\n\n#### JSON\n\nAll found vulnerabilities can be requested as file from the `/reports/report.json` endpoint. The data is structured like this:\n\u003cdetails\u003e\n  \u003csummary\u003eExample JSON\u003c/summary\u003e\n\n  ```json\n  [\n    {\n      \"ID\": \"CVE-2019-19924\",\n      \"Severity\": \"Medium\",\n      \"Type\": \"rpm\",\n      \"Package\": \"sqlite\",\n      \"Installed\": \"3.7.17-8.el7_7.1\",\n      \"FixedIn\": [],\n      \"FixState\": \"wont-fix\",\n      \"URLs\": [\n        \"https://access.redhat.com/security/cve/CVE-2019-19924\"\n      ],\n      \"ImageID\": \"docker.elastic.co/beats/filebeat@sha256:e418d12e08a1b74140c9edc6bdc773110b0f802340e25e2716950bac86ae14ce\",\n      \"Containers\": [\n        {\n          \"PodNamespace\": \"elastic-system\",\n          \"PodName\": \"filebeat-filebeat-6xkf4\",\n          \"ContainerName\": \"filebeat\"\n        },\n        {\n          \"PodNamespace\": \"elastic-system\",\n          \"PodName\": \"filebeat-filebeat-g6zbh\",\n          \"ContainerName\": \"filebeat\"\n        },\n        {\n          \"PodNamespace\": \"elastic-system\",\n          \"PodName\": \"filebeat-filebeat-jkgnh\",\n          \"ContainerName\": \"filebeat\"\n        }\n      ]\n    },\n    {\n      \"ID\": \"CVE-2020-16250\",\n      \"Severity\": \"Critical\",\n      \"Type\": \"go-module\",\n      \"Package\": \"github.com/hashicorp/vault/api\",\n      \"Installed\": \"v1.3.1\",\n      \"FixedIn\": [],\n      \"FixState\": \"unknown\",\n      \"URLs\": [\n        \"https://www.hashicorp.com/blog/category/vault/\",\n        \"https://github.com/hashicorp/vault/blob/master/CHANGELOG.md#151\",\n        \"http://packetstormsecurity.com/files/159478/Hashicorp-Vault-AWS-IAM-Integration-Authentication-Bypass.html\"\n      ],\n      \"ImageID\": \"ghcr.io/kyverno/kyverno@sha256:4fc715e9287446222bf12b1245899b195ecea8beda54c6f6a3587373c376cad1\",\n      \"Containers\": [\n        {\n          \"PodNamespace\": \"kyverno\",\n          \"PodName\": \"kyverno-555dcf9f66-csmq5\",\n          \"ContainerName\": \"kyverno\"\n        },\n        {\n          \"PodNamespace\": \"kyverno\",\n          \"PodName\": \"kyverno-555dcf9f66-gsphr\",\n          \"ContainerName\": \"kyverno\"\n        }\n      ]\n    }\n  ]\n  ```\n\u003c/details\u003e\n\n\n#### Metrics\n\nEvery CVE is exported with a Prometheus `vuln_operator_cves` gauge-metric for each container it appears in.\n\n```\nvuln_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\"}\n```\n\n**Note**: The operator removes all metrics from the vector before re-populating it. In the meanwhile the data is not expressive.\n\n\n#### Grafana Dashboard\n\nThere's a [dashboard](./deploy/grafana-dashboard.json) for Grafana to view the collected vulnerability metrics.\n\n\n#### PolicyReport\n\nWith the `policyreport` target set, the operator stores the scan-results as `PolicyReport` CRs inside the cluster. Each `PolicyReport` object\nis owned by the corresponding pod to enable autocleanup by Kubernetes.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExample PolicyReport\u003c/summary\u003e\n  \n  ```yaml\n  apiVersion: wgpolicyk8s.io/v1alpha2\n  kind: PolicyReport\n  metadata:\n    creationTimestamp: \"2022-06-18T14:57:27Z\"\n    generation: 3\n    labels:\n      kubernetes.io/created-by: vulnerability-operator\n    name: vuln-kyverno-688464bd95-55drc\n    namespace: kyverno\n    ownerReferences:\n    - apiVersion: v1\n      kind: Pod\n      name: kyverno-688464bd95-55drc\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    resourceVersion: \"160903586\"\n    uid: e3cd1447-49ef-481d-b44b-cc38239ea870\n  results:\n  - category: github.com/theupdateframework/go-tuf\n    message: 'github.com/theupdateframework/go-tuf: GHSA-66x3-6cw3-v5gj'\n    policy: GHSA-66x3-6cw3-v5gj\n    properties:\n      FixedVersion: 0.3.0\n      InstalledVersion: v0.0.0-20220211205608-f0c3294f63b9\n      URL: https://github.com/advisories/GHSA-66x3-6cw3-v5gj\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  - category: google.golang.org/protobuf\n    message: 'google.golang.org/protobuf: CVE-2015-5237'\n    policy: CVE-2015-5237\n    properties:\n      FixedVersion: \"\"\n      InstalledVersion: v1.28.0\n      URL: https://github.com/google/protobuf/issues/760\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  - category: google.golang.org/protobuf\n    message: 'google.golang.org/protobuf: CVE-2021-22570'\n    policy: CVE-2021-22570\n    properties:\n      FixedVersion: \"\"\n      InstalledVersion: v1.28.0\n      URL: https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  - category: google.golang.org/protobuf\n    message: 'google.golang.org/protobuf: CVE-2015-5237'\n    policy: CVE-2015-5237\n    properties:\n      FixedVersion: \"\"\n      InstalledVersion: v1.28.0\n      URL: https://github.com/google/protobuf/issues/760\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  - category: google.golang.org/protobuf\n    message: 'google.golang.org/protobuf: CVE-2021-22570'\n    policy: CVE-2021-22570\n    properties:\n      FixedVersion: \"\"\n      InstalledVersion: v1.28.0\n      URL: https://github.com/protocolbuffers/protobuf/releases/tag/v3.15.0\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  - category: github.com/theupdateframework/go-tuf\n    message: 'github.com/theupdateframework/go-tuf: GHSA-66x3-6cw3-v5gj'\n    policy: GHSA-66x3-6cw3-v5gj\n    properties:\n      FixedVersion: 0.3.0\n      InstalledVersion: v0.0.0-20220211205608-f0c3294f63b9\n      URL: https://github.com/advisories/GHSA-66x3-6cw3-v5gj\n    resources:\n    - kind: Pod\n      name: kyverno-688464bd95-55drc\n      namespace: kyverno\n      uid: 24bdccbb-653a-4005-8463-cf511a919037\n    result: fail\n    severity: high\n    source: vulnerability-operator\n    timestamp:\n      nanos: 728434599\n      seconds: 1655564847\n  scope:\n    kind: Pod\n    name: kyverno-688464bd95-55drc\n    namespace: kyverno\n    uid: 24bdccbb-653a-4005-8463-cf511a919037\n  summary:\n    error: 0\n    fail: 6\n    pass: 0\n    skip: 0\n    warn: 0\n  ```\n\u003c/details\u003e\n\n## Context-based vulnerability filtering\n\nYou can apply filter rules to either ignore certain vulnerabilities or to move them into a separate metric.\nThis 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.\n\nFilter rules support the following properties:\n- CVE\n- package name\n- container context (with the following subset)\n  - image\n  - namespace\n  - kind\n  - name\n\nContainer context properties support glob patterns `*` and `?`, while CVE and package only match its exact value.\nThe container context only applies, if all of its properties are matching (AND condition).\n\nThe filter rules are provided through a yaml formatted file. Its path is configured with `--filter-config-file`.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExample filter configuration\u003c/summary\u003e\n\n  ```yaml\n  ignore:\n    # Ignore any vulnerabilities in ruby gem rdoc\n    - package: rdoc\n    # Ignore CVE GHSA-8cr8-4vfw-mr7h\n    - vulnerability: GHSA-8cr8-4vfw-mr7h\n  audit:\n    # If GHSA-fp4w-jxhp-m23p was found in gitlab-ce images, move it the \"audit\" metric\n    - vulnerability: GHSA-fp4w-jxhp-m23p\n      context:\n      - image: gitlab/gitlab-ce*\n        namespace: \"*\"\n        kind: \"*\"\n        name: \"*\"\n    # Move any CVE for the git package to the \"audit\" metric, if it was found in a gitlab-*-redis deployment\n    - package: git\n      context:\n      - image: \"*\"\n        namespace: \"*\"\n        kind: Deployment\n        name: gitlab-*-redis\n  ```\n\u003c/details\u003e\n\n#### Targets\n\nFor the Prometheus target, the separate metric `vuln_operator_cves_audit` contains matches from the `audit` section.\n\nFor the json target, a separate file `audited.json` is provided.\n\n## Security\n\nThe docker-image is based on a scratch-image to reduce the attack-surface and keep the image small. \nFurthermore the image and release-artifacts are signed with [cosign](https://github.com/sigstore/cosign) and attested with provenance-files. The release-process\nsatisfies SLSA Level 2. All of those \"metadata files\" are also stored in a dedicated repository `ghcr.io/ckotzbauer/vulnerability-operator-metadata`.\nBoth, SLSA and the signatures are still experimental for this project.\nWhen discovering security issues please refer to the [Security process](https://github.com/ckotzbauer/.github/blob/main/SECURITY.md).\n\n\n[License](https://github.com/ckotzbauer/vulnerability-operator/blob/master/LICENSE)\n--------\n[Changelog](https://github.com/ckotzbauer/vulnerability-operator/blob/master/CHANGELOG.md)\n--------\n\n\n## Contributing\n\nPlease refer to the [Contribution guildelines](https://github.com/ckotzbauer/.github/blob/main/CONTRIBUTING.md).\n\n## Code of conduct\n\nPlease refer to the [Conduct guildelines](https://github.com/ckotzbauer/.github/blob/main/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckotzbauer%2Fvulnerability-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckotzbauer%2Fvulnerability-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckotzbauer%2Fvulnerability-operator/lists"}