Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ package across our portfolio.
- **Lane 2: OCI image PURL with package subcomponent.** Use only when
the assertion varies per image. Subject is the OCI image PURL with
the `repository_url` qualifier; the affected package is named in
`subcomponents`. Because OCI PURLs are registry-coupled, list one
product entry per distribution registry — typically both
`quay.io/stackstate/<image>` and the Rancher-registry copy.
`subcomponents`. Because OCI PURLs are registry-coupled, author one
VEX file per distribution registry — typically both
`quay.io/stackstate/<image>` and the Rancher Prime
`registry.rancher.com/suse-observability/<image>` copy. This mirrors
Rancher's generated `rancher/vexhub` layout and lets Trivy's
`--vex repo` lookup resolve the exact image repository.

### Steps

Expand All @@ -85,10 +88,12 @@ package across our portfolio.
[tools/README.md](./tools/README.md) for command examples.
- Lane 1 path:
`pkg/maven/org.eclipse.jetty/jetty-http/scan.openvex.json`.
- Lane 2 path:
- Lane 2 paths:
`pkg/oci/quay.io/stackstate/zookeeper/scan.openvex.json`
(and a sibling under the Rancher-registry path, or a single file
listing both in `products`).
and
`pkg/oci/registry.rancher.com/suse-observability/zookeeper/scan.openvex.json`.
Each file should contain the matching single OCI product, for
example `pkg:oci/zookeeper?repository_url=quay.io/stackstate/zookeeper`.
2. Run `python3 tools/build_index.py` to regenerate `index.json`. CI
asserts the on-disk index matches the `pkg/` tree
(`tools/build_index.py --check`).
Expand Down
37 changes: 29 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ findings that genuinely don't apply to our deployment.
## Scope

VEX statements in this hub apply to SUSE Observability product
artefacts distributed under:
artefacts distributed as OCI images from:

- `pkg:oci/quay.io/stackstate/*`
- `pkg:oci/<rancher-registry-namespace>/*` (Rancher Prime distribution)
- `quay.io/stackstate/*`
- `registry.rancher.com/suse-observability/*` (Rancher Prime distribution)

OCI products are identified with the same PURL shape Rancher's hub
uses: `pkg:oci/<image-name>?repository_url=<registry>/<namespace>/<image>`.

The hub is **complementary to** the SUSE-wide automated VEX
pipeline operated by Rancher's
Expand Down Expand Up @@ -48,6 +51,22 @@ image is scoped to how *we* configure the chart — it makes no claim
about how SUSE Application Collection's source image behaves in
another consumer's environment.

## Relationship to Rancher's VEX repos

Rancher keeps authoring and publication separate:

- `rancher/image-scanning` is the workflow repo where reviewed VEX
input is validated against scanner data and generated into OpenVEX.
- `rancher/vexhub` is the published static hub consumed by Trivy and
other VEX repository clients.

This repo currently carries SUSE Observability-specific authoring and
publication together, but the published files intentionally mirror
`rancher/vexhub`: one `pkg/.../scan.openvex.json` file per indexed
product and an `index.json` with `version: 1` plus package IDs and
locations. If a statement can be handled by Rancher's `image-scanning`
workflow, prefer that route and let their automation publish it.

## Layout

```
Expand All @@ -57,19 +76,21 @@ vexhub/
CODEOWNERS
CONTRIBUTING.md
vex-repository.json Aqua VEX Repository v0.1 descriptor
index.json PURL -> file mapping (generated)
index.json VEX repository index (generated)
pkg/ OpenVEX statements, organised by PURL
maven/ pkg:maven/...
oci/ pkg:oci/... (image-scoped, Lane 2)
oci/ pkg:oci/... (image-scoped, one file per OCI product)
apk/, rpm/, npm/, ... one directory per PURL type as needed
reports/ CSV exports for human review (future)
docs/
adr/ Architecture decision records (future)
tools/ build_index.py + vexctl usage docs
```

Layout matches the Aqua VEX Hub convention so consumers familiar with
`aquasecurity/vexhub` find files where they expect.
Layout matches the Aqua/Rancher VEX Hub convention so consumers familiar
with `aquasecurity/vexhub` and `rancher/vexhub` find files where they
expect. `index.json` intentionally mirrors Rancher's generated index:
`version: 1` plus a `packages` list of PURL IDs and file locations.

## Consuming this hub with Trivy

Expand All @@ -87,7 +108,7 @@ Then run scans with the repo enabled:

```bash
trivy vex repo download
trivy image --vex repo --show-suppressed pkg:oci/quay.io/stackstate/zookeeper:<tag>
trivy image --vex repo --show-suppressed quay.io/stackstate/kafka:<tag>
```

Suppressed findings are annotated with the matching VEX statement and the
Expand Down
13 changes: 11 additions & 2 deletions index.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"updated_at": "2026-05-01T07:25:29Z",
"packages": []
"version": 1,
"packages": [
{
"id": "pkg:oci/kafka?repository_url=quay.io%2Fstackstate%2Fkafka",
"location": "pkg/oci/quay.io/stackstate/kafka/scan.openvex.json"
},
{
"id": "pkg:oci/kafka?repository_url=registry.rancher.com%2Fsuse-observability%2Fkafka",
"location": "pkg/oci/registry.rancher.com/suse-observability/kafka/scan.openvex.json"
}
]
}
143 changes: 143 additions & 0 deletions pkg/oci/quay.io/stackstate/kafka/scan.openvex.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://github.com/StackVista/vexhub/pkg/oci/quay.io/stackstate/kafka/scan.openvex.json",
"author": "SUSE Observability Security Engineering",
"role": "Document Creator",
"version": 6,
"statements": [
{
"vulnerability": {
"name": "CVE-2026-2332",
"aliases": [
"GHSA-355h-qmc2-wpwf"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/org.eclipse.jetty/jetty-http@9.4.57.v20241219"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "SUSE Observability deploys this image as a Kafka broker StatefulSet. The Kafka chart runs /scripts/setup.sh, and that script execs kafka-server-start.sh with server.properties. The chart does not start Kafka Connect, does not expose a Jetty REST listener from this image, and JMX metrics are served by a separate jmx-exporter sidecar image. This statement does not apply to ad hoc use of this image for Kafka Connect or a custom command that starts Jetty-backed services.",
"timestamp": "2026-05-08T05:03:13Z"
},
{
"vulnerability": {
"name": "CVE-2025-67030",
"aliases": [
"GHSA-6fmv-xxpf-w3cw"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/org.codehaus.plexus/plexus-utils@3.5.1"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "The reported plexus-utils issue is in archive extraction. SUSE Observability starts the image as a Kafka broker using kafka-server-start.sh and does not run Kafka Connect, plugin archive installation, Maven tooling, or any product workflow that extracts attacker-provided archives through plexus-utils inside the broker container. This statement does not apply to custom commands, manual operator sessions, or Kafka Connect deployments that use this image to unpack untrusted plugin archives.",
"timestamp": "2026-05-08T05:03:13Z"
},
{
"vulnerability": {
"name": "CVE-2026-24281",
"aliases": [
"GHSA-7xrh-hqfc-g7qr"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/org.apache.zookeeper/zookeeper@3.8.4"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "This ZooKeeper finding is in TLS hostname verification through ZKTrustManager. The SUSE Observability Kafka chart defaults ZooKeeper client TLS to disabled and connects the brokers to the chart-managed ZooKeeper service through KAFKA_ZOOKEEPER_CONNECT without ZooKeeper TLS client material. The ZKTrustManager hostname-verification path is therefore not executed in the supported default broker deployment. This statement does not apply if auth.zookeeper.tls.enabled is enabled or if the image is run with custom ZooKeeper TLS client configuration.",
"timestamp": "2026-05-08T05:03:13Z"
},
{
"vulnerability": {
"name": "CVE-2026-24308",
"aliases": [
"GHSA-crhr-qqj8-rpxc"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/org.apache.zookeeper/zookeeper@3.8.4"
}
]
}
],
"status": "not_affected",
"justification": "inline_mitigations_already_exist",
"impact_statement": "This ZooKeeper finding concerns sensitive ZooKeeper client configuration values being logged. In the supported SUSE Observability Kafka broker deployment, ZooKeeper client TLS is disabled by default and auth.sasl.jaas.zookeeperUser/zookeeperPassword are empty, so the chart does not inject ZooKeeper client credentials or TLS secret paths into the broker's ZooKeeper client configuration. This statement does not apply to deployments that enable ZooKeeper SASL or ZooKeeper client TLS for Kafka brokers without re-validating the rendered configuration and log output.",
"timestamp": "2026-05-08T05:03:13Z"
},
{
"vulnerability": {
"name": "CVE-2026-42577",
"aliases": [
"GHSA-rwm7-x88c-3g2p"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/io.netty/netty-transport-native-epoll@4.1.125.Final"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "SUSE Observability starts this image as a Kafka broker. Kafka's broker listeners are configured through the chart's Kafka TCP listener settings and the chart does not configure ZooKeeper's Netty client socket implementation or Netty epoll transport for broker-to-ZooKeeper communication. The vulnerable Netty native epoll transport is present in the image but is not part of the broker execute path. This statement does not apply to custom commands or configuration that explicitly uses Netty epoll from this image.",
"timestamp": "2026-05-08T05:03:13Z"
},
{
"vulnerability": {
"name": "CVE-2026-42583",
"aliases": [
"GHSA-mj4r-2hfc-f8p6"
]
},
"products": [
{
"@id": "pkg:oci/kafka?repository_url=quay.io/stackstate/kafka",
"subcomponents": [
{
"@id": "pkg:maven/io.netty/netty-codec@4.1.125.Final"
}
]
}
],
"status": "not_affected",
"justification": "vulnerable_code_not_in_execute_path",
"impact_statement": "SUSE Observability starts this image as a Kafka broker and does not run Kafka Connect, Jetty REST endpoints, Netty-based services, or ZooKeeper's Netty client socket implementation from this container. The vulnerable Netty codec package is present in the image but is not used by the supported broker runtime path. This statement does not apply to custom commands or configuration that explicitly uses Netty codecs from this image.",
"timestamp": "2026-05-08T05:03:13Z"
}
],
"timestamp": "2026-05-08T05:03:13Z",
"last_updated": "2026-05-08T05:03:13Z"
}
Loading