Skip to content

Exports

What gets a finding out of the dashboard and in front of the person who can act on it.

SARIF 2.1.0

For GitHub code scanning, GitLab and Azure DevOps.

This is the export that matters most in practice, because it puts the finding on the pull request that introduced it rather than on a dashboard somebody visits on Thursdays. A finding annotated on the diff gets fixed; the same finding in a list gets triaged.

OpenVEX

A VEX document built from your triage decisions — what you assessed as not affected, and why.

Hand it to whoever consumes your SBOM. Without it they re-derive your entire backlog from your dependency list and arrive at conclusions you already investigated and dismissed.

How a triage reads in VEX

OpenVEX, CSAF and CycloneDX VEX — per scan, per project and for the whole estate — all read an issue's triage through the same table, so the same issue says the same thing in every signed document (decision 0041):

Triage CycloneDX analysis OpenVEX CSAF product_status
under review, pending approval in_triage under_investigation under_investigation
affected exploitable affected known_affected
will not fix — risk accepted exploitable, response will_not_fix affected, action statement "Will not fix: …" known_affected, remediation no_fix_planned
not affected, with a justification not_affected and its CycloneDX justification not_affected and the justification known_not_affected and the justification as a flag
not affected, without a justification in_triage under_investigation under_investigation
fixed, or the issue resolved resolved fixed fixed
  • An accepted risk is exported as exposure. The customer is owed the answer affected, no fix planned — not a clearance nobody argued.
  • A justification is never invented. A not affected recorded without one — older or imported rows — leaves as under investigation: nobody made that claim. CycloneDX gets its own vocabulary (code_not_present, code_not_reachable, requires_environment, protected_by_mitigating_control), which its schema accepts where OpenVEX's labels are not.
  • A request awaiting approval is under investigation everywhere, until somebody grants it.

In SARIF, the three settled statuses — not affected, will not fix, fixed — are marked suppressed, so a code-scanning view stops showing what was decided.

CSV

Issues as a flat file, for the analysis somebody wants to run in their own tool.

SBOM

The SBOM exactly as the cataloguer produced it, unmodified.

Worth being clear about why it is not reshaped: an SBOM is evidence, and evidence that passed through a transformation is evidence about the transformation too.

Documents written for people

Two PDF reports, written to be read rather than parsed:

  • a target's posture — where it stands now;
  • its detection and triage history — what was found, and what was decided about it.

See History and evidence.

Compliance evidence bundle

A cryptographically signed ZIP, covered under Compliance.

Project export

A whole project as one signed JSON document — the input a report plugin receives, and what an organisation writes its own plugin against. Download the export, in the Reports section of the project's page (below), saves it with your session; a pipeline asks the route with an integration key holding the export scope.

curl -H "X-API-Key: $KEY" -o export.zip https://vectispire.example.org/api/v1/projects/42/export
unzip export.zip                       # export.json and export.json.sig
cosign verify-blob --key public-key.pub --signature export.json.sig export.json

public-key.pub is /api/v1/crypto/public-key.pub, the key every Vectispire document is signed with.

What it holds, every part present even when empty — an empty list means "nothing", null means "not recorded", never zero: the project and the repositories and images filed in it; each target's newest completed scan (what it examined, what failed, each plugin's state) and the gate's last verdict; every issue that is not resolved, with its triage decision; counts per type, severity, state and triage status, resolved issues included; the consolidated components; the project's compliance state; and the checklist statements — each signed-off one with the digest of its signed package, and the open revision marked draft.

What it never holds: source code or anything quoted from it — an issue's text travels only for vulnerabilities, licences and end of life, never a secret's or a rule's message; a secret's value; a credential (a token in a repository URL is masked); an evidence file's bytes (named by SHA-256); an e-mail address — people appear by account id and display name, and a display name that is an address is left out.

Who may take one: an account that may act (not the platform governor) or an auditor, who sees the whole project, its images included. Anybody else is told the project does not exist (404), the same words as for a project that does not. An integration key restricted to one repository never sees a whole project. Each download is audited (PROJECT_EXPORTED) and sent to the SIEM as VECTI-SEC-032.

Bounded, never cut short: over 100,000 issues or components, or 64 MiB of JSON, the export is refused (409 project-export-too-large, naming the part, the figure and the bound) rather than signed incomplete.

Its schema is vectispire-project-export, versioned MAJOR.MINOR and stated in the export's first two fields. The installation serves the one it produces at /api/v1/schemas/project-export/1; the file is v1.schema.json in the source. A minor only adds optional fields: a plugin must ignore what it does not know. A major is a new file, and the release notes say when one appears and when the previous one stops being produced.

Reports

A report is your organisation's own document — a checklist in your security function's spreadsheet layout, a quarterly summary in your management's template — rendered from a project's export by a report plugin your administrators registered and approved. Vectispire gives the plugin the export, checks the file it writes, and signs it with the platform's key. Reports live on the project's page, in the Reports section.

A project's Reports section: the signed export, the report plugin switched on, and two runs — one produced, one failed with its reason.

Who sees what

The section is shown to anybody who sees the whole project, its images included: a report and the export describe the whole project, so they are built for nobody who sees only part of it. A reader who sees part of the project is told so, and offered nothing.

You are You can
Any account that sees the whole project read the plugins switched on for it and every run, and download a produced document
A write account (developer, security champion, administrator, CISO) or an auditor also request a report and download the export
A security lead (platform governor, administrator, CISO) also switch an approved plugin on or off for the project

The platform governor acts on nothing a project holds: the two buttons stay visible to them, disabled, with the reason. Each request and each export download is recorded in the audit log, and an export leaving the platform is signalled to the SIEM.

Requesting a report

Under Report plugins switched on, press Request a report beside the plugin. The run appears under Report runs, Waiting, and the page follows it until it ends: it asks the server again every five seconds while a run is waiting or running, and stops once none is. One run of a plugin at a time: the button stays disabled while one is under way, and that run is the one to wait for.

A run ends in one of three states:

State What it means
Produced The plugin wrote its document, the document is what its manifest declares, and its signed package is stored.
Failed Work went wrong: the plugin exited with an error, ran past its timeout, wrote nothing or too much, or no executor took the run. The reason is shown in words, with the plugin's own message when it wrote one. Ask again once the cause is fixed.
Refused The image had no verified signer, or the file it wrote is not what its manifest declares. Refused is not a failure, and it is shown in red rather than amber: it is how a tampered plugin, or one nobody vouched for, shows itself. Tell your administrators.

When the request itself is refused, the page says why: the platform governor disabled the plugin, it has no approved manifest, a run of it is already waiting or running, or this installation cannot run report plugins at all — its built-in worker is switched off, and this version does not run them on agents.

Provenance, under each run, lists what it ran with: the manifest and image digests, the signer, the export's SHA-256 and schema version, the document's and the package's SHA-256, and the signing key.

Downloading a document

Download on a produced run saves its package, a zip named by the server, report-<run>-<plugin>.zip, of three files:

  • the document, as the plugin wrote it, once checked against the type its manifest declares;
  • <document>.sig, its detached signature by the platform's key;
  • provenance.json, a signed statement of which export of this project was given to which image, verified as built by which signer, at whose request, and the document's SHA-256.

A document is kept for the evidence window. Once that has passed, the page says the document is no longer available; the run and its digests stay.

Verifying a document

Verify the package against the instance's public key, obtained separately — never one handed to you with the document. The commands are in the administration guide, the document, and how to verify it, and the Reports section links to them.

What the signature means: provenance, not truth. It says which export this installation gave which image, at whose request, and that these are the bytes the image wrote. It does not say the document renders the export faithfully: the export is kept with the run and the image is pinned, so anybody who doubts a document can render the export again with the same image and compare.

A withdrawn document is marked, and still downloadable. When the platform governor withdraws a plugin's manifest, every document it produced is marked Withdrawn on its run, with the date, who withdrew it and the justification. Its download is still offered — it is the evidence of what was handed out — and after it the page says that the signature still verifies but the installation no longer stands by the document. Anybody holding a copy can ask whether the installation still stands by it (how).

Switching a plugin on for a project

Security leads see a Switch on selector under the plugins, offering the approved plugins not yet on for the project. Switch off beside a plugin stops new requests; its runs and documents stay. Registering, approving and withdrawing plugins is under Administration → Report plugins (how).

Branding

Exports and reports carry your instance name where VECTISPIRE_BRAND_NAME is set — header, PDFs, SARIF, VEX and CSAF output. See Configuration.