JustScan Documentation
Operate JustScan

CVE Intelligence

Monitor CVE changes, current posture, and the background intelligence worker.

CVE Intelligence keeps the original scanner result and the current vulnerability assessment separate. A completed scan retains the evidence that was available at scan time, while later CVE feed changes can update the derived posture of the retained finding.

Authenticated users can investigate this information in the Vulnerability Knowledge Base (/vulnkb), which is now the CVE Explorer. Administrators also have the worker and source-event view at Administration → CVE Intelligence (/admin/vulnerability-intelligence). CVE Intelligence is a delta feed processor, not a full re-fetch of every entry in the Vulnerability Knowledge Base.

User-facing CVE Explorer

Open /vulnkb to search and filter CVEs. Search, severity, CVSS, exploit, publication, and page state are kept in the URL, so a filtered result can be bookmarked or shared with another authenticated user.

Select a CVE to open its dedicated explorer page. The page has four tabs:

  • Summary shows CVE metadata, current severity and CVSS, the latest recorded change, and normalized references.
  • Change history shows a compact timeline. Older events are loaded with cursor pagination as you reach the bottom of the scroll area; large arrays and objects stay collapsed until opened.
  • Affected findings shows packages and versions from completed scans that the current user is allowed to access. It includes the current posture and scoped counts for changed findings, rescan-needed findings, and available fixes.
  • References lists normalized external links from the CVE record.

All authenticated users can read normalized CVE history. Provider payloads, processing errors, raw source evidence, and installation-wide impact counts remain administrator-only. Finding, package, scan, and posture data is filtered by ownership, organization membership, or explicit scan sharing; a CVE page never grants access to a scan that the user could not open separately. Exposure is limited to completed scans.

The explorer informs users when a fresh scan is advisable, but it does not start rescans automatically.

What the feature does

When a scan completes, JustScan stores the scanner's vulnerability data as immutable scan-time intelligence. The current posture is derived separately and can include a newer feed version, CVE state, severity, CVSS data, affected ranges, fixed versions, exploit signals, and a reason for the current state.

The background worker then:

  1. Reads NVD CVE change history from the last successful checkpoint to the current time.
  2. Persists each normalized source event, including its before/after values and raw provider payload.
  3. Fetches the current official CVE record and current NVD CVE record for each changed CVE.
  4. Re-evaluates matching historical findings and appends posture events when their derived assessment changes.
  5. Advances the checkpoint only after the event has been processed successfully.

The original finding, scan-time evidence, and original scan compliance result are not rewritten. If the available source data is incomplete, conflicting, or cannot identify the affected package reliably, JustScan uses needs_rescan instead of guessing that a finding is safe.

Admin workflow

Open /admin/vulnerability-intelligence to inspect the worker and the source timeline.

Sync status

The page shows:

  • whether the worker is disabled, healthy, running, or needs attention;
  • the last successful checkpoint and the next retry time;
  • the active phase, such as fetching history, processing events, or finalizing;
  • completed and total events, failed events, unique CVEs, the current CVE, and the last progress update;
  • recent scheduled and manually queued sync runs.

Use Run sync now to queue one background run. The request returns immediately. While a run is active, use Stop sync to request a graceful cancellation; events already persisted and the verified cursor remain available. A second manual request while a run is active is rejected, and a disabled worker cannot be queued from the page. If the backend stops, its next startup and the history endpoint reconcile orphaned running rows as interrupted failures instead of leaving them running forever.

Change history

The timeline shows normalized CVE change events with the source, event type, observed time, impacted findings, and findings that require a rescan. Use the search and event-type filters to narrow the list.

Large before/after arrays and objects are collapsed into compact summaries. Expand a value when the detail is needed. The timeline is bounded with a scroll shadow and loads older events as you reach the bottom, so a large history does not expand the whole page at once.

New source events can appear while the worker is still running. Persistence of the raw event happens before current-record enrichment, so the timeline may receive data before the corresponding posture update has finished.

Scan Details triage

The Scan Details vulnerability table keeps the full history out of the row layout. Instead, the Signals area displays a quiet intelligence indicator when the current posture differs from the scan-time snapshot:

IndicatorMeaning
Severity increasedCurrent severity is higher than the scan-time assessment.
Fix availableCurrent intelligence identifies a fixed version.
Rescan neededThe source evidence is incomplete, conflicting, or cannot be matched confidently.
No longer affectedCurrent package applicability no longer matches the finding.
Disputed / rejectedThe current CVE state is disputed or rejected.

Unchanged findings remain visually quiet. Use the Intelligence filter in the table's filter and sort popover to show all findings, changed findings, findings needing a rescan, fix-available findings, findings that are no longer affected, or disputed/rejected findings. The Summary tab of a finding shows scan-time versus current intelligence and links to the CVE Explorer. The finding's History tab remains the place for the full per-finding posture history.

Intelligence-aware policy impact

When current CVE intelligence changes a finding from a completed scan, JustScan calculates a separate current policy projection. The original scan verdict, compliance_results, compliance history, vulnerability row, and scan status remain immutable for auditability. The projection is evaluated only for policies that were assigned to that scan and only for organizations the viewer is authorized to access.

The Scan Details page displays a banner when the current projection materially differs from the historical policy result:

BannerMeaning
Resolved by current intelligence — original scan remains failedA rejected or not-affected CVE is excluded from the current evaluation and the policy now passes. The historical scan still failed.
Still failing under current intelligenceCurrent severity, CVSS, fixed-version, or applicability data changed, but the policy still fails.
New policy failure caused by current intelligenceA later intelligence update causes a policy that originally passed to fail under the current projection.
Needs validation — rescan requiredIntelligence is disputed, unknown, incomplete, or conflicting. The original finding is retained and the failure is never cleared automatically.

The banner lists affected policies, the previous and current status, the changed CVEs, and the reason. Rescan now is shown only to users with scan write permission and reuses the normal rescan action; JustScan never starts a rescan automatically. A new completed scan is the only authoritative way to replace the historical compliance result.

Current evaluation preserves existing suppression behavior and Xray policy rules. A fixed version can resolve a require_fix rule, and a current severity or CVSS change can alter threshold rules, but none of these changes rewrite the scan-time data. Authorized viewers can see the banner without being notification recipients.

For notifications, JustScan emits one deduplicated intelligence_policy_impact event per scan, impact, and posture-change batch. Personal scans notify the personal scan owner. Organization-owned scans notify administrators and owners of organizations whose assigned policies were affected. Notification rules can match the direct user target, impact (resolved, new_failure, still_failed, or needs_validation), historical status, and current status. Recipients should still run a confirming scan before treating a resolved projection as a passing release decision.

Scheduling and checkpoints

The relevant backend settings are:

SettingDefaultBehavior
vuln_kb.cve_history_enabledtrueStarts the background CVE change-history worker.
vuln_kb.cve_history_interval_minutes120Delay between scheduled sync attempts after the current attempt finishes.
vuln_kb.cve_history_initial_lookback_hours24Lookback used when the source checkpoint does not exist; capped at 120 days.
vuln_kb.nvd_api_keyemptyOptional key sent to NVD for CVE history and CVE requests.

The checkpoint is stored in PostgreSQL and contains the last processed observation time and source event ID. It is advanced only after successful processing, which makes the feed resumable. A failed fetch or posture update leaves the last verified posture unchanged and schedules a retry.

The worker permits only one active run. The scheduler starts the next interval after the current attempt completes, so a long-running attempt does not overlap with another attempt. This protects the checkpoint from concurrent advancement, but a large backlog can make the next scheduled run start later than its nominal two-hour interval.

Scale and first-run guidance

The number of rows in vuln_kb is not the number of CVEs fetched on every sync. Normal runs follow the change cursor and process only CVEs that changed since the previous successful checkpoint. Scans also use local scanner and KB data; they do not make one NVD request per KB entry.

The expensive case is a new or deliberately widened checkpoint. The current worker spaces upstream requests by six seconds and retrieves two current records for each unique changed CVE. Duplicate history events for the same CVE share one current snapshot during a run, but thousands of distinct CVEs can still create a large backlog. Keep the initial lookback bounded, monitor the live progress card, and avoid repeatedly queuing manual runs while the backlog is being drained.

For a production rollout, verify that the database migrations have completed before enabling the worker. Start with the default 24-hour lookback unless a larger replay window is intentional, and watch the sync activity and backend logs until the first successful checkpoint is recorded.

API surface

These admin endpoints require an authenticated administrator session:

MethodEndpointPurpose
GET/api/v1/admin/vulnerability-intelligence/historyReturns the change timeline, checkpoint, recent runs, feature settings, and live sync status. Supports q, event_type, limit, before_at, and before_id.
POST/api/v1/admin/vulnerability-intelligence/syncQueues a background sync and returns 202 Accepted; returns a conflict if disabled or already running.
POST/api/v1/admin/vulnerability-intelligence/sync/cancelRequests cancellation of the active background sync and returns 202 Accepted; returns a conflict if no sync is active.
POST/api/v1/admin/vulnerability-intelligenceIngests an administrator-supplied normalized feed snapshot and refreshes matching retained findings; policy-impact notifications are projected in one background batch.

The scan vulnerability response exposes both scan_time_intelligence and current_posture. Use the scan history endpoint to inspect posture changes for one finding; use the admin timeline to investigate the source event across the installation.

Authenticated users can also use the following CVE Explorer endpoints. The history response is normalized and does not include administrator-only source or impact fields:

MethodEndpointPurpose
GET/api/v1/kb/:vulnId/historyCursor-paginated normalized CVE change history.
GET/api/v1/kb/:vulnId/exposurePage-based findings from completed scans in the caller's authorized scope. Supports posture=all, changed, needs_rescan, fix_available, not_affected, or disputed_rejected.
GET/api/v1/scans/:id/intelligence/policy-impactCurrent intelligence policy projection for the authorized completed scan; historical compliance data is never rewritten.

Troubleshooting

A sync runs for a long time

Check the active phase, completed/total events, unique CVE count, current CVE, and last progress timestamp in the admin page. A high unique-CVE count indicates upstream enrichment work; a stable last-progress timestamp indicates a stalled or failed worker. Review the most recent sync run and backend logs before starting another run.

A sync remains marked as running after a restart

Reload the CVE Intelligence admin page after the backend is healthy again. JustScan reconciles durable runs that were left in running state by the stopped process and records them as interrupted failures. The verified checkpoint remains intact, so the next scheduled or manual run can resume from the last successful event.

The timeline has events but posture has not changed yet

This is expected while an event is waiting for the official and NVD current records or for database posture evaluation. The source event is retained first. If enrichment fails, the event keeps its processing error, the checkpoint does not advance past it, and the worker retries.

The worker reports a database-column or migration error

Stop repeated manual retries and verify that the backend is running the same release whose migrations created the vulnerability-intelligence tables and columns. Back up PostgreSQL, inspect backend startup migration logs, and resolve the migration state before restarting the worker. Do not add a sequence of ad-hoc columns while the application is running; the worker and schema must come from one consistent release.

A finding becomes needs_rescan

needs_rescan is an intentional safe state when source evidence conflicts, package identity is incomplete, or an affected-range update cannot be matched confidently. Review the source event and package evidence, then run a fresh scan rather than treating the posture as not_affected.

See findings, SBOMs, and comparisons for the scan-side evidence model and backend configuration for all supported environment overrides.

On this page