Skip to content

Add validity_check support to vulnerabilities GraphQL

What does this MR do and why?

Add token_status support to vulnerabilities GraphQL

References

Screenshots or screen recordings

Type Project Group Not allowed
Vulnerabilities Screenshot_2025-10-03_at_17.48.17 Screenshot_2025-10-03_at_17.47.47 Screenshot_2025-10-03_at_18.04.49
Vulnerability Severity Counts Screenshot_2025-10-03_at_18.06.56 Screenshot_2025-10-03_at_18.07.35 Screenshot_2025-10-03_at_18.08.30

Refresh

Before After
Screenshot_2025-10-06_at_17.29.37 Screenshot_2025-10-06_at_17.30.02

How to set up and validate locally

  1. Set up Elasticsearch and enable SaaS mode



  1. Run GraphQL queries to verify vulnerability data

    Once your environment is configured, you can run the following GraphQL queries to verify vulnerability data filtered by validity check status.

Vulnerabilities (nodes) GraphQL query
query {
  # Project level
  project(fullPath: "gitlab-org/verify-validity-refresh-check") {
    id
    name
    fullPath

    active: vulnerabilities(validityCheck: [ACTIVE]) {
      nodes { id title severity }
    }
    inactive: vulnerabilities(validityCheck: [INACTIVE]) {
      nodes { id title severity }
    }
    unknown: vulnerabilities(validityCheck: [UNKNOWN]) {
      nodes { id title severity }
    }
  }

  # Group level
  group(fullPath: "gitlab-org") {
    id
    name
    fullPath

    active: vulnerabilities(validityCheck: [ACTIVE]) {
      nodes { id title severity }
    }
    inactive: vulnerabilities(validityCheck: [INACTIVE]) {
      nodes { id title severity }
    }
    unknown: vulnerabilities(validityCheck: [UNKNOWN]) {
      nodes { id title severity }
    }
  }

  # Instance level
  instanceSecurityDashboard {
    active: vulnerabilities(validityCheck: [ACTIVE]) {
      nodes { id title severity }
    }
    inactive: vulnerabilities(validityCheck: [INACTIVE]) {
      nodes { id title severity }
    }
    unknown: vulnerabilities(validityCheck: [UNKNOWN]) {
      nodes { id title severity }
    }
  }
}
Vulnerability Severity Counts
query {
  # Project level
  project(fullPath: "gitlab-org/verify-validity-refresh-check") {
    id
    name
    fullPath

    activeCount: vulnerabilitySeveritiesCount(validityCheck: [ACTIVE]) {
      critical high medium low unknown info
    }
    inactiveCount: vulnerabilitySeveritiesCount(validityCheck: [INACTIVE]) {
      critical high medium low unknown info
    }
    unknownCount: vulnerabilitySeveritiesCount(validityCheck: [UNKNOWN]) {
      critical high medium low unknown info
    }
  }

  # Group level
  group(fullPath: "gitlab-org") {
    id
    name
    fullPath

    activeCount: vulnerabilitySeveritiesCount(validityCheck: [ACTIVE]) {
      critical high medium low unknown info
    }
    inactiveCount: vulnerabilitySeveritiesCount(validityCheck: [INACTIVE]) {
      critical high medium low unknown info
    }
    unknownCount: vulnerabilitySeveritiesCount(validityCheck: [UNKNOWN]) {
      critical high medium low unknown info
    }
  }

  # Instance level
  instanceSecurityDashboard {
    activeCount: vulnerabilitySeveritiesCount(validityCheck: [ACTIVE]) {
      critical high medium low unknown info
    }
    inactiveCount: vulnerabilitySeveritiesCount(validityCheck: [INACTIVE]) {
      critical high medium low unknown info
    }
    unknownCount: vulnerabilitySeveritiesCount(validityCheck: [UNKNOWN]) {
      critical high medium low unknown info
    }
  }
}


  1. Refresh test
  • Enable the required feature flag

    secret_detection_validity_checks_refresh_token
  • Follow Simulate GitLab SaaS mode steps

  • Retrieve the last vulnerability and finding

    Run a successful pipeline on the imported project, then retrieve the last finding

    finding = Vulnerability.last.finding

    This fetches the latest vulnerability and its associated finding record.

  • Manually set the token status to active

    finding_token_status = Vulnerabilities::FindingTokenStatus.find_or_initialize_by(
      vulnerability_occurrence_id: finding.id
    )
    
    # Run until fts.reload has status: "active"
    finding_token_status.update!(
      status: :active,
      project_id: finding.project_id
    )
    finding_token_status.reload

    This ensures a Vulnerabilities::FindingTokenStatus record exists and sets it as active.

  • Sync the finding into Elasticsearch (if needed)

    ::Vulnerabilities::EsHelper.sync_elasticsearch(finding.vulnerability_id)
    Elastic::ProcessBookkeepingService.new.execute # until => [0, 0]

    This updates the vulnerability record in Elasticsearch with the current database state.

Query the token status
query {
  vulnerability(id: "gid://gitlab/Vulnerability/544") {
    id
    title
    findingTokenStatus {
      status
    }
  }
}
GraphQL mutation: Refresh the finding token status
mutation {
  refreshFindingTokenStatus(input: { vulnerabilityId: "gid://gitlab/Vulnerability/544" }) {
    errors
    findingTokenStatus {
      status
    }
  }
}

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Ugo Nnanna Okeadu

Merge request reports

Loading