Skip to content

feat(vulnerability): implement workload internet exposure resolution and priority handling - #510

Open
ybelMekk wants to merge 26 commits into
mainfrom
fix/priority
Open

ybelMekk wants to merge 26 commits into
mainfrom
fix/priority

Conversation

@ybelMekk

@ybelMekk ybelMekk commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

This PR makes URGENT an explicitly workload-contextual priority. URGENT requires confirmed workload internet exposure, which cannot be determined at image or summary scope, so image/summary responses now expose the raw CISA KEV count through a new knownExploited field instead of overloading urgent.

GraphQL schema changes (additive, non-breaking)

ImageVulnerabilitySummaryCountsByPriority:

  • Added knownExploited: Int!, the number of vulnerabilities with a CISA Known Exploited Vulnerabilities (KEV) entry.
  • Kept urgent: Int!, now @deprecated and hardcoded to 0 at image and summary scope. It is retained for backwards compatibility so existing consumers do not break. Clients should migrate to knownExploited.

VULNERABILITY_PRIORITY_URGENT as an order field is @deprecated. It is backed by a count that is always 0, so ordering by it has no effect and falls back to a stable name sort. The enum value is removed entirely in the stacked follow-up #513, so this PR only deprecates it.

Priority filtering

  • TeamVulnerabilitySummaryFilter.priorities and ImageVulnerabilityFilter.priorities accept a list, replacing the previous single-value filter.
  • TeamVulnerabilitySummaryFilter.priority is kept and @deprecated. It is mapped internally to a single-element priorities list, so existing clients keep working. If both are set, priorities wins.
  • Passing URGENT through either field returns an error rather than silently matching nothing, since the value is not resolvable at these scopes. This is a behaviour change for any client currently filtering on URGENT.

Workload internet exposure

New internal/vulnerability/exposure.go resolves a workload's internet exposure from its ingress class names into TRUE, FALSE or UNKNOWN. The issue checker uses this to emit external-ingress urgent/critical vulnerability issues only for workloads with confirmed external exposure and a non-zero KEV count.

An earlier iteration added a ResolvePriority helper. It ended up with no production caller once the issue checker gated directly on exposure, so it was removed rather than left as dead logic.

Tests

  • Integration tests in integration_tests/vulnerabilities.lua query both fields, asserting urgent = 0 and a non-null knownExploited, which locks in the deprecation contract.
  • Unit tests cover exposure resolution, priority filter validation, the deprecated priority to priorities mapping, and the summary transform.

Dependencies

Bumps github.com/nais/v13s/pkg/api for the KEV count, plus routine updates to cloud.google.com/go/*, google.golang.org/api, google.golang.org/genproto and google.golang.org/grpc.

Migration note for consumers

Replace countsByPriority.urgent with countsByPriority.knownExploited, and filter.priority with filter.priorities. Stop filtering and ordering by URGENT at image and summary scope. No field is removed in this PR, so no consumer breaks on deploy.

Follow-up

#513 is stacked on this branch and removes the deprecated VULNERABILITY_PRIORITY_URGENT order-by enum value. Merge this PR first.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The deprecated VULNERABILITY_PRIORITY_URGENT ordering behavior is inconsistent with the schema/documentation and the exposed data (urgent counts always 0 at summary/image scope).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates vulnerability priority semantics so that “URGENT” becomes workload-contextual (tied to internet exposure), while “known-exploited” (KEV count) is used for workload-level issue emission; it also updates GraphQL filters to accept multiple priorities and clarifies that URGENT is never reported at image/summary scope.

Changes:

  • Updated summary/image vulnerability transforms to always return urgent = 0 at image/summary scope and removed ACT_NOW↔URGENT mapping.
  • Added workload internet exposure resolution and a priority resolver to gate URGENT behavior based on KEV + confirmed external exposure.
  • Updated GraphQL inputs/resolvers/tests to support priorities: [CVEPriority!] and refreshed messaging and dependency versions.
File summaries
File Description
internal/workload/application/ingress_class_mapping.go Exposes ingress class → ingress type classification helper for reuse.
internal/vulnerability/transform.go Stops surfacing URGENT at image/summary scope; adds list-priority mapping helper.
internal/vulnerability/transform_test.go Updates tests for KEV/urgent behavior and adds priority-list mapping tests.
internal/vulnerability/sortfilter.go Adjusts order-by field mapping for workload summaries (incl. URGENT).
internal/vulnerability/queries.go Updates summary/image list queries to use list-based priority filtering.
internal/vulnerability/priority.go Introduces centralized priority resolution (KEV + exposure-based escalation).
internal/vulnerability/priority_test.go Adds coverage for priority resolution rules and reason flags.
internal/vulnerability/models.go Changes filters to Priorities []CVEPriority and adds priorities to image filter model.
internal/vulnerability/fake/v13s.go Updates fake v13s time-series data to new priority fields/expectations.
internal/vulnerability/fake/fakedata.go Updates fake workload summaries to align with new top priority expectations.
internal/vulnerability/exposure.go Adds workload internet exposure resolver from ingress class names.
internal/vulnerability/exposure_test.go Adds tests for exposure resolution across ingress-class combinations.
internal/issue/checker/workload_v13s.go Gates urgent ingress issue emission on KEV count + confirmed external exposure; updates messaging.
internal/issue/checker/workload_v13s_test.go Updates tests to use KevCount and validates urgent gating scenarios.
internal/graph/schema/vulnerability.graphqls Updates filter inputs to list priorities and deprecates URGENT-at-summary/image fields with clarifications.
internal/graph/gengql/vulnerability.generated.go Regenerates gqlgen unmarshalling/marshalling for list-priority inputs.
internal/graph/gengql/root_.generated.go Regenerates schema snapshot with updated inputs/deprecations.
integration_tests/vulnerabilities.lua Updates integration expectations for urgent = 0 at summary scope.
integration_tests/issues_for_team.lua Updates issue message expectations to “known-exploited vulnerabilities”.
go.mod Bumps v13s API module and golang.org/x/crypto versions.
go.sum Updates dependency checksums for the bumped modules.
Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file
  • Files reviewed: 19/21 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/vulnerability/sortfilter.go Outdated
Comment thread internal/graph/schema/vulnerability.graphqls

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It introduces public GraphQL API behavior changes plus non-trivial vulnerability/issue semantics updates and dependency bumps that warrant a final human review of compatibility and domain correctness.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file
  • Files reviewed: 19/21 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ybelMekk
ybelMekk force-pushed the fix/priority branch 2 times, most recently from 886dd61 to d3985ff Compare September 8, 2026 11:32
@ybelMekk
ybelMekk requested a lite review from Copilot September 8, 2026 11:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The GraphQL schema removes an existing public field (urgent) rather than deprecating it, which is a breaking change for API consumers.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file
  • Files reviewed: 20/22 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread internal/graph/schema/vulnerability.graphqls

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The GraphQL schema description for the deprecated urgent field is misleading (it claims urgent is “known-exploited” while it always returns 0 at image/summary scope).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file
  • Files reviewed: 20/22 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread internal/graph/schema/vulnerability.graphqls Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are correctness/maintainability issues in the updated urgent gating logic and a schema documentation mismatch in generated GraphQL output that should be fixed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

internal/issue/checker/workload_v13s.go:227

  • ResolvePriority is invoked with hardcoded values (HIGH + hasKevEntry=true + unassigned severity + epssKnown=false), which makes the result depend only on exposure. This is misleading for readers and will silently diverge if ResolvePriority logic changes; prefer checking exposure directly here (or pass real inputs).
  • Files reviewed: 20/22 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread internal/graph/gengql/root_.generated.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes public GraphQL contract semantics around vulnerability priority and updates issue emission logic + dependency versions, which merits final human verification of client impact and behavior.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file
  • Files reviewed: 20/22 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread internal/vulnerability/priority.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

It introduces a breaking GraphQL schema change by removing the priority input field (replaced by priorities) without an in-schema deprecation/migration path.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Files not reviewed (1)

  • internal/graph/gengql/vulnerability.generated.go: Generated file

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

internal/graph/schema/vulnerability.graphqls:350

  • The PR description says the urgent priority field was replaced everywhere by knownExploited, but the schema still exposes urgent (deprecated, always 0) for backwards compatibility and tests still query it. Consider updating the PR description to reflect the actual approach (deprecated urgent + new knownExploited) so reviewers and release notes are accurate.
  • Files reviewed: 18/20 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread internal/graph/schema/vulnerability.graphqls
@ybelMekk
ybelMekk force-pushed the fix/priority branch 3 times, most recently from 2806538 to c765ba0 Compare September 14, 2026 22:18
ybelMekk and others added 22 commits September 24, 2026 14:07
…xploited

Bump github.com/nais/v13s/pkg/api to bd6d431 (renames Summary.ActNow to
Summary.KevCount, wire-compatible). Remove the always-zero
countsByPriority.urgent counter and expose a proper knownExploited count
sourced from KevCount instead. Keep severity ints and hasSBOM as
deprecated-but-present fields.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The urgent field is now deprecated and documented as always 0, but its description still says "Known-exploited vulnerabilities that require immediate action", which is misleading for API consumers. Update the field description to reflect that it is kept only for backwards compatibility and always returns 0 at image/summary scope.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…d monitor priorities in TeamVulnerabilitySummary
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment thread internal/graph/schema/vulnerability.graphqls Outdated
Comment on lines +513 to +514
"Risk and threat intelligence signals used to prioritize the image vulnerability."
riskAssessment: VulnerabilityRiskAssessment!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ybelMekk Hvorfor bruker vi ikke @deprecated her?

"Whether the CVE is known to be used in ransomware attacks."
knownRansomwareUse: Boolean!
"Risk and threat intelligence signals used to prioritize the CVE."
riskAssessment: VulnerabilityRiskAssessment!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Og her? @ybelMekk

@ybelMekk

Copy link
Copy Markdown
Contributor Author

ok, då har jeg sett på disse :)

@ybelMekk

Copy link
Copy Markdown
Contributor Author

Jeg oppdaterer å fikser på den oppfølgnings branch/ ryddig av ting etterpå

@thokra-nav thokra-nav left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants