Skip to content
Reports

Reports

kartis-scan turns a consolidated scan document — the JSON produced by scripts/full-scan.sh (see Scanning) — into a customer-facing Markdown report. There is no report viewer in Kartis itself; the Markdown is meant to be read directly, converted with another tool, or consumed by Eon Center, Eon Aethis, or Eon Insights.

Generating a report

kartis-scan report [file] [flags]
  --lang <nl|en>       report language (default "nl")
  -o, --out <path>     output file (default: stdout)
  --anonymize          anonymize the input before rendering

The input is a file argument, or stdin when no argument (or -) is given:

kartis-scan report scan.json                # Dutch report to stdout
kartis-scan report --lang en scan.json       # English report
scripts/full-scan.sh qgf.io | kartis-scan report -o report.md

What’s in the rendered document

internal/report renders, in order:

  • Header — domain, scan window, duration, host/service/finding counts.
  • Summary — an overall risk verdict plus a per-severity tally, and a “top actions” list of up to five items: the highest-severity findings (one action per finding source, to avoid repetition), plus a post-quantum key-exchange recommendation appended whenever no service offers hybrid PQ key exchange.
  • Post-quantum readiness — whether hybrid PQ key exchange (for example X25519MLKEM768) is present anywhere, and a per-TLS-service table of key exchange group, weakest certificate link, and PQC classification.
  • Findings — grouped by severity, each with its description, evidence, any associated CVE IDs, and a risk/mitigation block. Mitigation text comes from internal/report/mitigations.go, keyed by finding source.
  • Appendix — a table of every discovered service (host, port, protocol, service, product/version), and for each TLS service, its certificate chain: subject, issuer, signature algorithm, key details, PQC classification, expiry, and SANs.
  • Methodology — a fixed disclosure paragraph: the scan is an authorized external perimeter scan, the scanner identifies itself honestly and performs no evasion, and certificate parsing relies on the TLS 1.2 cleartext handshake (a TLS 1.3-only host reports protocol/key-exchange posture without parsed certificates).

The document renders in Dutch (nl, the default) or English (en); all section headers, labels, and the methodology text are localized (internal/report/i18n.go).

Output format

kartis-scan report only produces GitHub-flavored Markdown — there is no built-in DOCX or PDF export. Converting the Markdown to another format (for example with pandoc, or by opening it in a word processor) is a manual step outside the CLI.

Anonymizing scan data

kartis-scan anonymize [file] [flags]
  -o, --out <path>     output file (default: stdout)

Reads a consolidated scan JSON document (file argument or stdin) and writes an anonymized copy:

  • hostnames matching the literal qgf.io domain (and the bare qgf token, including its dash form used by Microsoft 365 routing hosts) become acme.com subdomains
  • IP addresses become RFC 5737 documentation addresses
  • certificate identifiers (serial numbers, fingerprints, key IDs, raw DER/PEM) are replaced with random values

Every distinct real value maps to one stable anonymized value, so the anonymized document stays internally consistent (the same real hostname always becomes the same fake one, throughout the document).

Limitation: the domain match is hardcoded to qgf.io (internal/ anonymize/anonymize.go) — there is no domain parameter. Anonymizing a scan of any other domain will not scrub that domain’s hostnames; they pass through unchanged into the “anonymized” output, while IPs and certificate fields are still scrubbed. Today this command is effectively limited to producing sample documents from qgf.io (the standing own-infra reference target), not to anonymizing arbitrary customer scans.

Pipe it into report to produce an anonymized, shareable sample document:

kartis-scan anonymize scan.json | kartis-scan report -o sample.md

or use report’s own --anonymize flag to do both in one step:

kartis-scan report --anonymize -o sample.md scan.json