Skip to content

Quorum Documentation — Index

This is the landing page (master index) of the enterprise documentation for Quorum (quorum-sec-scan), a consensus security scanning tool delivered as a CLI and Docker images. Quorum orchestrates a pool of 12 OSS scanners — trivy, grype, checkov, kics, dockle, kubescape, polaris, kube-score, terrascan, tfsec, regula and conftest (policy-as-code over the operator's Rego in ./policy) — normalizes everything into a canonical model (model.Finding), resolves vulnerability aliases (CVE/GHSA via OSV.dev), correlates equivalent findings through a deterministic correlationKey, computes a confidence (consensus) score and emits a SARIF (primary), JSON or XML report. Consensus goes beyond SCA and covers multi-cloud IaC (AWS/Azure/GCP via the AVD hub) and Kubernetes posture (the kubescape C-#### hub, correlating kubescape × polaris × kube-score), with crosswalks derived from real output; RBAC stays single-engine (documented). The design principle is "false split > false merge" and the operational motto is "0 findings is not proof of safety". This documentation describes the product AS-IS at version v0.8.3 (branch main as the source of truth); items for web frontend and relational database, HTTP REST API are marked N/A by architecture, with a technical rationale and, where useful, a clearly separated "future proposal". AI/LLM stays out of the deterministic core, but since v0.8.3 there is an opt-in advisory layer (--advice, off by default) — presentation-only, byte-identical output when disabled.


Table of Contents (TOC)

# Document Description (1 line)
00 Index This page: landing, reading map, assumption/gap registers and metadata.
01 Overview What Quorum is, CLI/Docker scope, principles and N/A boundaries.
02 Functional Requirements Commands, flags (--metrics/--log-format/--advice/--fix), exit codes, 12 scanners and target matrix.
03 Non-Functional Requirements Performance, target SLO/SLI, supply chain (SLSA/SBOM/knowledge-pack attested), interpretive compliance.
04 Architecture Pipeline, internal/* packages, orchestrator fan-out, consensus crosswalks and sequence.
05 Data Modeling model.Finding, MergedFinding (Remediation/References/Advice/Fix), crosswalk YAML, fingerprints and JSON/XML shapes.
06 Interfaces (CLI) and Output Formats CLI contract, list-scanners, advise-index, advisory flags, SARIF/JSON/XML and invocation examples.
07 Persistence and Artifacts Alias cache, Grype DB, crosswalk YAML, advice cache, .quorumignore baseline and reports.
08 Frontend / Terminal Experience Terminal UX: stdout/stderr, summary, absence of color/TTY (web is N/A).
09 Backend cmd/quorum + internal/* as the CLI "backend"; no server/daemon (web N/A).
10 Infrastructure Build, GHCR distribution (:full/:slim), cosign keyless + SLSA + SBOM SPDX + knowledge-pack attestation; hosted runtime N/A.
11 DevOps CI/e2e/release workflows, PR flow, automatic moving v0 tag (tag-major.yml) and consumer verification.
12 Security Threat model, risks R1–R8, supply chain, egress controls for the remote advisor and framework mappings.
13 AI (Artificial Intelligence) Honest framing: the core has no AI/LLM/ML; an opt-in local/remote advisory layer exists (off by default); OSV is a deterministic lookup.
14 Observability [quorum] logs on stderr, SARIF/JSON fields, --metrics textfile and the quorum_advice_* metrics.
15 Testing Test strategy, contract tests, consensus e2e, the internal/evals advisory harness and coverage proposals.
16 Roadmap V1/V2/V3 phases, Polaris status and SemVer release gates.
17 Backlog Prioritized Epics/Stories (MoSCoW, Fibonacci story points).
18 Risk Matrix Technical/supply-chain/operational risks with a qualitative 5x5 matrix.
19 Costs Cost modeling (Actions/GHCR/headcount), licenses and FX.
20 Improvements and Recommendations Prioritized performance/UX/supply-chain opportunities.
21 Proposal — Advisory AI (opt-in) The AI design proposal (Phases 0–3), now implemented in v0.8.3 without touching the deterministic core.
99 Checklists Actionable adoption, operation and release checklists.

How to read / documentation map

Pick the trail that matches your role:

flowchart TD
    Start([You are...]) --> Dev[Developer / Contributor]
    Start --> Ops[CI/CD / Platform Engineer]
    Start --> Sec[Security / AppSec]
    Start --> PM[Product / Stakeholder]

    Dev --> D1[01 Overview]
    Dev --> D2[04 Architecture]
    Dev --> D3[05 Data Model]
    Dev --> D4[09 Backend]
    Dev --> D5[15 Testing]

    Ops --> O1[06 CLI Interfaces]
    Ops --> O2[07 Persistence]
    Ops --> O3[10 Infrastructure]
    Ops --> O4[11 DevOps]
    Ops --> O5[14 Observability]

    Sec --> S1[12 Security]
    Sec --> S2[18 Risks]
    Sec --> S3[13 AI]

    PM --> P1[01 Overview]
    PM --> P2[02 Functional Requirements]
    PM --> P3[16 Roadmap]
    PM --> P4[17 Backlog]
    PM --> P5[19 Costs]

Suggested trails:

Naming convention: files follow the NN-file.md pattern, with 00 as the index and 99 for checklists. Cross-links use relative paths inside docs/.


Scope boundaries (AS-IS)

Quorum is CLI/Docker only. The domains below are N/A by architecture in v0.8.3:

Domain Status Technical rationale Where to dig deeper
Web frontend / UI N/A There is no HTTP server nor browser assets; the UX is terminal (stdout/stderr). 08-frontend
Relational database N/A There is no persistent domain datastore; only rebuildable file caches (aliases, Grype DB, advice cache). 07-persistencia-e-artefatos
HTTP REST API N/A There is no resident endpoint/service; the interface is the CLI binary and the Docker image. 06-interfaces-cli-e-formatos
Authentication / accounts N/A There are no users, sessions or identity managed by the product. 12-seguranca
AI / LLM / ML N/A in the core; opt-in advisory The deterministic core has no AI (OSV.dev is a deterministic lookup, not ML). Since v0.8.3 an opt-in advisory layer (--advice, off by default) can attach natural-language recommendations; it never touches correlationKey/confidence/severity/the fail-on gate. 13-ia, 21-proposta-ia
Runtime security (Falco/Tetragon), hosted/K8s runtime N/A (future proposal) The product runs in batch in the pipeline; there is no cluster-resident component. 10-infraestrutura, 16-roadmap

Assumptions Register (consolidated)

Cross-cutting assumptions that govern the whole documentation suite. Assumptions specific to each document appear in the "## Assumptions" section of the respective file.

ID Assumption Source documents
A-01 The main branch (product v0.8.3) is the source of truth; where DESIGN.md (Draft v0.1) diverges, the code prevails. 04, 05, 09, 18
A-02 The version constant in root.go is 0.1.0 because it is overridden at build-time via -ldflags (GoReleaser); releases inject 0.8.3. Examples use 0.8.3. 02, 05, 06, 09
A-03 report.Version = "0.1.0" is reported faithfully and treated as the contract version / fingerprint namespace (quorum/v1), not the product version. 05, 06
A-04 Quorum is CLI/Docker only: web, RDBMS, REST API and auth are N/A by architecture; AI/LLM stays out of the deterministic core and only appears as an opt-in advisory layer (off by default). 01, 03, 08, 09, 13, 15, 17, 20, 99
A-05 OSV.dev is the only runtime network dependency of the core, optional and with graceful degradation; --offline disables it (air-gapped operation) and also blocks the remote advisor. 01, 02, 03, 12
A-06 --timeout maps to PerScannerTime (per scanner); the 60s ProbeTime (defaultProbeTime) is separate and not exposed as a flag in v0.8.3. 02, 14, 99
A-07 correlationKey and confidence are deterministic over the normalized data; the advisory layer is presentation-only and does not alter them. 01, 05
A-08 ~~polaris appears in scannerCategory without an adapter~~ — resolved: polaris and kube-score are real adapters (K8S_POSTURE) since v0.5.0 (see G-03), participating in the K8s posture consensus. There is no phantom scanner. 02, 05, 09, 16
A-09 The target matrix reflects Supports/Capabilities read from the code, preserving divergences (e.g. kubescape Supports repo+k8s but declares capability only k8s). 02
A-10 The alias cache has no TTL; management/cleanup are manual; improvements listed as a future proposal. 02, 07
A-11 Performance targets and SLO/SLI are engineering targets, not validated by a formal benchmark in the repo. 03, 20
A-12 PCI/ISO/ASVS/Top10/DREAD mappings are interpretive of the code as-is, not a compliance attestation; DREAD scores are qualitative. 03, 12
A-13 Owner/repo is Martinez1991/quorum-sec-scan and the registry is ghcr.io/martinez1991/quorum-sec-scan (lowercase). 10, 11, 99
A-14 The :full image is linux/amd64 (Grype DB pre-cached at build-time); :slim covers amd64+arm64 with scanners on the PATH, changing the performance/availability profile. 03, 09, 10, 99
A-15 The production consumer verifies the image/binary (cosign + gh attestation) and pins by digest; the product only provides the means. 03, 11
A-16 Distribution availability depends on third parties (GHCR/Releases/OSV) outside the project's control. 03
A-17 Logs are text with a [quorum] prefix on stderr (not JSON by default, no per-line levels/timestamps); the telemetry consumer is the invoking platform. 03, 14
A-18 The repository is public OSS (free Actions/storage quotas); paid tiers model the private/overage case. FX US$ 1 ≈ R$ 5.50. 19
A-19 Quorum's license is Apache-2.0 (confirmed via LICENSE); the licenses of the bundled scanners are estimates to confirm upstream. 19
A-20 Image/artifact sizes are qualitative (inferred from the Dockerfiles), not measured in the repo. 10, 19
A-21 Fixtures in internal/adapter/testdata are not part of the production execution path. 13, 15
A-22 The advisory layer is opt-in and off by default; without --advice the output is byte-identical. Phase 0 (curated templates + OWASP refs) and Phase 2 (RAG over a digest-pinned OWASP corpus) are deterministic and model-free; Phase 1 (local LLM) and Phase 3 (remote provider) are opt-in, reproducible (temperature=0 + cache) and gated (remote requires --advice-allow-egress, is blocked by --offline and refuses --fix). Every AI attachment is labeled "AI-generated, advisory only". 05, 06, 12, 13, 14, 15, 21

Gap Register

Items not verified at the source, divergences and known debts. These are natural candidates for the backlog (17-backlog) and improvements (20-melhorias).

G-02, G-09, G-10 and G-11 were resolved in v0.2.4 (issues #15#18, milestone hardening v0.2.4). The rows below remain for historical traceability.

ID Gap Impact Source documents
G-01 Divergent version: report.Version hardcoded to 0.1.0 vs product v0.8.3; the intent (stable contract vs drift) is not clear in the code. Medium 05
G-02 Resolved in v0.2.4 (#18). ~~durationMs in scanners[] serialized as nanoseconds~~ — now ScannerRun.MarshalJSON emits milliseconds, consistent with summary.durationMs. Medium 06
G-03 Resolved in v0.5.0: polaris stopped being dead-config and became a real adapter (K8S_POSTURE), together with kube-score — re-added to scannerCategory. There is no more phantom scanner. Low 02, 05, 09, 16
G-04 Resolved/accepted: cache with schemaVersion (v0.4.1). TTL and cross-process locking are intentionally omitted (decision): CVE↔GHSA aliases are immutable facts (they do not age), and the atomic write (tmp+rename) already prevents corruption — a concurrent loss is benign (just a re-lookup). Low 07, 02
G-05 Resolved in v0.4.2: the crosswalk Load accepts a versioned document (schemaVersion + controls) in addition to the legacy list (backward-compatible), allowing the format to evolve. Low 07
G-06 Grype DB frozen in the :full build — it can still miss recent CVEs without a rebuild/repull (staleness by design). ⚠️ Bug fixed in v0.2.6: GRYPE_DB_VALIDATE_AGE=false was missing, so after 5 days grype failed every scan (DB age validation); now the embedded DB does not expire (it only ages). High 07, 18
G-07 Much improved / accepted residue: bases @sha256; SBOM SPDX attested (image) and per-binary; kubescape by SHA256; trivy/kics/dockle by digest/checksum; Grype/Syft via anchore install.sh (internal checksum). Accepted residue: Checkov via pip is version-pinned (==3.3.6) — the full hash-lock of the dep tree was deferred (high maintenance cost per bump + cross-platform musl fragility vs. low return). Low 03, 12, 18
G-08 Resolved (v0.4.2/v0.4.4): --metrics <file> exports a Prometheus textfile and --log-format json emits the progress logs as JSON lines ({ts,level,msg}) for ingestion. Low 03, 14
G-09 Resolved in v0.2.4 (#15). ~~--output without Clean (perm 0644)~~ — now filepath.Clean + write with perm 0o600 (R3). High 12
G-10 Resolved in v0.2.4 (#16). ~~OSV id without url.PathEscape/validation~~ — now validated (^[A-Za-z][A-Za-z0-9._-]{0,127}$) + url.PathEscape (R6). Medium 12
G-11 Resolved in v0.2.4 (#17). ~~target ref without rejecting -~~ — now the CLI boundary refuses a target starting with - (R1 argument injection). Medium 12
G-12 Resolved (v0.4.1/v0.4.4): runCmd caps the scanner stdout (512 MiB, QUORUM_MAX_OUTPUT_BYTES) (R2) and there is a target size cap for repo/k8s (20 GiB, QUORUM_MAX_TARGET_BYTES, walk with early-abort) (R5). Low 12
G-13 aliases.json without integrity/signature (perm 0644): cache poisoning risk (R7). Medium 12
G-14 No redaction of secret values in the report (R8). Medium 12
G-15 Test coverage not collected in CI; internal/{model,purl,consensus,crosswalk} without dedicated _test.go; non-deterministic e2e (the gate only checks multiDetected>=1). Medium 15
G-16 Resolved. ~~Moving v0 tag moved manually~~ — now the .github/workflows/tag-major.yml workflow advances v0/v0.2 automatically on each semver release. Low 11, 99
G-17 ⚠️ Partially measured: image sizes confirmed — :full ≈ 3.3 GB, :slim ≈ 27 MB (2026-07-03). Actions minutes and GHCR storage remain under provider quotas (variable); performance benchmarks remain a target. Low 19, 03, 10, 20
G-18 Resolved: THIRD_PARTY_NOTICES.md lists the bundled scanners (all Apache-2.0), and the attested SBOM SPDX per release is the authoritative list of components/licenses. Medium 19
G-19 ⚠️ Reduced: test coverage is now collected in CI (~60%), with new tests in purl/model/consensus/crosswalk and in the security flows; the exhaustive line-by-line verification of all adapters/reporters remains a documentary caveat (non-blocking). Low 02, 04, 09, 12, 20

Open questions (for stakeholders)

Decisions that depend on product/maintainers and that unblock or adjust the documentation.

Product and scope

  • [x] Polaris: will it become an adapter or should the scannerCategory entry be removed? (G-03) — ✅ resolved: polaris + kube-score are real adapters (K8S_POSTURE) since v0.5.0.
  • [ ] kubescape: is the Supports repo+k8s vs capability only k8s divergence intentional? It may confuse users on repo targets. (A-09)
  • [ ] Is there appetite for additional image profiles (:sca/:iac/:k8s) or is the :full/:slim pair definitive?
  • [ ] Is there appetite for --format table/markdown and PR decoration while keeping the product strictly CLI (automation only in the Action)?

Contracts and versioning

  • [ ] Should report.Version reflect the product version via ldflags or is it deliberate independent contract versioning? (G-01)
  • [ ] Is the []MergedFinding dump in the JSON findings field (with full Members) a stable contract or an internal detail subject to change?
  • [ ] Should durationMs in scanners[] be converted to milliseconds (consistency with summary)? (G-02)
  • [ ] Is there an intent to officially publish the JSON Schema (quorum-report-v1.json) as a versioned file?

Configuration and operation

  • [ ] Should the 60s ProbeTime be exposed as a CLI/Action flag or stay internal? (A-06)
  • [ ] Introduce schemaVersion in aliases.json and/or in the crosswalk YAMLs for explicit migration? (G-04, G-05)
  • [ ] Offer a configurable TTL or a quorum cache clear command for the alias cache? (A-10)
  • [ ] Should a custom crosswalk merge with the bundled one (instead of replacing it) when --crosswalk points to another directory?
  • [ ] What is the recommended official cadence for rebuilding/repulling the :full image (fresh Grype DB)? (G-06)

Advisory layer (AI)

  • [ ] Should the default --advice-provider ever move beyond none, or does an opt-in-only default stay the policy? (A-22)
  • [ ] Which local endpoints/models are officially supported/documented for --advice-provider=local (e.g. Ollama)?
  • [ ] What is the cadence for refreshing and re-attesting the digest-pinned OWASP corpus (quorum advise-index)?

Supply chain, security and CI

  • [ ] Is there a plan to harden all scanners in Dockerfile.full to @sha256 and generate an SBOM for :full? (G-07)
  • [ ] Does release.yml publish SLSA attestation + cosign signature for both images (:full and :slim), the binaries and the knowledge pack?
  • [ ] Is there an intent for an internal/configurable OSV mirror (BaseURL via env) for air-gapped beyond --offline?
  • [ ] Do SAST (golangci-lint/gosec/CodeQL) and secret scanning (gitleaks) enter ci.yml or a dedicated workflow?
  • [ ] Should there be a blocking coverage gate in CI and what is the official target (suggestion: 80% global / 90% core)? (G-15)
  • [ ] Should a self-scan (dogfooding) of the published images run in release.yml before the push?
  • [x] Will the moving v0 tag be moved by automation after the release? (G-16) — ✅ yes, via tag-major.yml.
  • [ ] Is there branch protection with required checks (ci/e2e) configured in the GitHub settings to formally reflect it?

Business and governance

  • [ ] Is the repository public (OSS quotas) or private (subject to overage)? Is there a real budget/headcount or a volunteer regime? (A-18)
  • [ ] What is the retention/GC policy for old tags in GHCR? (G-17)
  • [ ] Officially confirm the license of each bundled scanner and the obligation to include a third-party NOTICE in :full. (G-18)
  • [ ] Should there be an automatic warning for the "all scanners ran but 0 findings" case or does it stay only in the documentation?

Assumptions

Assumptions specific to this index (in addition to the consolidated ones above):

  • The TOC was built from a real Glob docs/*.md (21 documents present besides this index); the one-line descriptions derive from the H1s and the known scope of each file.
  • The Assumptions, Gaps and Questions registers consolidate the content of the sections of the same name in documents 01–20 and 99; each item references the source documents for traceability.
  • The gap impact classification (Low/Medium/High) is qualitative and serves prioritization, it is not a measurement.
  • Cross-links use relative NN-file.md paths and assume that all files listed in the TOC remain in the docs/ directory.

Metadata

Field Value
Product Quorum (quorum-sec-scan)
Documented version v0.8.3 (AS-IS)
Source of truth branch main
Scanners 12 (trivy, grype, checkov, kics, dockle, kubescape, polaris, kube-score, terrascan, tfsec, regula, conftest)
Language Go 1.26 (CLI with cobra)
Advisory layer Opt-in --advice (off by default); Phases 0–3 implemented (internal/enrich, internal/rag, internal/advisor, internal/evals)
Distribution Docker GHCR :full (linux/amd64) / :slim (amd64+arm64) + GoReleaser binaries; cosign keyless, SLSA build-provenance and SBOM SPDX attested (image and per-binary), plus knowledge-pack attestation
Owner/repo Martinez1991/quorum-sec-scan
Registry ghcr.io/martinez1991/quorum-sec-scan
License Apache-2.0
Doc language en (default)
Revision date 2026-07-04
Status Under review — pending stakeholder answers (see "Open questions")