Skip to content

feat(vulnerability): adapt API to v13s vulnerability priority model#452

Open
ybelMekk wants to merge 32 commits into
mainfrom
feat/cve-priority
Open

feat(vulnerability): adapt API to v13s vulnerability priority model#452
ybelMekk wants to merge 32 commits into
mainfrom
feat/cve-priority

Conversation

@ybelMekk

@ybelMekk ybelMekk commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Scope

  • Adapt API to the latest v13s priority model.
  • Keep GraphQL naming stable while aligning behavior.
  • Expose CVE signal fields on ImageVulnerability.

Changes

  • Bumped github.com/nais/v13s/pkg/api to the latest revision.
  • Switched summary filtering and mapping from risk-tier to priority fields.
  • Kept explicit CVEPriority <-> vulnerabilities.Priority mapping.
  • Updated summary and history top field handling (TopPriority).
  • Updated fake data to the new priority field names.
  • Limited issue checker alerts to immediate vulnerabilities.

Validation

  • mise run generate:graphql
  • go build ./...
  • go test ./internal/vulnerability/... -count=1

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.

Pull request overview

Updates the vulnerability domain in nais/api to match the latest v13s “risk-tier” model, while keeping GraphQL/API naming stable and exposing additional CVE signal data needed by the frontend.

Changes:

  • Adds EPSS/KEV/ransomware signals (and fix version) to ImageVulnerability, and introduces derived CVEPriority on CVE.
  • Extends sorting/filtering to support priority-based ordering for image vulnerabilities, CVEs, and workload vulnerability summaries.
  • Updates issue generation to use tier counts (ACT_NOW/HIGH_RISK) and introduces a new issue type for external-ingress workloads with ACT_NOW vulnerabilities.

Reviewed changes

Copilot reviewed 15 out of 19 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
internal/vulnerability/transform.go Maps new CVE signal fields and tier summary fields into API models.
internal/vulnerability/transform_test.go Adds unit tests for CVE priority derivation.
internal/vulnerability/sortfilter.go Registers new sort fields for priority/tier counts.
internal/vulnerability/queries.go Adds priority ordering for CVEs and hardens totalCount → int32 conversion.
internal/vulnerability/models.go Extends models with CVE priority enum + new fields (EPSS/KEV/etc).
internal/vulnerability/fake/fakedata.go Updates fake vulnerability summaries/findings to include tier and signal fields.
internal/issue/queries.go Adds conversion support for the new issue type details payload.
internal/issue/model.go Defines the new issue type and its details struct.
internal/issue/checker/workload_v13s.go Updates issue logic to use tier counts; adds external-ingress ACT_NOW issue emission.
internal/graph/schema/vulnerability.graphqls Extends public GraphQL schema with new fields/enums/sort options.
internal/graph/schema/issues.graphqls Adds the new issue type + GraphQL type.
internal/graph/issues.resolvers.go Wires resolvers for the new issue GraphQL type.
internal/graph/gengql/vulnerability.generated.go Regenerates gqlgen output for vulnerability schema changes.
internal/graph/gengql/schema.generated.go Regenerates gqlgen output for schema/type additions.
internal/graph/gengql/root_.generated.go Regenerates gqlgen resolver root + complexity updates.
internal/graph/gengql/issues.generated.go Regenerates gqlgen output for the new issue type.
integration_tests/issues_for_team.lua Updates expected message/severity for vulnerable image issues.
go.mod Bumps v13s API dependency to include risk-tier summary model updates.
go.sum Updates dependency checksums accordingly.
Files not reviewed (3)
  • internal/graph/gengql/issues.generated.go: Language not supported
  • internal/graph/gengql/schema.generated.go: Language not supported
  • internal/graph/gengql/vulnerability.generated.go: Language not supported

Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/vulnerability/transform_test.go Outdated
Comment thread internal/graph/schema/vulnerability.graphqls
Comment thread internal/graph/schema/vulnerability.graphqls
Comment thread internal/vulnerability/fake/fakedata.go Outdated
Comment thread internal/vulnerability/fake/fakedata.go Outdated
@ybelMekk ybelMekk force-pushed the feat/cve-priority branch from 3d8ae28 to c82b22d Compare June 8, 2026 10:27
@ybelMekk ybelMekk marked this pull request as ready for review June 8, 2026 10:28
@ybelMekk ybelMekk requested a review from a team as a code owner June 8, 2026 10:28
@ybelMekk ybelMekk changed the title fix(vulnerability): adapt API to v13s risk-tier model feat(vulnerability): adapt API to v13s risk-tier model Jun 8, 2026
@ybelMekk ybelMekk force-pushed the feat/cve-priority branch 2 times, most recently from a580717 to 82b803e Compare June 15, 2026 08:10

@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.

Nå er det veldig mange tall på f.eks. ImageVulnerabilitySummary. Skal noen av de gamle få en @deprecated? Hvordan skal brukerne vite hva som skal brukes og ikke?

Comment thread internal/issue/checker/workload_v13s.go Outdated
continue
}

externalIngresses := externalIngressesByWorkload[key]

@thokra-nav thokra-nav Jun 16, 2026

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.

externalIngressesByWorkload er brukket i dag, det ligger en const externalIngressClassName som ikke støtter det nye haproxy opplegget. Kan du se om vi kan utnytte application.GetIngressType eller lage en hjelpefunksjon i application-pakka som benytter ingressClassMapping fra den pakka?

Strengt talt ikke en must i denne PR-en, siden den ikke endrer på logikken for dette egentlig, men relatert. Dette kan også gjøres i en annen pr i etterkant :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

enig kan godt ta dette i en egen PR.

Comment thread internal/vulnerability/transform.go Outdated
@ybelMekk

ybelMekk commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Nå er det veldig mange tall på f.eks. ImageVulnerabilitySummary. Skal noen av de gamle få en @deprecated? Hvordan skal brukerne vite hva som skal brukes og ikke?

Godt poeng 👍 Dette er ikke ment som “gamle vs nye” tall, men ulike dimensjoner

  • critical/high/medium/low/unassigned = alvorlighetsgrad (CVSS-fordeling)
  • priorityActNow/high/elevated/monitor + topVulnerabilityPriority = operasjonell prioritet (hva bør håndteres først)
  • highEpssCount = ekstra risikosignaler

@ybelMekk ybelMekk changed the title feat(vulnerability): adapt API to v13s risk-tier model feat(vulnerability): adapt API to v13s vulnerability priority model Jun 17, 2026
@ybelMekk ybelMekk force-pushed the feat/cve-priority branch from 4277e04 to fd27b92 Compare June 19, 2026 07:17
@christeredvartsen

christeredvartsen commented Jun 22, 2026

Copy link
Copy Markdown
Member

Enig med @thokra-nav her, det blir veldig mange int / float felt direkte på den ImageVulnerabilitySummary typen. Er det noen måte å gruppere dem på så ikke alle trenger å ligge samlet? Er det sånn at alle feltene brukes for å kalkulere noe, eller brukes et subsett for å kalkulere noe, og et annet subsett for å kalkulere noe annet?

Det hadde vært fint å kunne markere "det gamle" med @deprecated om vi ønsker at folk skal bruke "det nye" i stedet.

Comment thread internal/issue/checker/workload_v13s.go Outdated
Severity: issue.SeverityCritical,
Message: fmt.Sprintf(
"Workload with external ingresses %s has a vulnerability with CVSS score %.1f",
"Workload with external ingresses %s has %d act_now vulnerabilities",

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.

Kan vi gjøre denne meldinga bedre for sluttbrukerne? act_now ser ut som en enum verdi. Kan det heller være noe Workload '%s' (exposed via external ingress) has %d urgent vulnerabilities..

Act now er et vanskelig uttrykk å bruke i sånne meldinger som det der, er nivå-begrepene de vi faktisk ønsker å bruke, eller kan vi vurdere litt andre nivåer?
ActNow, High, Elevated, Monitor er det jeg forstår er den nye aksen, men hva er forskjell på High og Elevated? ActNow høres litt ut som en forklaring på "Critical", ikke selve verdinavnet

@ybelMekk ybelMekk Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Takk for gode innspill 🙌 @christeredvartsen
Enig i at enum navn ikke bør eksponeres direkte til sluttbruker. Vi kan bruke mer lesbar tekst i bruker meldinger, og beholde ACT_NOW/HIGH/ELEVATED/MONITOR som interne verdier i APIet?
Hvis dere har bedre forslag til ordlyd er jeg helt åpen for det. Dette er foreløpig basert på egne vurderinger, så jeg ønsker gjerne innspill. Målet har også vært å unngå å bryte eksisterende verdier og klienter.

Nivåene i v13s betyr i dag:

  • ACT_NOW: has_kev_entry = true (kjennt utnyttet “in the wild” via KEV).
  • HIGH: ikke KEV, men known_ransomware_use = true eller epss_percentile >= 0.90 (høy relativ sannsynlighet for utnyttelse innen 30 dager).
  • ELEVATED: ikke KEV/HIGH, men severity in (CRITICAL, HIGH) og epss_percentile >= 0.50.
  • MONITOR: alt annet.

@thokra-nav thokra-nav Jun 24, 2026

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.

Målet har også vært å unngå å bryte eksisterende verdier og klienter.

Vi skal ikke være redd for å bruke @deprecated. De fleste som har brukt api-et til nå er kjent med at det kan komme endringer. Så lenge vi bruker @deprecated og streber etter å opprettholde funksjonaliteten som den er i dag, i en periode, så går det bra.


Problemet som jeg ser det er at vi skal støtte både den gamle og nye måten å sortere på, som skaper litt forvirring på hva som hører sammen og ikke.

Typen ImageVulnerabilitySummary inneholder etter denne pr-en 14 felter, hvor 11 er av typen Int!. Det er to grupper av ints som jeg antar summerer til den samme totalverdien i total feltet, hvor den ene har 4 felter og priority prefiks og den andre 5 felter og er uten prefiks.

Så med nais-hatten på: Burde vi ikke standardisert på en måte å presentere det på, sånn at det er forutsigbart hvilke tall vi bruker og at de er sammenlignbare? F.eks. hvis vi presenterer tallene kun på den nye prioriteringsmåten, så kan brukerne fortsatt lage en oversikt over severity ved å iterere selv over sårbarhetene. Men jeg antar det nye er en bedre måte å presentere det på siden vi implementerer det.

Tilbake med API-hatten:
Alternativt: kan vi endre litt på typen til å kanskje tydeliggjøre oppsplittingen noe mer?

f.eks.

type ImageVulnerabilitySummary {
	"Total number of vulnerabilities."
	total: Int!

	"Risk score of the image."
	riskScore: Int!

	"Vulnerability counts by priority."
	countsByPriority: ImageVulnerabilitySummaryCountsByPriority!

	"Vulnerability counts by severity."
	countsBySeverity: ImageVulnerabilitySummaryCountsBySeverity!

	"Timestamp of the last update of the vulnerability summary."
	lastUpdated: Time

	"""
	When set, the vulnerability counts are sourced from this older image tag because
	no summary exists yet for the requested tag (e.g. a newly deployed image that is
	still being scanned). The value is the tag the stale data originates from.
	"""
	staleImageTag: String
}

type ImageVulnerabilitySummaryCountsBySeverity {
	low: Int!
	medium: Int!
	high: Int!
	critical: Int!
	unassigned: Int!
}

type ImageVulnerabilitySummaryCountsByPriority {
	low: Int!
	medium: Int!
	high: Int!
	critical: Int!
}

Da kan vi gjenbruke ordene som jeg føler skiller det tydeligere enn f.eks. high og elevated, (navn på typer og felter er kun som eksempel). Går vi denne veien så må vi også legge til @deprecated på de gamle feltene som jeg fjernet i eksempelet.

Eller f.eks. noe sånn?

type ImageVulnerabilitySummary {
	"Total number of vulnerabilities."
	total: Int!

	"Risk score of the image."
	riskScore: Int!

	"Vulnerability counts by priority."
	counts(type: ImageVulnerabilitySummaryCountsType = PRIORITY): ImageVulnerabilitySummaryCounts!

	"Timestamp of the last update of the vulnerability summary."
	lastUpdated: Time

	"""
	When set, the vulnerability counts are sourced from this older image tag because
	no summary exists yet for the requested tag (e.g. a newly deployed image that is
	still being scanned). The value is the tag the stale data originates from.
	"""
	staleImageTag: String
}

type ImageVulnerabilitySummaryCounts {
	low: Int!
	medium: Int!
	high: Int!
	critical: Int!
	unassigned: Int!
}

enum ImageVulnerabilitySummaryCountsType {
	PRIORITY
	SEVERITY
}

Og en annen ting, dette feltet trenger vi kanskje ikke siden det lett kan utledes fra tallene hvis klienten ønsker det?

topVulnerabilityPriority: CVEPriority

Comment thread internal/graph/schema/issues.graphqls
ybelMekk added 12 commits June 26, 2026 09:21
…checker

- Add priorityActNow, priorityHigh, priorityElevated, priorityMonitor fields to ImageVulnerabilitySummary model
- Expose priority fields in vulnerability.graphqls and GraphQL resolvers
- Add VULNERABILITY_PRIORITY_ACT_NOW and VULNERABILITY_PRIORITY_HIGH sort fields
- Add ExternalIngressActNowVulnerabilityIssue type and issue checker
- Map priority signals (EPSS, KEV, ransomware) via VulnerabilityPrioritySignals
- Bump golang.org/x/net to v0.55.0 and golang.org/x/crypto to v0.52.0 to fix known vulnerabilities
- Update v13s/pkg/api to v0.0.0-20260525171357-13563f32226d (priority_elevated, priority_monitor support)
…; fix ExternalIngressActNow resolver stubs; add priority sort fields
@ybelMekk ybelMekk force-pushed the feat/cve-priority branch from 8dc6401 to 7576a8d Compare June 26, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants