wip: sidecar for trivy #3012

Merged
mfreeman451 merged 16 commits from refs/pull/3012/head into staging 2026-03-04 05:50:10 +00:00
mfreeman451 commented 2026-03-03 16:44:14 +00:00 (Migrated from github.com)
Owner

Imported from GitHub pull request.

Original GitHub pull request: #2988
Original author: @mfreeman451
Original URL: https://github.com/carverauto/serviceradar/pull/2988
Original created: 2026-03-03T16:44:14Z
Original updated: 2026-03-04T05:50:20Z
Original head: carverauto/serviceradar:2987-feat-trivy-support
Original base: staging
Original merged: 2026-03-04T05:50:10Z by @mfreeman451

IMPORTANT: Please sign the Developer Certificate of Origin

Thank you for your contribution to ServiceRadar. Please note, when contributing, the developer must include
a DCO sign-off statement indicating the DCO acceptance in one commit message. Here
is an example DCO Signed-off-by line in a commit message:

Signed-off-by: J. Doe <j.doe@domain.com>

Describe your changes

Code checklist before requesting a review

  • I have signed the DCO?
  • The build completes without errors?
  • All tests are passing when running make test?
Imported from GitHub pull request. Original GitHub pull request: #2988 Original author: @mfreeman451 Original URL: https://github.com/carverauto/serviceradar/pull/2988 Original created: 2026-03-03T16:44:14Z Original updated: 2026-03-04T05:50:20Z Original head: carverauto/serviceradar:2987-feat-trivy-support Original base: staging Original merged: 2026-03-04T05:50:10Z by @mfreeman451 --- ## IMPORTANT: Please sign the Developer Certificate of Origin Thank you for your contribution to ServiceRadar. Please note, when contributing, the developer must include a [DCO sign-off statement]( https://developercertificate.org/) indicating the DCO acceptance in one commit message. Here is an example DCO Signed-off-by line in a commit message: ``` Signed-off-by: J. Doe <j.doe@domain.com> ``` ## Describe your changes ## Issue ticket number and link ## Code checklist before requesting a review - [ ] I have signed the DCO? - [ ] The build completes without errors? - [ ] All tests are passing when running make test?
qodo-code-review[bot] commented 2026-03-03 16:44:56 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2988#issuecomment-3992267467
Original created: 2026-03-03T16:44:56Z

Review Summary by Qodo

Add Trivy Operator NATS sidecar service with CRD watching and JetStream publishing

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Implements a complete Trivy sidecar service that watches Trivy Operator CRDs and publishes
  findings to NATS JetStream
• Core components include dynamic CRD discovery, event deduplication by resourceVersion, and retry
  logic with exponential backoff
• Provides operational metrics (published, failures, deduplicated, dropped messages) with Prometheus
  export and health check endpoints
• Implements secure NATS publishing with TLS support (CA cert, mTLS, SNI) and JWT credentials
  authentication
• Generates deterministic event IDs using SHA256 hashing for reliable deduplication across cluster
  restarts
• Includes comprehensive unit and integration tests for deduplication, retry mechanisms, and NATS
  JetStream publishing
• Provides Kubernetes deployment manifest with RBAC, environment configuration, and metrics exposure
• Comprehensive documentation covering architecture, deployment guide, environment variables,
  troubleshooting, and design rationale
Diagram
flowchart LR
  A["Trivy Operator CRDs"] -->|Watch| B["trivy-sidecar Service"]
  B -->|Deduplicate| C["RevisionDeduper"]
  B -->|Retry Logic| D["NATSPublisher"]
  D -->|Publish| E["NATS JetStream"]
  B -->|Track| F["Metrics"]
  F -->|Export| G["Prometheus /metrics"]
  B -->|Health Check| H["HTTP Server"]
  H -->|Expose| I["/healthz /readyz /metrics"]
Grey Divider

File Changes

1. go/pkg/trivysidecar/metrics.go ✨ Enhancement +181/-0

Operational metrics tracking and Prometheus export

• Implements Metrics struct with atomic counters for tracking sidecar operational telemetry
 (published, failures, deduplicated, dropped, watch restarts, skipped kinds)
• Provides methods to increment counters and track last publish timestamp
• Implements Prometheus metrics export via WritePrometheus() with per-kind breakdown
• Includes label escaping utility for Prometheus format compliance

go/pkg/trivysidecar/metrics.go


2. go/pkg/trivysidecar/service.go ✨ Enhancement +225/-0

Core sidecar service for Trivy report publishing

• Implements Service struct that orchestrates Trivy CRD watching and NATS publishing
• Discovers available report kinds via Kubernetes discovery API and starts dynamic informers
• Handles object events (add/update) with deduplication by resourceVersion
• Implements retry logic with exponential backoff for failed publishes

go/pkg/trivysidecar/service.go


3. go/pkg/trivysidecar/config.go ⚙️ Configuration changes +191/-0

Configuration loading and validation from environment

• Defines Config struct with NATS connection, Kubernetes, and publish retry settings
• Implements LoadConfigFromEnv() to read configuration from environment variables with defaults
• Validates required fields (NATS_HOSTPORT, CLUSTER_ID) and timing constraints
• Provides helper functions for parsing duration and boolean environment variables

go/pkg/trivysidecar/config.go


View more (21)
4. go/pkg/trivysidecar/publisher.go ✨ Enhancement +168/-0

NATS JetStream publisher with TLS and auth support

• Implements NATSPublisher interface for publishing messages to NATS JetStream
• Handles TLS configuration with CA cert, client cert/key pairs, and SNI support
• Manages connection state tracking and error handling
• Supports NATS credentials file authentication and configurable reconnect behavior

go/pkg/trivysidecar/publisher.go


5. go/pkg/trivysidecar/envelope.go ✨ Enhancement +164/-0

Message envelope construction and event ID generation

• Defines Envelope struct as normalized payload for NATS messages with cluster, report, and owner
 metadata
• Implements BuildEnvelope() to construct envelopes from Kubernetes unstructured objects
• Generates deterministic event_id using SHA256 hash of
 cluster/kind/namespace/name/resourceVersion
• Extracts summary and owner references from report objects

go/pkg/trivysidecar/envelope.go


6. go/pkg/trivysidecar/kinds.go ✨ Enhancement +102/-0

Trivy report kind discovery and subject mapping

• Defines ReportKind struct describing Trivy CRD types and NATS subject mappings
• Provides DefaultSupportedReportKinds() listing 10 report kinds (vulnerability, configaudit,
 exposedsecret, rbacassessment, infraassessment and cluster variants)
• Implements DiscoverReportKinds() to query Kubernetes API for available CRDs
• Includes MissingKinds() to identify unsupported report kinds

go/pkg/trivysidecar/kinds.go


7. go/pkg/trivysidecar/service_test.go 🧪 Tests +101/-0

Unit tests for service deduplication and retry logic

• Tests deduplication logic by verifying unchanged resourceVersions are not republished
• Tests publish retry mechanism with configurable failure injection
• Validates metrics counters for deduplicated and published messages

go/pkg/trivysidecar/service_test.go


8. go/pkg/trivysidecar/publisher_integration_test.go 🧪 Tests +105/-0

Integration test for NATS JetStream publishing

• Integration test that spins up embedded NATS JetStream server
• Verifies NATSPublisher successfully publishes messages to JetStream stream
• Validates message count in stream after publish

go/pkg/trivysidecar/publisher_integration_test.go


9. go/pkg/trivysidecar/health.go ✨ Enhancement +92/-0

HTTP health and metrics endpoints

• Implements HTTPServer exposing /healthz, /readyz, and /metrics endpoints
• Readiness probe checks publisher connection and watching kinds count
• Metrics endpoint exports Prometheus format metrics via WritePrometheus()
• Includes JSON response helpers for health endpoints

go/pkg/trivysidecar/health.go


10. go/pkg/trivysidecar/envelope_test.go 🧪 Tests +69/-0

Unit tests for envelope construction and event ID

• Tests deterministic event_id generation with same and different resourceVersions
• Tests envelope construction including owner reference and summary extraction
• Validates summary field extraction from nested report structure

go/pkg/trivysidecar/envelope_test.go


11. go/pkg/trivysidecar/runtime.go ✨ Enhancement +89/-0

Runtime lifecycle management and Kubernetes client setup

• Implements Runtime struct bundling service, HTTP server, and publisher lifecycle
• Builds Kubernetes clients (dynamic, discovery) from in-cluster or kubeconfig configuration
• Orchestrates startup of HTTP metrics server and service run loop
• Handles graceful shutdown of publisher and HTTP server

go/pkg/trivysidecar/runtime.go


12. go/cmd/tools/trivy-sidecar/main.go ✨ Enhancement +39/-0

Trivy sidecar main entry point

• Entry point for trivy-sidecar binary
• Loads configuration from environment, creates runtime, and runs service
• Handles OS signals (SIGINT, SIGTERM) for graceful shutdown
• Returns appropriate exit codes on configuration or runtime errors

go/cmd/tools/trivy-sidecar/main.go


13. go/pkg/trivysidecar/deduper.go ✨ Enhancement +31/-0

Revision deduplication tracker

• Implements RevisionDeduper to track last published resourceVersion per UID
• Provides IsDuplicate() to check if a revision was already published
• Provides MarkPublished() to record published revisions
• Uses RWMutex for thread-safe access

go/pkg/trivysidecar/deduper.go


14. go/pkg/trivysidecar/kinds_test.go 🧪 Tests +12/-0

Unit test for subject generation

• Tests subject construction for report kinds with prefix and suffix

go/pkg/trivysidecar/kinds_test.go


15. go/pkg/trivysidecar/utils.go Miscellaneous +13/-0

Map cloning utility function

• Implements cloneMap() utility to deep copy map[string]any objects
• Used for safe manipulation of Kubernetes object payloads

go/pkg/trivysidecar/utils.go


16. go.sum Dependencies +96/-1

Dependency checksums for Kubernetes and NATS

• Adds checksums for Kubernetes client-go and apimachinery dependencies (v0.32.5)
• Adds checksums for NATS server and client libraries
• Adds checksums for supporting libraries (protobuf, gofuzz, json-iterator, etc.)

go.sum


17. k8s/demo/base/serviceradar-trivy-sidecar.yaml ⚙️ Configuration changes +156/-0

Kubernetes deployment manifest for trivy-sidecar

• Defines Kubernetes ServiceAccount, ClusterRole, and ClusterRoleBinding for sidecar RBAC
• Configures Deployment with environment variables for NATS and Trivy configuration
• Mounts NATS credentials and certificates from secrets/PVCs
• Exposes metrics port 9108 with liveness and readiness probes
• Includes resource requests/limits and Service for metrics endpoint

k8s/demo/base/serviceradar-trivy-sidecar.yaml


18. docs/docs/trivy-integration.md 📝 Documentation +135/-0

Trivy integration documentation and deployment guide

• Documents architecture showing Trivy Operator CRDs flowing through sidecar to NATS JetStream
• Provides build, deployment, and verification instructions
• Lists all supported environment variables with defaults
• Includes troubleshooting guide for common issues (connectivity, CRD availability, TLS)

docs/docs/trivy-integration.md


19. openspec/changes/add-trivy-operator-nats-sidecar/design.md 📝 Documentation +100/-0

Design document for Trivy sidecar architecture

• Outlines design decisions for dedicated trivy-sidecar service
• Reuses Falcosidekick NATS connection patterns for auth and TLS
• Defines low-cardinality subject contract (trivy.report.<kind>)
• Specifies message envelope structure with deterministic event_id and deduplication strategy
• Documents failure handling, deployment model, and migration plan

openspec/changes/add-trivy-operator-nats-sidecar/design.md


20. openspec/changes/add-trivy-operator-nats-sidecar/specs/trivy-nats-ingestion/spec.md 📝 Documentation +83/-0

Specification for Trivy NATS ingestion requirements

• Defines requirements for publishing Trivy reports to JetStream
• Specifies deterministic event ID generation for deduplication
• Documents NATS authentication and TLS configuration requirements
• Includes scenarios for handling partial CRD availability and operational telemetry

openspec/changes/add-trivy-operator-nats-sidecar/specs/trivy-nats-ingestion/spec.md


21. go.mod Dependencies +30/-0

Kubernetes client library dependencies

• Adds Kubernetes client-go (v0.32.5) and apimachinery (v0.32.5) dependencies
• Adds transitive dependencies for Kubernetes API machinery (klog, kube-openapi, utils, etc.)
• Adds JSON and YAML handling libraries for Kubernetes objects

go.mod


22. docs/sidebars.ts 📝 Documentation +1/-0

Documentation sidebar navigation update

• Adds Trivy Integration documentation link to sidebar navigation
• Positioned after Falco Integration in integration section

docs/sidebars.ts


23. openspec/changes/add-trivy-operator-nats-sidecar/proposal.md 📝 Documentation +40/-0

Trivy Operator NATS sidecar integration proposal and design

• Introduces a new Go sidecar service (trivy-sidecar) that watches Trivy Operator CRDs and
 publishes findings to NATS JetStream
• Reuses proven NATS authentication patterns (JWT .creds, CA verification, mTLS) from existing
 falcosidekick implementation
• Supports multiple Trivy report types (VulnerabilityReport, ConfigAuditReport,
 ExposedSecretReport, RbacAssessmentReport, InfraAssessmentReport) with deterministic event
 identity and deduplication
• Includes metrics, health endpoints, and operational documentation for deployment verification
 against live Kubernetes clusters

openspec/changes/add-trivy-operator-nats-sidecar/proposal.md


24. openspec/changes/add-trivy-operator-nats-sidecar/tasks.md 📝 Documentation +33/-0

Trivy sidecar implementation task checklist and tracking

• Defines implementation tasks across five categories: sidecar foundation, NATS publishing,
 security/deployment, validation, and documentation
• Most tasks marked complete (checkboxes checked) including Kubernetes discovery, informer wiring,
 NATS connection setup, envelope building, and unit/integration tests
• One manual validation task (4.4) remains pending for live cluster testing with kubectl and
 nats CLI
• Includes documentation task for deployment guide and operational troubleshooting steps

openspec/changes/add-trivy-operator-nats-sidecar/tasks.md


Grey Divider

Qodo Logo

Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2988#issuecomment-3992267467 Original created: 2026-03-03T16:44:56Z --- <h3>Review Summary by Qodo</h3> Add Trivy Operator NATS sidecar service with CRD watching and JetStream publishing <code>✨ Enhancement</code> <code>🧪 Tests</code> <code>📝 Documentation</code> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <h3>Walkthroughs</h3> <details open> <summary>Description</summary> <br/> <pre> • Implements a complete Trivy sidecar service that watches Trivy Operator CRDs and publishes findings to NATS JetStream • Core components include dynamic CRD discovery, event deduplication by resourceVersion, and retry logic with exponential backoff • Provides operational metrics (published, failures, deduplicated, dropped messages) with Prometheus export and health check endpoints • Implements secure NATS publishing with TLS support (CA cert, mTLS, SNI) and JWT credentials authentication • Generates deterministic event IDs using SHA256 hashing for reliable deduplication across cluster restarts • Includes comprehensive unit and integration tests for deduplication, retry mechanisms, and NATS JetStream publishing • Provides Kubernetes deployment manifest with RBAC, environment configuration, and metrics exposure • Comprehensive documentation covering architecture, deployment guide, environment variables, troubleshooting, and design rationale </pre> </details> <details> <summary>Diagram</summary> <br/> > ```mermaid flowchart LR A["Trivy Operator CRDs"] -->|Watch| B["trivy-sidecar Service"] B -->|Deduplicate| C["RevisionDeduper"] B -->|Retry Logic| D["NATSPublisher"] D -->|Publish| E["NATS JetStream"] B -->|Track| F["Metrics"] F -->|Export| G["Prometheus /metrics"] B -->|Health Check| H["HTTP Server"] H -->|Expose| I["/healthz /readyz /metrics"] ``` </details> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <h3>File Changes</h3> <details> <summary>1. go/pkg/trivysidecar/metrics.go <code>✨ Enhancement</code> <code> +181/-0 </code> </summary> <br/> >Operational metrics tracking and Prometheus export ><pre> >• Implements <b><i>Metrics</i></b> struct with atomic counters for tracking sidecar operational telemetry > (published, failures, deduplicated, dropped, watch restarts, skipped kinds) >• Provides methods to increment counters and track last publish timestamp >• Implements Prometheus metrics export via <b><i>WritePrometheus()</i></b> with per-kind breakdown >• Includes label escaping utility for Prometheus format compliance ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-a461a52c08cb9804f93c7dff94ee94bac1882aa997a50db2017f5c9a4771ad27'> go/pkg/trivysidecar/metrics.go </a> <hr/> </details> <details> <summary>2. go/pkg/trivysidecar/service.go <code>✨ Enhancement</code> <code> +225/-0 </code> </summary> <br/> >Core sidecar service for Trivy report publishing ><pre> >• Implements <b><i>Service</i></b> struct that orchestrates Trivy CRD watching and NATS publishing >• Discovers available report kinds via Kubernetes discovery API and starts dynamic informers >• Handles object events (add/update) with deduplication by resourceVersion >• Implements retry logic with exponential backoff for failed publishes ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-af87504899cb539e93c74343b83b2bc22fc89f1a17da796f72097b9a524fe722'> go/pkg/trivysidecar/service.go </a> <hr/> </details> <details> <summary>3. go/pkg/trivysidecar/config.go <code>⚙️ Configuration changes</code> <code> +191/-0 </code> </summary> <br/> >Configuration loading and validation from environment ><pre> >• Defines <b><i>Config</i></b> struct with NATS connection, Kubernetes, and publish retry settings >• Implements <b><i>LoadConfigFromEnv()</i></b> to read configuration from environment variables with defaults >• Validates required fields (<b><i>NATS_HOSTPORT</i></b>, <b><i>CLUSTER_ID</i></b>) and timing constraints >• Provides helper functions for parsing duration and boolean environment variables ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-ecf66476ca413579156eadfb48b574b04a2d93fef47cc1f94ef8369676abc86c'> go/pkg/trivysidecar/config.go </a> <hr/> </details> <details><summary><ins><strong>View more (21)</strong></ins></summary><br/> <details> <summary>4. go/pkg/trivysidecar/publisher.go <code>✨ Enhancement</code> <code> +168/-0 </code> </summary> <br/> >NATS JetStream publisher with TLS and auth support ><pre> >• Implements <b><i>NATSPublisher</i></b> interface for publishing messages to NATS JetStream >• Handles TLS configuration with CA cert, client cert/key pairs, and SNI support >• Manages connection state tracking and error handling >• Supports NATS credentials file authentication and configurable reconnect behavior ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-eaecb20a3b0fe2b04f09d30dcded1515292f88ca51482bdfa4830c4828b37c42'> go/pkg/trivysidecar/publisher.go </a> <hr/> </details> <details> <summary>5. go/pkg/trivysidecar/envelope.go <code>✨ Enhancement</code> <code> +164/-0 </code> </summary> <br/> >Message envelope construction and event ID generation ><pre> >• Defines <b><i>Envelope</i></b> struct as normalized payload for NATS messages with cluster, report, and owner > metadata >• Implements <b><i>BuildEnvelope()</i></b> to construct envelopes from Kubernetes unstructured objects >• Generates deterministic <b><i>event_id</i></b> using SHA256 hash of > cluster/kind/namespace/name/resourceVersion >• Extracts summary and owner references from report objects ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-0935678e83f7e44d42884a84c30a13eea5b52c7b8901e1b28b0be6f5b9ec3478'> go/pkg/trivysidecar/envelope.go </a> <hr/> </details> <details> <summary>6. go/pkg/trivysidecar/kinds.go <code>✨ Enhancement</code> <code> +102/-0 </code> </summary> <br/> >Trivy report kind discovery and subject mapping ><pre> >• Defines <b><i>ReportKind</i></b> struct describing Trivy CRD types and NATS subject mappings >• Provides <b><i>DefaultSupportedReportKinds()</i></b> listing 10 report kinds (vulnerability, configaudit, > exposedsecret, rbacassessment, infraassessment and cluster variants) >• Implements <b><i>DiscoverReportKinds()</i></b> to query Kubernetes API for available CRDs >• Includes <b><i>MissingKinds()</i></b> to identify unsupported report kinds ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-6d4156fd766e3cab181cdc9e87bd2b76af9b0bc64cf9f9141e4be583399bbeca'> go/pkg/trivysidecar/kinds.go </a> <hr/> </details> <details> <summary>7. go/pkg/trivysidecar/service_test.go <code>🧪 Tests</code> <code> +101/-0 </code> </summary> <br/> >Unit tests for service deduplication and retry logic ><pre> >• Tests deduplication logic by verifying unchanged resourceVersions are not republished >• Tests publish retry mechanism with configurable failure injection >• Validates metrics counters for deduplicated and published messages ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-28dec4ad4fb310dbc9ce80cf6503551ab4b6345ad4190f7be7527c5d34df0442'> go/pkg/trivysidecar/service_test.go </a> <hr/> </details> <details> <summary>8. go/pkg/trivysidecar/publisher_integration_test.go <code>🧪 Tests</code> <code> +105/-0 </code> </summary> <br/> >Integration test for NATS JetStream publishing ><pre> >• Integration test that spins up embedded NATS JetStream server >• Verifies <b><i>NATSPublisher</i></b> successfully publishes messages to JetStream stream >• Validates message count in stream after publish ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-2ed55120eb1fb56d268c76a4497de94199f8497d00ade35ea21b73e6f64c0ab8'> go/pkg/trivysidecar/publisher_integration_test.go </a> <hr/> </details> <details> <summary>9. go/pkg/trivysidecar/health.go <code>✨ Enhancement</code> <code> +92/-0 </code> </summary> <br/> >HTTP health and metrics endpoints ><pre> >• Implements <b><i>HTTPServer</i></b> exposing <b><i>/healthz</i></b>, <b><i>/readyz</i></b>, and <b><i>/metrics</i></b> endpoints >• Readiness probe checks publisher connection and watching kinds count >• Metrics endpoint exports Prometheus format metrics via <b><i>WritePrometheus()</i></b> >• Includes JSON response helpers for health endpoints ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-e04b2828ef5581695f9f70dabdeca0459edc25494e1ad23ef9a3bb47fb9712fa'> go/pkg/trivysidecar/health.go </a> <hr/> </details> <details> <summary>10. go/pkg/trivysidecar/envelope_test.go <code>🧪 Tests</code> <code> +69/-0 </code> </summary> <br/> >Unit tests for envelope construction and event ID ><pre> >• Tests deterministic <b><i>event_id</i></b> generation with same and different resourceVersions >• Tests envelope construction including owner reference and summary extraction >• Validates summary field extraction from nested report structure ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-81a4e2a42886914061b4419abeb50ea75cc32a5857777d05647a7a55e137ea75'> go/pkg/trivysidecar/envelope_test.go </a> <hr/> </details> <details> <summary>11. go/pkg/trivysidecar/runtime.go <code>✨ Enhancement</code> <code> +89/-0 </code> </summary> <br/> >Runtime lifecycle management and Kubernetes client setup ><pre> >• Implements <b><i>Runtime</i></b> struct bundling service, HTTP server, and publisher lifecycle >• Builds Kubernetes clients (dynamic, discovery) from in-cluster or kubeconfig configuration >• Orchestrates startup of HTTP metrics server and service run loop >• Handles graceful shutdown of publisher and HTTP server ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-3523bdac06515434cfd27265889380d059ed7d0eeb5c77ee52347dda43d3b5b3'> go/pkg/trivysidecar/runtime.go </a> <hr/> </details> <details> <summary>12. go/cmd/tools/trivy-sidecar/main.go <code>✨ Enhancement</code> <code> +39/-0 </code> </summary> <br/> >Trivy sidecar main entry point ><pre> >• Entry point for <b><i>trivy-sidecar</i></b> binary >• Loads configuration from environment, creates runtime, and runs service >• Handles OS signals (SIGINT, SIGTERM) for graceful shutdown >• Returns appropriate exit codes on configuration or runtime errors ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-66af22b566404d3571c32f5cb2904fb148a2c3da270ef2bb0d04e39985649a9b'> go/cmd/tools/trivy-sidecar/main.go </a> <hr/> </details> <details> <summary>13. go/pkg/trivysidecar/deduper.go <code>✨ Enhancement</code> <code> +31/-0 </code> </summary> <br/> >Revision deduplication tracker ><pre> >• Implements <b><i>RevisionDeduper</i></b> to track last published resourceVersion per UID >• Provides <b><i>IsDuplicate()</i></b> to check if a revision was already published >• Provides <b><i>MarkPublished()</i></b> to record published revisions >• Uses RWMutex for thread-safe access ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-d5875843780fbe278f52b9f00440b6206e794c1221b1ae2bda15b1254fafc4e5'> go/pkg/trivysidecar/deduper.go </a> <hr/> </details> <details> <summary>14. go/pkg/trivysidecar/kinds_test.go <code>🧪 Tests</code> <code> +12/-0 </code> </summary> <br/> >Unit test for subject generation ><pre> >• Tests subject construction for report kinds with prefix and suffix ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-b8f1482f2557a25f89c9ab219865644f66abc364c4ee0248efa9e7df731b8724'> go/pkg/trivysidecar/kinds_test.go </a> <hr/> </details> <details> <summary>15. go/pkg/trivysidecar/utils.go <code> Miscellaneous </code> <code> +13/-0 </code> </summary> <br/> >Map cloning utility function ><pre> >• Implements <b><i>cloneMap()</i></b> utility to deep copy map[string]any objects >• Used for safe manipulation of Kubernetes object payloads ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-eddf2682d1e439da6f8b9e5f6ca1de28a9a7aadac34eb752b6f0411c88d91cbf'> go/pkg/trivysidecar/utils.go </a> <hr/> </details> <details> <summary>16. go.sum <code> Dependencies </code> <code> +96/-1 </code> </summary> <br/> >Dependency checksums for Kubernetes and NATS ><pre> >• Adds checksums for Kubernetes client-go and apimachinery dependencies (v0.32.5) >• Adds checksums for NATS server and client libraries >• Adds checksums for supporting libraries (protobuf, gofuzz, json-iterator, etc.) ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-3295df7234525439d778f1b282d146a4f1ff6b415248aaac074e8042d9f42d63'> go.sum </a> <hr/> </details> <details> <summary>17. k8s/demo/base/serviceradar-trivy-sidecar.yaml <code>⚙️ Configuration changes</code> <code> +156/-0 </code> </summary> <br/> >Kubernetes deployment manifest for trivy-sidecar ><pre> >• Defines Kubernetes ServiceAccount, ClusterRole, and ClusterRoleBinding for sidecar RBAC >• Configures Deployment with environment variables for NATS and Trivy configuration >• Mounts NATS credentials and certificates from secrets/PVCs >• Exposes metrics port 9108 with liveness and readiness probes >• Includes resource requests/limits and Service for metrics endpoint ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-f2a6a15043b998a47b13b3216573bb56f7ffca11f65533073e79bba41a4efa3d'> k8s/demo/base/serviceradar-trivy-sidecar.yaml </a> <hr/> </details> <details> <summary>18. docs/docs/trivy-integration.md <code>📝 Documentation</code> <code> +135/-0 </code> </summary> <br/> >Trivy integration documentation and deployment guide ><pre> >• Documents architecture showing Trivy Operator CRDs flowing through sidecar to NATS JetStream >• Provides build, deployment, and verification instructions >• Lists all supported environment variables with defaults >• Includes troubleshooting guide for common issues (connectivity, CRD availability, TLS) ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-baf5892cf49794ff0c7ec234a20fc573f641feb379892ee58b7aa2ea9cf2dfbc'> docs/docs/trivy-integration.md </a> <hr/> </details> <details> <summary>19. openspec/changes/add-trivy-operator-nats-sidecar/design.md <code>📝 Documentation</code> <code> +100/-0 </code> </summary> <br/> >Design document for Trivy sidecar architecture ><pre> >• Outlines design decisions for dedicated <b><i>trivy-sidecar</i></b> service >• Reuses Falcosidekick NATS connection patterns for auth and TLS >• Defines low-cardinality subject contract (trivy.report.&lt;kind&gt;) >• Specifies message envelope structure with deterministic event_id and deduplication strategy >• Documents failure handling, deployment model, and migration plan ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-51de18a00ed6613df8d32e56dd00e4d49d619529f051f7edd7332141c04b141a'> openspec/changes/add-trivy-operator-nats-sidecar/design.md </a> <hr/> </details> <details> <summary>20. openspec/changes/add-trivy-operator-nats-sidecar/specs/trivy-nats-ingestion/spec.md <code>📝 Documentation</code> <code> +83/-0 </code> </summary> <br/> >Specification for Trivy NATS ingestion requirements ><pre> >• Defines requirements for publishing Trivy reports to JetStream >• Specifies deterministic event ID generation for deduplication >• Documents NATS authentication and TLS configuration requirements >• Includes scenarios for handling partial CRD availability and operational telemetry ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-06a3d926e3c2108c9b3d3758fddd15c48c53801880d16fb708dd203d0306cfe4'> openspec/changes/add-trivy-operator-nats-sidecar/specs/trivy-nats-ingestion/spec.md </a> <hr/> </details> <details> <summary>21. go.mod <code> Dependencies </code> <code> +30/-0 </code> </summary> <br/> >Kubernetes client library dependencies ><pre> >• Adds Kubernetes client-go (v0.32.5) and apimachinery (v0.32.5) dependencies >• Adds transitive dependencies for Kubernetes API machinery (klog, kube-openapi, utils, etc.) >• Adds JSON and YAML handling libraries for Kubernetes objects ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-33ef32bf6c23acb95f5902d7097b7a1d5128ca061167ec0716715b0b9eeaa5f6'> go.mod </a> <hr/> </details> <details> <summary>22. docs/sidebars.ts <code>📝 Documentation</code> <code> +1/-0 </code> </summary> <br/> >Documentation sidebar navigation update ><pre> >• Adds Trivy Integration documentation link to sidebar navigation >• Positioned after Falco Integration in integration section ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-6e908f6e4016ad389cfb93ce7a47df677247c0f9d17c3589710592e8cf9527e0'> docs/sidebars.ts </a> <hr/> </details> <details> <summary>23. openspec/changes/add-trivy-operator-nats-sidecar/proposal.md <code>📝 Documentation</code> <code> +40/-0 </code> </summary> <br/> >Trivy Operator NATS sidecar integration proposal and design ><pre> >• Introduces a new Go sidecar service (<b><i>trivy-sidecar</i></b>) that watches Trivy Operator CRDs and > publishes findings to NATS JetStream >• Reuses proven NATS authentication patterns (JWT <b><i>.creds</i></b>, CA verification, mTLS) from existing > <b><i>falcosidekick</i></b> implementation >• Supports multiple Trivy report types (<b><i>VulnerabilityReport</i></b>, <b><i>ConfigAuditReport</i></b>, > <b><i>ExposedSecretReport</i></b>, <b><i>RbacAssessmentReport</i></b>, <b><i>InfraAssessmentReport</i></b>) with deterministic event > identity and deduplication >• Includes metrics, health endpoints, and operational documentation for deployment verification > against live Kubernetes clusters ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-df93a6356b087c939a7ef59224b6d19223b25461ea7b05c2af889745b79fd634'> openspec/changes/add-trivy-operator-nats-sidecar/proposal.md </a> <hr/> </details> <details> <summary>24. openspec/changes/add-trivy-operator-nats-sidecar/tasks.md <code>📝 Documentation</code> <code> +33/-0 </code> </summary> <br/> >Trivy sidecar implementation task checklist and tracking ><pre> >• Defines implementation tasks across five categories: sidecar foundation, NATS publishing, > security/deployment, validation, and documentation >• Most tasks marked complete (checkboxes checked) including Kubernetes discovery, informer wiring, > NATS connection setup, envelope building, and unit/integration tests >• One manual validation task (<b><i>4.4</i></b>) remains pending for live cluster testing with <b><i>kubectl</i></b> and > <b><i>nats</i></b> CLI >• Includes documentation task for deployment guide and operational troubleshooting steps ></pre> > ><a href='https://github.com/carverauto/serviceradar/pull/2988/files#diff-b0027a1761f91a132380ee7131215c9f6705668d20d3fa071759381d3603f5e8'> openspec/changes/add-trivy-operator-nats-sidecar/tasks.md </a> <hr/> </details> </details> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <a href="https://www.qodo.ai"><img src="https://www.qodo.ai/wp-content/uploads/2025/03/qodo-logo.svg" width="80" alt="Qodo Logo"></a>
qodo-code-review[bot] commented 2026-03-03 16:44:58 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2988#issuecomment-3992267565
Original created: 2026-03-03T16:44:58Z

Code Review by Qodo

🐞 Bugs (5) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider
Action required
1. MODULE.bazel missing k8s repos 📘 Rule violation ⛯ Reliability
Description
go.mod adds new Kubernetes (k8s.io/* and related) dependencies, but the Bazel bzlmod Go
dependency metadata is not updated to include them. This will likely break Bazel builds/tests that
rely on go_deps.from_file(go_mod = "//:go.mod") + use_repo(...) staying in sync with go.mod.
Code

go.mod[R41-42]

+	k8s.io/apimachinery v0.32.5
+	k8s.io/client-go v0.32.5
Evidence
PR adds new Go module dependencies (k8s.io/apimachinery, k8s.io/client-go, etc.) in go.mod,
which requires updating Bazel module metadata per the checklist. The repository’s MODULE.bazel
explicitly documents that bazel mod tidy should populate/sync the go_deps use_repo(...) list
based on go.mod, but that list currently contains no k8s.io_*/sigs.k8s.io_* repos.

AGENTS.md
go.mod[41-75]
MODULE.bazel[435-478]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New Go dependencies were added to `go.mod` (notably `k8s.io/*` and `sigs.k8s.io/*`), but the Bazel bzlmod Go dependency metadata has not been updated accordingly.
## Issue Context
This repo uses Bazel bzlmod + Gazelle (`go_deps.from_file(go_mod = &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;//:go.mod&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;)`) and a pinned `use_repo(...)` list that is expected to be kept in sync with `go.mod` (typically via `bazel mod tidy`). Without updating Bazel module metadata, Bazel builds/tests can fail due to missing external repos.
## Fix Focus Areas
- go.mod[41-75]
- MODULE.bazel[392-478]
- MODULE.bazel.lock[1-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Broken doc link path 🐞 Bug ✓ Correctness
Description
The new Trivy integration doc links to a contributor’s local /Users/... filesystem path, which will
be broken in the published docs site and for all other users.
Code

docs/docs/trivy-integration.md[38]

+Set the sidecar image tag in [serviceradar-trivy-sidecar.yaml](/Users/mfreeman/src/serviceradar/k8s/demo/base/serviceradar-trivy-sidecar.yaml) before deploy.
Evidence
The markdown link target is an absolute path on one developer’s machine, not a repo-relative or
site-relative URL.

docs/docs/trivy-integration.md[37-45]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Trivy integration doc contains a hard-coded absolute path to a local developer machine, so the link is broken for all other users.
## Issue Context
This is in a user-facing docs page and will ship as-is.
## Fix Focus Areas
- docs/docs/trivy-integration.md[37-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Readiness before informer sync 🐞 Bug ⛯ Reliability
Description
Readiness is based on watchingKindsGauge > 0, but that gauge is set before informer caches are
synced and is not cleared on cache sync failure—so /readyz can go green while the sidecar is not
actually watching/processing reports.
Code

go/pkg/trivysidecar/service.go[R60-66]

+func (s *Service) Ready() bool {
+	if s == nil || s.publisher == nil {
+		return false
+	}
+
+	return s.publisher.IsConnected() && s.metrics.watchingKindsGauge.Load() > 0
+}
Evidence
Ready() only checks NATS connectivity and watchingKindsGauge > 0. The gauge is set to
len(discoveredKinds) before WaitForCacheSync, and cache sync failures only log (no
error/rollback), leaving readiness potentially true even in a non-functional state.

go/pkg/trivysidecar/service.go[60-66]
go/pkg/trivysidecar/service.go[120-127]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`/readyz` can return ready even if informer caches never synced, because readiness relies on `watchingKindsGauge &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 0` which is set before cache sync and never cleared on sync failure.
## Issue Context
This can lead Kubernetes to route traffic/consider the pod healthy while it cannot actually observe/publish Trivy reports.
## Fix Focus Areas
- go/pkg/trivysidecar/service.go[60-66]
- go/pkg/trivysidecar/service.go[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended
4. managedFields not removed 🐞 Bug ➹ Performance
Description
Envelope building attempts to strip managedFields but deletes only a top-level key. This is
unlikely to remove metadata.managedFields, so published payloads may include large managedFields
blobs, increasing JetStream storage/bandwidth and publish latency.
Code

go/pkg/trivysidecar/envelope.go[R68-70]

+	reportBody := cloneMap(obj.Object)
+	delete(reportBody, "managedFields")
+
Evidence
The code clones the whole unstructured object map and deletes only reportBody["managedFields"].
The design explicitly calls out large payload size as a risk; failing to strip managedFields
exacerbates that risk.

go/pkg/trivysidecar/envelope.go[68-83]
openspec/changes/add-trivy-operator-nats-sidecar/design.md[78-86]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The current managedFields stripping deletes only a top-level key and likely does not remove the actual Kubernetes managed fields blob, leading to unnecessarily large NATS messages.
## Issue Context
Design notes already call out large payload size as an operational risk.
## Fix Focus Areas
- go/pkg/trivysidecar/envelope.go[68-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Deduper grows unbounded 🐞 Bug ⛯ Reliability
Description
The in-memory revision deduper stores every UID ever seen with no eviction/TTL. In long-lived
clusters or high churn, this can grow without bound and eventually cause memory pressure/OOM
restarts.
Code

go/pkg/trivysidecar/deduper.go[R6-13]

+type RevisionDeduper struct {
+	mu             sync.RWMutex
+	revisionsByUID map[string]string
+}
+
+func NewRevisionDeduper() *RevisionDeduper {
+	return &RevisionDeduper{revisionsByUID: make(map[string]string)}
+}
Evidence
RevisionDeduper is backed by a plain map keyed by UID; entries are added/updated but never
removed.

go/pkg/trivysidecar/deduper.go[5-31]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The deduper map can grow forever because UIDs are only added/updated and never evicted.
## Issue Context
Trivy reports can be high-cardinality (per workload/image/namespace) and churn over time.
## Fix Focus Areas
- go/pkg/trivysidecar/deduper.go[5-31]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Stream config unused🐞 Bug ✓ Correctness
Description
NATS_STREAM / NATSStreamName is loaded and stored on NATSPublisher, but it is never used
during publish. This is misleading configuration and removes the opportunity to validate/ensure the
expected stream is configured.
Code

go/pkg/trivysidecar/publisher.go[R57-85]

+	publisher := &NATSPublisher{
+		nc:         nc,
+		js:         js,
+		streamName: cfg.NATSStreamName,
+	}
+	publisher.connected.Store(nc.IsConnected())
+
+	return publisher, nil
+}
+
+func (p *NATSPublisher) Publish(ctx context.Context, subject string, payload []byte) error {
+	if p == nil || p.nc == nil || p.js == nil {
+		return errNATSJetStreamUnavailable
+	}
+
+	if p.nc.IsClosed() {
+		p.connected.Store(false)
+		return errNATSConnectionClosed
+	}
+
+	_, err := p.js.Publish(ctx, subject, payload)
+	if err != nil {
+		p.connected.Store(p.nc.IsConnected())
+		return fmt.Errorf("publish to %s: %w", subject, err)
+	}
+
+	p.connected.Store(true)
+	return nil
+}
Evidence
Config reads NATS_STREAM, NewNATSPublisher stores it in the struct, but Publish() calls
js.Publish(...) without referencing streamName and there is no startup validation that the
configured stream exists.

go/pkg/trivysidecar/config.go[59-63]
go/pkg/trivysidecar/config.go[84-86]
go/pkg/trivysidecar/publisher.go[57-61]
go/pkg/trivysidecar/publisher.go[67-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sidecar advertises `NATS_STREAM` configuration but does not use it, so users may believe changing it has an effect when it does not.
## Issue Context
At minimum this should be either enforced/validated or removed to avoid false configuration knobs.
## Fix Focus Areas
- go/pkg/trivysidecar/config.go[59-63]
- go/pkg/trivysidecar/config.go[84-86]
- go/pkg/trivysidecar/publisher.go[57-61]
- go/pkg/trivysidecar/publisher.go[67-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider
ⓘ The new review experience is currently in Beta. Learn more
Grey Divider

Qodo Logo

Imported GitHub PR comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2988#issuecomment-3992267565 Original created: 2026-03-03T16:44:58Z --- <h3>Code Review by Qodo</h3> <code>🐞 Bugs (5)</code> <code>📘 Rule violations (1)</code> <code>📎 Requirement gaps (0)</code> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <br/> <img src="https://www.qodo.ai/wp-content/uploads/2026/01/action-required.png" height="20" alt="Action required"> <details> <summary> 1. <b><i>MODULE.bazel</i></b> missing k8s repos <code>📘 Rule violation</code> <code>⛯ Reliability</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> ><b><i>go.mod</i></b> adds new Kubernetes (<b><i>k8s.io/*</i></b> and related) dependencies, but the Bazel bzlmod Go >dependency metadata is not updated to include them. This will likely break Bazel builds/tests that >rely on <b><i>go_deps.from_file(go_mod = &quot;//:go.mod&quot;)</i></b> + <b><i>use_repo(...)</i></b> staying in sync with <b><i>go.mod</i></b>. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[go.mod[R41-42]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-33ef32bf6c23acb95f5902d7097b7a1d5128ca061167ec0716715b0b9eeaa5f6R41-R42)</code> > >```diff >+ k8s.io/apimachinery v0.32.5 >+ k8s.io/client-go v0.32.5 >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> >PR adds new Go module dependencies (<b><i>k8s.io/apimachinery</i></b>, <b><i>k8s.io/client-go</i></b>, etc.) in <b><i>go.mod</i></b>, >which requires updating Bazel module metadata per the checklist. The repository’s <b><i>MODULE.bazel</i></b> >explicitly documents that <b><i>bazel mod tidy</i></b> should populate/sync the <b><i>go_deps</i></b> <b><i>use_repo(...)</i></b> list >based on <b><i>go.mod</i></b>, but that list currently contains no <b><i>k8s.io_*</i></b>/<b><i>sigs.k8s.io_*</i></b> repos. ></pre> > > <code>AGENTS.md</code> > <code>[go.mod[41-75]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go.mod/#L41-L75)</code> > <code>[MODULE.bazel[435-478]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/MODULE.bazel/#L435-L478)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >New Go dependencies were added to `go.mod` (notably `k8s.io/*` and `sigs.k8s.io/*`), but the Bazel bzlmod Go dependency metadata has not been updated accordingly. >## Issue Context >This repo uses Bazel bzlmod + Gazelle (`go_deps.from_file(go_mod = &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;//:go.mod&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;quot;)`) and a pinned `use_repo(...)` list that is expected to be kept in sync with `go.mod` (typically via `bazel mod tidy`). Without updating Bazel module metadata, Bazel builds/tests can fail due to missing external repos. >## Fix Focus Areas >- go.mod[41-75] >- MODULE.bazel[392-478] >- MODULE.bazel.lock[1-40] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <details> <summary> 2. Broken doc link path <code>🐞 Bug</code> <code>✓ Correctness</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> >The new Trivy integration doc links to a contributor’s local /Users/... filesystem path, which will >be broken in the published docs site and for all other users. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[docs/docs/trivy-integration.md[38]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-baf5892cf49794ff0c7ec234a20fc573f641feb379892ee58b7aa2ea9cf2dfbcR38-R38)</code> > >```diff >+Set the sidecar image tag in [serviceradar-trivy-sidecar.yaml](/Users/mfreeman/src/serviceradar/k8s/demo/base/serviceradar-trivy-sidecar.yaml) before deploy. >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> >The markdown link target is an absolute path on one developer’s machine, not a repo-relative or >site-relative URL. ></pre> > > <code>[docs/docs/trivy-integration.md[37-45]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/docs/docs/trivy-integration.md/#L37-L45)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >The Trivy integration doc contains a hard-coded absolute path to a local developer machine, so the link is broken for all other users. >## Issue Context >This is in a user-facing docs page and will ship as-is. >## Fix Focus Areas >- docs/docs/trivy-integration.md[37-40] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <details> <summary> 3. Readiness before informer sync <code>🐞 Bug</code> <code>⛯ Reliability</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> >Readiness is based on <b><i>watchingKindsGauge &gt; 0</i></b>, but that gauge is set before informer caches are >synced and is not cleared on cache sync failure—so <b><i>/readyz</i></b> can go green while the sidecar is not >actually watching/processing reports. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[go/pkg/trivysidecar/service.go[R60-66]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-af87504899cb539e93c74343b83b2bc22fc89f1a17da796f72097b9a524fe722R60-R66)</code> > >```diff >+func (s *Service) Ready() bool { >+ if s == nil || s.publisher == nil { >+ return false >+ } >+ >+ return s.publisher.IsConnected() && s.metrics.watchingKindsGauge.Load() > 0 >+} >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> ><b><i>Ready()</i></b> only checks NATS connectivity and <b><i>watchingKindsGauge &gt; 0</i></b>. The gauge is set to ><b><i>len(discoveredKinds)</i></b> before <b><i>WaitForCacheSync</i></b>, and cache sync failures only log (no >error/rollback), leaving readiness potentially true even in a non-functional state. ></pre> > > <code>[go/pkg/trivysidecar/service.go[60-66]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/service.go/#L60-L66)</code> > <code>[go/pkg/trivysidecar/service.go[120-127]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/service.go/#L120-L127)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >`/readyz` can return ready even if informer caches never synced, because readiness relies on `watchingKindsGauge &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; 0` which is set before cache sync and never cleared on sync failure. >## Issue Context >This can lead Kubernetes to route traffic/consider the pod healthy while it cannot actually observe/publish Trivy reports. >## Fix Focus Areas >- go/pkg/trivysidecar/service.go[60-66] >- go/pkg/trivysidecar/service.go[120-127] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <br/> <img src="https://www.qodo.ai/wp-content/uploads/2026/01/review-recommended.png" height="20" alt="Remediation recommended"> <details> <summary> 4. managedFields not removed <code>🐞 Bug</code> <code>➹ Performance</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> >Envelope building attempts to strip <b><i>managedFields</i></b> but deletes only a top-level key. This is >unlikely to remove <b><i>metadata.managedFields</i></b>, so published payloads may include large managedFields >blobs, increasing JetStream storage/bandwidth and publish latency. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[go/pkg/trivysidecar/envelope.go[R68-70]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-0935678e83f7e44d42884a84c30a13eea5b52c7b8901e1b28b0be6f5b9ec3478R68-R70)</code> > >```diff >+ reportBody := cloneMap(obj.Object) >+ delete(reportBody, "managedFields") >+ >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> >The code clones the whole unstructured object map and deletes only <b><i>reportBody[&quot;managedFields&quot;]</i></b>. >The design explicitly calls out large payload size as a risk; failing to strip managedFields >exacerbates that risk. ></pre> > > <code>[go/pkg/trivysidecar/envelope.go[68-83]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/envelope.go/#L68-L83)</code> > <code>[openspec/changes/add-trivy-operator-nats-sidecar/design.md[78-86]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/openspec/changes/add-trivy-operator-nats-sidecar/design.md/#L78-L86)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >The current managedFields stripping deletes only a top-level key and likely does not remove the actual Kubernetes managed fields blob, leading to unnecessarily large NATS messages. >## Issue Context >Design notes already call out large payload size as an operational risk. >## Fix Focus Areas >- go/pkg/trivysidecar/envelope.go[68-70] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <details> <summary> 5. Deduper grows unbounded <code>🐞 Bug</code> <code>⛯ Reliability</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> >The in-memory revision deduper stores every UID ever seen with no eviction/TTL. In long-lived >clusters or high churn, this can grow without bound and eventually cause memory pressure/OOM >restarts. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[go/pkg/trivysidecar/deduper.go[R6-13]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-d5875843780fbe278f52b9f00440b6206e794c1221b1ae2bda15b1254fafc4e5R6-R13)</code> > >```diff >+type RevisionDeduper struct { >+ mu sync.RWMutex >+ revisionsByUID map[string]string >+} >+ >+func NewRevisionDeduper() *RevisionDeduper { >+ return &RevisionDeduper{revisionsByUID: make(map[string]string)} >+} >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> ><b><i>RevisionDeduper</i></b> is backed by a plain map keyed by UID; entries are added/updated but never >removed. ></pre> > > <code>[go/pkg/trivysidecar/deduper.go[5-31]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/deduper.go/#L5-L31)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >The deduper map can grow forever because UIDs are only added/updated and never evicted. >## Issue Context >Trivy reports can be high-cardinality (per workload/image/namespace) and churn over time. >## Fix Focus Areas >- go/pkg/trivysidecar/deduper.go[5-31] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <details> <summary> 6. <s>Stream config unused</s> ☑ <code>🐞 Bug</code> <code>✓ Correctness</code></summary> <br/> > <details open> ><summary>Description</summary> ><br/> > ><pre> ><b><i>NATS_STREAM</i></b> / <b><i>NATSStreamName</i></b> is loaded and stored on <b><i>NATSPublisher</i></b>, but it is never used >during publish. This is misleading configuration and removes the opportunity to validate/ensure the >expected stream is configured. ></pre> ></details> > <details open> ><summary>Code</summary> ><br/> > ><code>[go/pkg/trivysidecar/publisher.go[R57-85]](https://github.com/carverauto/serviceradar/pull/2988/files#diff-eaecb20a3b0fe2b04f09d30dcded1515292f88ca51482bdfa4830c4828b37c42R57-R85)</code> > >```diff >+ publisher := &NATSPublisher{ >+ nc: nc, >+ js: js, >+ streamName: cfg.NATSStreamName, >+ } >+ publisher.connected.Store(nc.IsConnected()) >+ >+ return publisher, nil >+} >+ >+func (p *NATSPublisher) Publish(ctx context.Context, subject string, payload []byte) error { >+ if p == nil || p.nc == nil || p.js == nil { >+ return errNATSJetStreamUnavailable >+ } >+ >+ if p.nc.IsClosed() { >+ p.connected.Store(false) >+ return errNATSConnectionClosed >+ } >+ >+ _, err := p.js.Publish(ctx, subject, payload) >+ if err != nil { >+ p.connected.Store(p.nc.IsConnected()) >+ return fmt.Errorf("publish to %s: %w", subject, err) >+ } >+ >+ p.connected.Store(true) >+ return nil >+} >``` ></details> > <details > ><summary>Evidence</summary> ><br/> > ><pre> >Config reads <b><i>NATS_STREAM</i></b>, <b><i>NewNATSPublisher</i></b> stores it in the struct, but <b><i>Publish()</i></b> calls ><b><i>js.Publish(...)</i></b> without referencing <b><i>streamName</i></b> and there is no startup validation that the >configured stream exists. ></pre> > > <code>[go/pkg/trivysidecar/config.go[59-63]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/config.go/#L59-L63)</code> > <code>[go/pkg/trivysidecar/config.go[84-86]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/config.go/#L84-L86)</code> > <code>[go/pkg/trivysidecar/publisher.go[57-61]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/publisher.go/#L57-L61)</code> > <code>[go/pkg/trivysidecar/publisher.go[67-84]](https://github.com/carverauto/serviceradar/blob/f188a1f2bed36fa6439b8637fed7489e730e990c/go/pkg/trivysidecar/publisher.go/#L67-L84)</code> ></details> > <details> ><summary>Agent prompt</summary> ><br/> > >``` >The issue below was found during a code review. Follow the provided context and guidance below and implement a solution > >## Issue description >The sidecar advertises `NATS_STREAM` configuration but does not use it, so users may believe changing it has an effect when it does not. >## Issue Context >At minimum this should be either enforced/validated or removed to avoid false configuration knobs. >## Fix Focus Areas >- go/pkg/trivysidecar/config.go[59-63] >- go/pkg/trivysidecar/config.go[84-86] >- go/pkg/trivysidecar/publisher.go[57-61] >- go/pkg/trivysidecar/publisher.go[67-84] >``` > <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> ></details> <hr/> </details> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <pre>ⓘ The new review experience is currently in Beta. <a href="https://docs.qodo.ai/qodo-documentation/code-review">Learn more</a></pre> <img src="https://www.qodo.ai/wp-content/uploads/2025/11/light-grey-line.svg" height="10%" alt="Grey Divider"> <a href="https://www.qodo.ai"><img src="https://www.qodo.ai/wp-content/uploads/2025/03/qodo-logo.svg" width="80" alt="Qodo Logo"></a>
qodo-code-review[bot] commented 2026-03-03 16:49:13 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR review comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381746
Original created: 2026-03-03T16:49:13Z
Original path: go.mod
Original line: 42

Action required

1. module.bazel missing k8s repos 📘 Rule violation ⛯ Reliability

go.mod adds new Kubernetes (k8s.io/* and related) dependencies, but the Bazel bzlmod Go
dependency metadata is not updated to include them. This will likely break Bazel builds/tests that
rely on go_deps.from_file(go_mod = "//:go.mod") + use_repo(...) staying in sync with go.mod.
Agent Prompt
## Issue description
New Go dependencies were added to `go.mod` (notably `k8s.io/*` and `sigs.k8s.io/*`), but the Bazel bzlmod Go dependency metadata has not been updated accordingly.

## Issue Context
This repo uses Bazel bzlmod + Gazelle (`go_deps.from_file(go_mod = "//:go.mod")`) and a pinned `use_repo(...)` list that is expected to be kept in sync with `go.mod` (typically via `bazel mod tidy`). Without updating Bazel module metadata, Bazel builds/tests can fail due to missing external repos.

## Fix Focus Areas
- go.mod[41-75]
- MODULE.bazel[392-478]
- MODULE.bazel.lock[1-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Imported GitHub PR review comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381746 Original created: 2026-03-03T16:49:13Z Original path: go.mod Original line: 42 --- <img src="https://www.qodo.ai/wp-content/uploads/2025/12/v2-action-required.svg" height="20" alt="Action required"> 1\. <b><i>module.bazel</i></b> missing k8s repos <code>📘 Rule violation</code> <code>⛯ Reliability</code> <pre> <b><i>go.mod</i></b> adds new Kubernetes (<b><i>k8s.io/*</i></b> and related) dependencies, but the Bazel bzlmod Go dependency metadata is not updated to include them. This will likely break Bazel builds/tests that rely on <b><i>go_deps.from_file(go_mod = &quot;//:go.mod&quot;)</i></b> + <b><i>use_repo(...)</i></b> staying in sync with <b><i>go.mod</i></b>. </pre> <details> <summary><strong>Agent Prompt</strong></summary> ``` ## Issue description New Go dependencies were added to `go.mod` (notably `k8s.io/*` and `sigs.k8s.io/*`), but the Bazel bzlmod Go dependency metadata has not been updated accordingly. ## Issue Context This repo uses Bazel bzlmod + Gazelle (`go_deps.from_file(go_mod = "//:go.mod")`) and a pinned `use_repo(...)` list that is expected to be kept in sync with `go.mod` (typically via `bazel mod tidy`). Without updating Bazel module metadata, Bazel builds/tests can fail due to missing external repos. ## Fix Focus Areas - go.mod[41-75] - MODULE.bazel[392-478] - MODULE.bazel.lock[1-40] ``` <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> </details>
qodo-code-review[bot] commented 2026-03-03 16:49:13 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR review comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381750
Original created: 2026-03-03T16:49:13Z
Original path: docs/docs/trivy-integration.md
Original line: 38

Action required

2. Broken doc link path 🐞 Bug ✓ Correctness

The new Trivy integration doc links to a contributor’s local /Users/... filesystem path, which will
be broken in the published docs site and for all other users.
Agent Prompt
## Issue description
The Trivy integration doc contains a hard-coded absolute path to a local developer machine, so the link is broken for all other users.

## Issue Context
This is in a user-facing docs page and will ship as-is.

## Fix Focus Areas
- docs/docs/trivy-integration.md[37-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Imported GitHub PR review comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381750 Original created: 2026-03-03T16:49:13Z Original path: docs/docs/trivy-integration.md Original line: 38 --- <img src="https://www.qodo.ai/wp-content/uploads/2025/12/v2-action-required.svg" height="20" alt="Action required"> 2\. Broken doc link path <code>🐞 Bug</code> <code>✓ Correctness</code> <pre> The new Trivy integration doc links to a contributor’s local /Users/... filesystem path, which will be broken in the published docs site and for all other users. </pre> <details> <summary><strong>Agent Prompt</strong></summary> ``` ## Issue description The Trivy integration doc contains a hard-coded absolute path to a local developer machine, so the link is broken for all other users. ## Issue Context This is in a user-facing docs page and will ship as-is. ## Fix Focus Areas - docs/docs/trivy-integration.md[37-40] ``` <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> </details>
qodo-code-review[bot] commented 2026-03-03 16:49:13 +00:00 (Migrated from github.com)
Author
Owner

Imported GitHub PR review comment.

Original author: @qodo-code-review[bot]
Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381752
Original created: 2026-03-03T16:49:13Z
Original path: go/pkg/trivysidecar/service.go
Original line: 69

Action required

3. Readiness before informer sync 🐞 Bug ⛯ Reliability

Readiness is based on watchingKindsGauge > 0, but that gauge is set before informer caches are
synced and is not cleared on cache sync failure—so /readyz can go green while the sidecar is not
actually watching/processing reports.
Agent Prompt
## Issue description
`/readyz` can return ready even if informer caches never synced, because readiness relies on `watchingKindsGauge > 0` which is set before cache sync and never cleared on sync failure.

## Issue Context
This can lead Kubernetes to route traffic/consider the pod healthy while it cannot actually observe/publish Trivy reports.

## Fix Focus Areas
- go/pkg/trivysidecar/service.go[60-66]
- go/pkg/trivysidecar/service.go[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Imported GitHub PR review comment. Original author: @qodo-code-review[bot] Original URL: https://github.com/carverauto/serviceradar/pull/2988#discussion_r2879381752 Original created: 2026-03-03T16:49:13Z Original path: go/pkg/trivysidecar/service.go Original line: 69 --- <img src="https://www.qodo.ai/wp-content/uploads/2025/12/v2-action-required.svg" height="20" alt="Action required"> 3\. Readiness before informer sync <code>🐞 Bug</code> <code>⛯ Reliability</code> <pre> Readiness is based on <b><i>watchingKindsGauge &gt; 0</i></b>, but that gauge is set before informer caches are synced and is not cleared on cache sync failure—so <b><i>/readyz</i></b> can go green while the sidecar is not actually watching/processing reports. </pre> <details> <summary><strong>Agent Prompt</strong></summary> ``` ## Issue description `/readyz` can return ready even if informer caches never synced, because readiness relies on `watchingKindsGauge > 0` which is set before cache sync and never cleared on sync failure. ## Issue Context This can lead Kubernetes to route traffic/consider the pod healthy while it cannot actually observe/publish Trivy reports. ## Fix Focus Areas - go/pkg/trivysidecar/service.go[60-66] - go/pkg/trivysidecar/service.go[120-127] ``` <code>ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools</code> </details>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
carverauto/serviceradar!3012
No description provided.