Skip to main content
RelixQ
Menu

Scans, findings and reports

The day-to-day working loop: run a scan, read the live progress stream, filter and triage findings, save views, and export evidence.

Scanner families
4
Trigger sources
5
Report types
5
Browse the Developer Guide

Ways to trigger a scan

A scan is one run of one or more scanners against a project's assets. Each run records its trigger source — manual, pr, scheduled, cli, or api — which is shown in the Scans table.

Web — Run scan
The primary action on the Scans page. For connected GitHub projects, public repositories need no credentials and private repositories use the project token. A shallow working copy is used for the requested managed scan; retention and deletion behavior is governed by the approved schedule and applicable agreement described in the Trust Center.
Scheduled
One cron expression per project, with enable and disable, read and upsert via PUT /api/v1/projects/{projectId}/schedules. There is no web UI for editing schedules yet — use the API. The scheduler ticks every 30 seconds.
CLI
relixq scan runs entirely on your machine with no network; relixq submit uploads the results to your workspace. relixq remote-scan triggers a scan on the platform instead. See Enterprise CLI.
CI
Run the CLI, or install the GitHub App, to scan on every pull request. See Release gates.
API
POST /api/v1/scans starts a run directly. The scope object accepts a pullRequestNumber, though no worker consumes it to limit the scan to changed files yet.

The Scans page

Route: /orgs/<org>/projects/<project>/scans. The page lists the 24 most recent runs, most recent first — a recency window, not a time window.

ColumnContents
ScanThe scan id, with a status icon
Statusqueued · running (pulsing) · succeeded · failed · cancelled
Triggermanual, pr, scheduled, cli, or api
BranchBranch scanned, or a dash when not applicable
StartedRelative time
DurationWall-clock duration once finished, a dash while running
FindingsFinding count; failed scans show a dash

If a trigger fails — for example a connected source cannot be accessed — the error appears inline next to the button rather than creating a phantom run. A project with no runs shows the intentional empty state.

Scan detail and live progress

Route: .../scans/<scanId>. Three areas:

  • Status panel (live). A completed / total jobs (N%) counter and progress bar. For a running or queued scan the panel subscribes to a Server-Sent Events stream at /api/scans/{scanId}/events and updates in place as scan.progress events arrive, flipping to Succeeded on scan.completed. Below it, a four-stage pipeline — Clone repository → Detect languages → Analyze cryptography → Generate report.
  • Details grid. Trigger, Branch, Commit, Started, Duration, Files scanned, and Findings. Fields the backend did not report show a dash.
  • Files by language. A per-language breakdown with critical-finding counts, rendered only when the scan reported file statistics.

The findings list

Route: .../findings. The header states exactly what you are looking at — "N findings match · of M in this project" — the filtered count next to the unfiltered project total. The left filter rail drives the URL query string, so any filtered view is shareable as a link.

FilterValues
SearchFree text across file path, algorithm, and rule (debounced as you type)
Severitycritical, high, medium, low chips. info exists in the schema and can be filtered via the URL.
Statusopen, in progress, accepted risk, fixed, false positive
Environmentprod, staging, dev. test and unknown are valid URL values without chips.
Quantum safetyvulnerable, Grover-weakened, classically broken, hybrid, quantum-safe

Chips are multi-select within a group. A few extra filters — algorithm, serviceId, owner, plus sort (riskScore | lastSeenDate | severity) and order — are accepted as URL parameters even though the rail has no controls for them. There is no language filter parameter; language is visible per finding but not filterable today.

Table columns: expand chevron, Severity, Algorithm, Location, Service, Env, Exposure, Owner, Risk (0–100), Last seen, Status. Clicking the chevron expands an inline "Why this was flagged" panel without leaving the list — quantum-safety classification, rule id, language, usage type, detector confidence, suggested migration target, vertical context, and the recommendation. Paging is 50 per page by default.

Finding detail

Route: .../findings/<findingId>. Titled with the rule id and the path:line location, with the severity chip alongside.

Source
A syntax-highlighted panel with the flagged line marked. Because the finding contract carries no source code, this renders a representative sample for the language and algorithm — not the literal contents of your file. Open path:line in your editor for the real code.
AI Explanation
An on-demand button that sends the finding metadata — algorithm, usage, location, quantum classification, severity, environment, exposure, suggested target, but never your source — to a server-side LLM call and returns a three-part analysis: why quantum-vulnerable, the risk, and the migration path, naming a concrete NIST PQC target where relevant.
Recommendation
The scanner and scoring recommendation — the suggested migration and any interim hardening.
Context sidebar
Service, Environment, Exposure, Owner, Usage, Algorithm, the quantum classification chip, the suggested migration target, Vertical, and detector Confidence.
Risk Score sidebar
The 0–100 score with its contributing rows: algorithm risk, usage multiplier, exposure multiplier, environment multiplier, and confidence.
History
First seen, Last seen, and current Status.

A suggested triage loop

Severity is the scanner assessment of the weakness itself. The risk score additionally weighs where it runs — production versus development, external versus internal exposure, usage type. A workable weekly loop:

  1. 01

    Filter to what matters first

    severity=critical plus status=open, adding environment=prod if the list is long, sorted by risk score — the default sort.

  2. 02

    Review each finding

    Use the inline "Why flagged" panel or the detail page; reach for the AI explanation when you need the migration reasoning spelled out.

  3. 03

    Fix or dispose

    Fix the code and re-scan, or mark it a false positive if the detector is wrong.

  4. 04

    Route exceptions through governance

    If a finding is real but must be accepted for now, file a governance exception with an expiry rather than silently ignoring it. See Governance.

  5. 05

    Save the filter, then let CI hold the line

    Next week starts from the same query, and release gates stop new critical findings from landing between reviews.

Saved views

Route: .../saved-views. Saved views bookmark finding filters so recurring queries are one click. The page has a save form and a list where each view shows its name, creator, and age.

Reports and exports

Route: .../reports. Generation is asynchronous: submitting queues a job and returns the report id immediately, and the page polls while any job is queued or running so rows advance queued → running → ready without a manual reload.

Report typeFormatsAudience
Executive quantum exposureMarkdown, JSON, CSV, SARIF, PDFLeadership and CISO board pack
HNDL exposure registerMarkdown, JSON, CSVThe harvest-now-decrypt-later register export
Remediation programMarkdown, JSON, CSVMigration work-item status
Compliance mappingMarkdown, JSONControl and compliance coverage
CI gate evidenceMarkdown, JSONRelease-gate evidence bundle

A scope filter narrows the export to All findings, Open only, or Critical and high only, each shown with its live finding count. The format list adapts to the chosen type so you can never queue a job the backend cannot render; unsupported combinations fail with an explicit reason rather than a silently wrong file. Artifacts are retained for 90 days.

One deliberate carve-out: the CycloneDX CBOM is not a report job. It is a direct download served straight from the scoring service. See Inventory and CBOM.

Related pages