Documentação do Quorum — Índice¶
Esta é a landing page (índice mestre) da documentação enterprise do Quorum (quorum-sec-scan),
uma ferramenta de consensus security scanning entregue como CLI e imagens Docker. O Quorum
orquestra um pool de 12 scanners OSS — trivy, grype, checkov, kics, dockle, kubescape, polaris,
kube-score, terrascan, tfsec, regula e conftest (policy-as-code sobre Rego do operador em ./policy) —
normaliza tudo para um modelo canônico (model.Finding), resolve aliases de vulnerabilidade
(CVE/GHSA via OSV.dev), correlaciona findings equivalentes por um correlationKey determinístico,
calcula um score de confiança (consensus) e emite relatório SARIF (primário), JSON ou XML.
O consenso vai além de SCA e cobre IaC multi-cloud (AWS/Azure/GCP via hub AVD) e postura
Kubernetes (hub C-#### do kubescape, correlacionando kubescape × polaris × kube-score), com
crosswalks derivados de output real; RBAC segue single-engine (documentado). O princípio de projeto é
"false split > false merge" e o lema operacional é "0 findings is not proof of safety".
Esta documentação descreve o produto AS-IS na versão v0.8.3 (branch main como fonte de verdade);
itens de frontend web, banco de dados relacional e API REST HTTP são marcados N/A por
arquitetura, com justificativa técnica e, quando útil, uma "Proposta futura" claramente separada.
IA/LLM fica fora do núcleo determinístico, mas desde a v0.8.3 existe uma camada consultiva opt-in
(--advice, desligada por padrão) — apenas de apresentação, com saída byte-idêntica quando desabilitada.
Sumário (TOC)¶
| # | Documento | Descrição (1 linha) |
|---|---|---|
| 00 | Índice | Esta página: landing, mapa de leitura, registros de premissas/lacunas e metadados. |
| 01 | Visão Geral | O que é o Quorum, escopo CLI/Docker, princípios e fronteiras N/A. |
| 02 | Requisitos Funcionais | Comandos, flags (--metrics/--log-format/--advice/--fix), exit codes, 12 scanners e matriz de targets. |
| 03 | Requisitos Não Funcionais | Performance, SLO/SLI alvo, supply chain (SLSA/SBOM/knowledge-pack atestado), conformidade interpretativa. |
| 04 | Arquitetura | Pipeline, pacotes internal/*, fan-out do orchestrator, crosswalks de consenso e sequência. |
| 05 | Modelagem de Dados | model.Finding, MergedFinding (Remediation/References/Advice/Fix), crosswalk YAML, fingerprints e formas de JSON/XML. |
| 06 | Interfaces (CLI) e Formatos de Saída | Contrato da CLI, list-scanners, advise-index, flags consultivas, SARIF/JSON/XML e exemplos de invocação. |
| 07 | Persistência e Artefatos | Cache de aliases, Grype DB, crosswalk YAML, cache de advice, baseline .quorumignore e relatórios. |
| 08 | Frontend / Experiência de Terminal | UX de terminal: stdout/stderr, summary, ausência de cor/TTY (web é N/A). |
| 09 | Backend | cmd/quorum + internal/* como "backend" CLI; sem servidor/daemon (web N/A). |
| 10 | Infraestrutura | Build, distribuição GHCR (:full/:slim), cosign keyless + SLSA + SBOM SPDX + atestação do knowledge-pack; runtime hospedado N/A. |
| 11 | DevOps | Workflows CI/e2e/release, fluxo de PR, tag móvel v0 automática (tag-major.yml) e verificação do consumidor. |
| 12 | Segurança | Modelo de ameaças, riscos R1–R8, supply chain, controles de egress do advisor remoto e mapeamentos de framework. |
| 13 | IA (Inteligência Artificial) | Framing honesto: o núcleo não tem IA/LLM/ML; existe uma camada consultiva opt-in local/remota (desligada por padrão); OSV é lookup determinístico. |
| 14 | Observabilidade | Logs [quorum] em stderr, campos SARIF/JSON, textfile --metrics e as métricas quorum_advice_*. |
| 15 | Testes | Estratégia de testes, contract tests, e2e de consenso, o harness consultivo internal/evals e propostas de cobertura. |
| 16 | Roadmap | Fases V1/V2/V3, status do Polaris e gates de release SemVer. |
| 17 | Backlog | Epics/Stories priorizados (MoSCoW, story points Fibonacci). |
| 18 | Matriz de Riscos | Riscos técnicos/supply-chain/operacionais com matriz 5x5 qualitativa. |
| 19 | Custos | Modelagem de custos (Actions/GHCR/headcount), licenças e câmbio. |
| 20 | Melhorias e Recomendações | Oportunidades de performance/UX/supply chain priorizadas. |
| 21 | Proposta — IA consultiva (opt-in) | A proposta de design de IA (Fases 0–3), agora implementada na v0.8.3 sem tocar o núcleo determinístico. |
| 99 | Checklists | Checklists acionáveis de adoção, operação e release. |
Como ler / mapa da documentação¶
Escolha a trilha conforme seu papel:
flowchart TD
Start([Você é...]) --> Dev[Desenvolvedor / Contribuidor]
Start --> Ops[Engenheiro de CI/CD / Plataforma]
Start --> Sec[Segurança / AppSec]
Start --> PM[Produto / Stakeholder]
Dev --> D1[01 Visão Geral]
Dev --> D2[04 Arquitetura]
Dev --> D3[05 Modelo de Dados]
Dev --> D4[09 Backend]
Dev --> D5[15 Testes]
Ops --> O1[06 Interfaces CLI]
Ops --> O2[07 Persistência]
Ops --> O3[10 Infraestrutura]
Ops --> O4[11 DevOps]
Ops --> O5[14 Observabilidade]
Sec --> S1[12 Segurança]
Sec --> S2[18 Riscos]
Sec --> S3[13 IA]
PM --> P1[01 Visão Geral]
PM --> P2[02 Requisitos Funcionais]
PM --> P3[16 Roadmap]
PM --> P4[17 Backlog]
PM --> P5[19 Custos]
Trilhas sugeridas:
- Primeiro contato: 01-visao-geral → 06-interfaces-cli-e-formatos → 99-checklists.
- Entender o "como funciona": 04-arquitetura → 05-modelo-de-dados → 09-backend.
- Adotar em pipeline: 06-interfaces-cli-e-formatos → 10-infraestrutura → 11-devops → 14-observabilidade.
- Avaliar postura de segurança: 12-seguranca → 18-riscos → 13-ia.
- Planejar a camada consultiva: 21-proposta-ia → 13-ia → 06-interfaces-cli-e-formatos.
- Planejar evolução: 16-roadmap → 17-backlog → 20-melhorias.
Convenção de nomes: arquivos seguem o padrão NN-arquivo.md, com 00 como índice e 99 para
checklists. Cross-links usam caminhos relativos dentro de docs/.
Fronteiras de escopo (AS-IS)¶
O Quorum é CLI/Docker only. Os domínios abaixo são N/A por arquitetura na v0.8.3:
| Domínio | Status | Justificativa técnica | Onde se aprofundar |
|---|---|---|---|
| Frontend web / UI | N/A | Não há servidor HTTP nem assets de browser; a UX é terminal (stdout/stderr). | 08-frontend |
| Banco de dados relacional | N/A | Não há datastore de domínio persistente; só caches de arquivo reconstruíveis (aliases, Grype DB, cache de advice). | 07-persistencia-e-artefatos |
| API REST HTTP | N/A | Não há endpoint/serviço residente; a interface é o binário CLI e a imagem Docker. | 06-interfaces-cli-e-formatos |
| Autenticação / contas | N/A | Não há usuários, sessões ou identidade gerenciada pelo produto. | 12-seguranca |
| IA / LLM / ML | N/A no núcleo; consultivo opt-in | O núcleo determinístico não tem IA (OSV.dev é lookup determinístico, não ML). Desde a v0.8.3 uma camada consultiva opt-in (--advice, desligada por padrão) pode anexar recomendações em linguagem natural; ela nunca toca correlationKey/confidence/severidade/o gate fail-on. |
13-ia, 21-proposta-ia |
| Runtime security (Falco/Tetragon), runtime hospedado/K8s | N/A (proposta futura) | O produto roda em batch no pipeline; não há componente residente em cluster. | 10-infraestrutura, 16-roadmap |
Registro de Premissas (consolidado)¶
Premissas transversais que governam toda a suíte de documentação. Premissas específicas de cada documento aparecem na seção "## Premissas" do respectivo arquivo.
| ID | Premissa | Documentos-fonte |
|---|---|---|
| A-01 | A branch main (produto v0.8.3) é a fonte de verdade; onde DESIGN.md (Draft v0.1) diverge, prevalece o código. |
04, 05, 09, 18 |
| A-02 | A constante version em root.go é 0.1.0 por ser sobrescrita em build-time via -ldflags (GoReleaser); releases injetam 0.8.3. Exemplos usam 0.8.3. |
02, 05, 06, 09 |
| A-03 | report.Version = "0.1.0" é reportado fielmente e tratado como versão de contrato / namespace de fingerprint (quorum/v1), não versão do produto. |
05, 06 |
| A-04 | O Quorum é CLI/Docker only: web, RDBMS, API REST e auth são N/A por arquitetura; IA/LLM fica fora do núcleo determinístico e só aparece como camada consultiva opt-in (desligada por padrão). | 01, 03, 08, 09, 13, 15, 17, 20, 99 |
| A-05 | OSV.dev é a única dependência de rede em runtime do núcleo, opcional e com degradação graciosa; --offline a desabilita (operação air-gapped) e também bloqueia o advisor remoto. |
01, 02, 03, 12 |
| A-06 | --timeout mapeia para PerScannerTime (por scanner); o ProbeTime de 60s (defaultProbeTime) é separado e não exposto como flag na v0.8.3. |
02, 14, 99 |
| A-07 | correlationKey e confidence são determinísticos sobre os dados normalizados; a camada consultiva é apenas de apresentação e não os altera. |
01, 05 |
| A-08 | ~~polaris aparece em scannerCategory sem adapter~~ — resolvido: polaris e kube-score são adapters reais (K8S_POSTURE) desde a v0.5.0 (ver G-03), participando do consenso de postura K8s. Não há scanner fantasma. |
02, 05, 09, 16 |
| A-09 | A matriz de targets reflete Supports/Capabilities lidos do código, preservando divergências (ex.: kubescape Supports repo+k8s mas declara capability só k8s). |
02 |
| A-10 | O cache de aliases não tem TTL; gerenciamento/limpeza são manuais; melhorias listadas como proposta futura. | 02, 07 |
| A-11 | Metas de performance e SLO/SLI são alvos de engenharia, não validados por benchmark formal no repo. | 03, 20 |
| A-12 | Mapeamentos PCI/ISO/ASVS/Top10/DREAD são interpretativos do código as-is, não atestação de conformidade; scores DREAD são qualitativos. | 03, 12 |
| A-13 | Owner/repo é Martinez1991/quorum-sec-scan e o registry é ghcr.io/martinez1991/quorum-sec-scan (lowercase). |
10, 11, 99 |
| A-14 | Imagem :full é linux/amd64 (Grype DB pré-cacheado em build-time); :slim cobre amd64+arm64 com scanners no PATH, alterando perfil de performance/disponibilidade. |
03, 09, 10, 99 |
| A-15 | O consumidor em produção verifica imagem/binário (cosign + gh attestation) e pina por digest; o produto só fornece os meios. |
03, 11 |
| A-16 | Disponibilidade de distribuição depende de terceiros (GHCR/Releases/OSV) fora do controle do projeto. | 03 |
| A-17 | Logs são texto com prefixo [quorum] em stderr (não JSON por padrão, sem níveis/timestamps por linha); o consumidor da telemetria é a plataforma invocadora. |
03, 14 |
| A-18 | Repositório é público OSS (cotas gratuitas de Actions/storage); faixas pagas modelam o caso privado/excedente. Câmbio US$ 1 ≈ R$ 5,50. | 19 |
| A-19 | Licença do Quorum é Apache-2.0 (confirmada via LICENSE); licenças dos scanners empacotados são estimativas a confirmar no upstream. |
19 |
| A-20 | Tamanhos de imagem/artefato são qualitativos (inferidos dos Dockerfiles), não medidos no repo. | 10, 19 |
| A-21 | Fixtures em internal/adapter/testdata não fazem parte do caminho de execução de produção. |
13, 15 |
| A-22 | A camada consultiva é opt-in e desligada por padrão; sem --advice a saída é byte-idêntica. A Fase 0 (templates curados + refs OWASP) e a Fase 2 (RAG sobre corpus OWASP pinado por digest) são determinísticas e sem modelo; a Fase 1 (LLM local) e a Fase 3 (provider remoto) são opt-in, reprodutíveis (temperature=0 + cache) e com gates (remoto exige --advice-allow-egress, é bloqueado por --offline e recusa --fix). Todo anexo de IA é rotulado "AI-generated, advisory only". |
05, 06, 12, 13, 14, 15, 21 |
Registro de Lacunas¶
Itens não verificados na origem, divergências e dívidas conhecidas. Estes são candidatos naturais a backlog (17-backlog) e melhorias (20-melhorias).
✅ G-02, G-09, G-10 e G-11 foram resolvidos na v0.2.4 (issues #15–#18, milestone hardening v0.2.4). As linhas abaixo ficam para rastreabilidade histórica.
| ID | Lacuna | Impacto | Documentos-fonte |
|---|---|---|---|
| G-01 | Versão divergente: report.Version hardcoded 0.1.0 vs produto v0.8.3; intenção (contrato estável vs defasagem) não clara no código. |
Médio | 05 |
| G-02 | ✅ Resolvido na v0.2.4 (#18). ~~durationMs em scanners[] serializava como nanosegundos~~ — agora ScannerRun.MarshalJSON emite milissegundos, coerente com summary.durationMs. |
Médio | 06 |
| G-03 | ✅ Resolvido na v0.5.0: polaris deixou de ser dead-config e virou um adapter real (K8S_POSTURE), junto com kube-score — re-adicionados ao scannerCategory. Não há mais scanner fantasma. |
Baixo | 02, 05, 09, 16 |
| G-04 | ✅ Resolvido/aceito: cache com schemaVersion (v0.4.1). TTL e locking entre processos são intencionalmente omitidos (decisão): aliases CVE↔GHSA são fatos imutáveis (não envelhecem), e a escrita atômica (tmp+rename) já impede corrupção — perda concorrente é benigna (apenas re-lookup). |
Baixo | 07, 02 |
| G-05 | ✅ Resolvido na v0.4.2: o Load do crosswalk aceita um documento versionado (schemaVersion + controls) além da lista legada (retrocompatível), permitindo evoluir o formato. |
Baixo | 07 |
| G-06 | Grype DB congelado no build da :full — ainda pode perder CVEs recentes sem rebuild/repull (staleness por design). ⚠️ Bug corrigido na v0.2.6: faltava GRYPE_DB_VALIDATE_AGE=false, então após 5 dias o grype falhava todo scan (validação de idade do DB); agora o DB embutido não expira (só envelhece). |
Alto | 07, 18 |
| G-07 | ✅ Muito melhorado / resíduo aceito: bases @sha256; SBOM SPDX atestado (imagem) e por-binário; kubescape por SHA256; trivy/kics/dockle por digest/checksum; Grype/Syft via anchore install.sh (checksum interno). Resíduo aceito: Checkov via pip fica pinado por versão (==3.3.6) — o hash-lock pleno da árvore de deps foi deferido (alto custo de manutenção por bump + fragilidade cross-platform musl vs. baixo retorno). |
Baixo | 03, 12, 18 |
| G-08 | ✅ Resolvido (v0.4.2/v0.4.4): --metrics <arquivo> exporta Prometheus textfile e --log-format json emite os logs de progresso como JSON lines ({ts,level,msg}) para ingestão. |
Baixo | 03, 14 |
| G-09 | ✅ Resolvido na v0.2.4 (#15). ~~--output sem Clean (perm 0644)~~ — agora filepath.Clean + escrita com perm 0o600 (R3). |
Alto | 12 |
| G-10 | ✅ Resolvido na v0.2.4 (#16). ~~id da OSV sem url.PathEscape/validação~~ — agora validado (^[A-Za-z][A-Za-z0-9._-]{0,127}$) + url.PathEscape (R6). |
Médio | 12 |
| G-11 | ✅ Resolvido na v0.2.4 (#17). ~~ref do alvo sem rejeição de -~~ — agora o boundary da CLI recusa target iniciando com - (R1 argument injection). |
Médio | 12 |
| G-12 | ✅ Resolvido (v0.4.1/v0.4.4): runCmd limita o stdout do scanner (512 MiB, QUORUM_MAX_OUTPUT_BYTES) (R2) e há cap de tamanho de alvo para repo/k8s (20 GiB, QUORUM_MAX_TARGET_BYTES, walk com early-abort) (R5). |
Baixo | 12 |
| G-13 | aliases.json sem integridade/assinatura (perm 0644): risco de cache poisoning (R7). |
Médio | 12 |
| G-14 | Sem redaction de valores de segredo no relatório (R8). | Médio | 12 |
| G-15 | Cobertura de testes não coletada no CI; internal/{model,purl,consensus,crosswalk} sem _test.go dedicado; e2e não-determinístico (gate só checa multiDetected>=1). |
Médio | 15 |
| G-16 | ✅ Resolvido. ~~Tag móvel v0 movida manualmente~~ — agora o workflow .github/workflows/tag-major.yml avança v0/v0.2 automaticamente a cada release semver. |
Baixo | 11, 99 |
| G-17 | ⚠️ Parcialmente medido: tamanhos das imagens confirmados — :full ≈ 3,3 GB, :slim ≈ 27 MB (2026-07-03). Minutos de Actions e storage GHCR continuam sob cotas do provedor (variáveis); benchmarks de performance seguem como alvo. |
Baixo | 19, 03, 10, 20 |
| G-18 | ✅ Resolvido: THIRD_PARTY_NOTICES.md lista os scanners empacotados (todos Apache-2.0), e a SBOM SPDX atestada por release é a lista autoritativa de componentes/licenças. | Médio | 19 |
| G-19 | ⚠️ Reduzido: cobertura de testes agora coletada no CI (~60%), com testes novos em purl/model/consensus/crosswalk e nos fluxos de segurança; a verificação linha-a-linha exaustiva de todos os adapters/reporters permanece um caveat documental (não bloqueante). | Baixo | 02, 04, 09, 12, 20 |
Perguntas em aberto (para stakeholders)¶
Decisões que dependem de produto/mantenedores e que destravam ou ajustam a documentação.
Produto e escopo
- [x] Polaris: virará adapter ou a entrada em
scannerCategorydeve ser removida? (G-03) — ✅ resolvido:polaris+kube-scoresão adapters reais (K8S_POSTURE) desde a v0.5.0. - [ ] kubescape: a divergência
Supportsrepo+k8s vs capability só k8s é intencional? Pode confundir usuários em alvosrepo. (A-09) - [ ] Há apetite por perfis de imagem adicionais (
:sca/:iac/:k8s) ou o par:full/:slimé definitivo? - [ ] Há apetite por
--format table/markdowne PR decoration mantendo o produto estritamente CLI (automação só no Action)?
Contratos e versionamento
- [ ]
report.Versiondeve refletir a versão do produto via ldflags ou é versionamento de contrato independente proposital? (G-01) - [ ] O dump de
[]MergedFindingno campofindingsdo JSON (comMemberscompletos) é contrato estável ou detalhe interno sujeito a mudança? - [ ]
durationMsemscanners[]deveria ser convertido para milissegundos (coerência comsummary)? (G-02) - [ ] Pretende-se publicar oficialmente o JSON Schema (
quorum-report-v1.json) como arquivo versionado?
Configuração e operação
- [ ] O ProbeTime de 60s deve ser exposto como flag de CLI/Action ou permanece interno? (A-06)
- [ ] Introduzir
schemaVersionnoaliases.jsone/ou nos YAML de crosswalk para migração explícita? (G-04, G-05) - [ ] Oferecer TTL configurável ou comando
quorum cache clearpara o cache de aliases? (A-10) - [ ] Crosswalk customizado deveria mesclar com o bundled (em vez de substituir) quando
--crosswalkaponta para outro diretório? - [ ] Qual a cadência oficial recomendada para rebuild/repull da imagem
:full(Grype DB fresco)? (G-06)
Camada consultiva (IA)
- [ ] O default
--advice-providerdeve algum dia ir além denone, ou o default opt-in-only permanece a política? (A-22) - [ ] Quais endpoints/modelos locais são oficialmente suportados/documentados para
--advice-provider=local(ex.: Ollama)? - [ ] Qual a cadência para refrescar e re-atestar o corpus OWASP pinado por digest (
quorum advise-index)?
Supply chain, segurança e CI
- [ ] Há plano de endurecer todos os scanners do
Dockerfile.fullpara@sha256e gerar SBOM da:full? (G-07) - [ ]
release.ymlpublica atestação SLSA + assinatura cosign para ambas as imagens (:fulle:slim), os binários e o knowledge pack? - [ ] Há intenção de mirror interno/configurável da OSV (BaseURL por env) para air-gapped além do
--offline? - [ ] SAST (golangci-lint/gosec/CodeQL) e secret scanning (gitleaks) entram no
ci.ymlou em workflow dedicado? - [ ] Deve haver gate de cobertura bloqueante no CI e qual a meta oficial (sugestão: 80% global / 90% núcleo)? (G-15)
- [ ] Deve rodar self-scan (dogfooding) das imagens publicadas no
release.ymlantes do push? - [x] A tag móvel
v0será movida por automação após o release? (G-16) — ✅ sim, viatag-major.yml. - [ ] Existe branch protection com required checks (ci/e2e) configurada nas settings do GitHub a refletir formalmente?
Negócio e governança
- [ ] O repositório é público (cotas OSS) ou privado (sujeito a overage)? Há orçamento/headcount real ou regime voluntário? (A-18)
- [ ] Qual a política de retenção/GC de tags antigas no GHCR? (G-17)
- [ ] Confirmar oficialmente a licença de cada scanner empacotado e a obrigação de incluir NOTICE de terceiros na
:full. (G-18) - [ ] Deve haver warning automático para o caso "todos scanners
ranmas 0 findings" ou isso fica só na documentação?
Premissas¶
Premissas específicas deste índice (além das consolidadas acima):
- O TOC foi construído a partir de um
Glob docs/*.mdreal (21 documentos presentes além deste índice); as descrições de uma linha derivam dos H1 e do escopo conhecido de cada arquivo. - Os Registros de Premissas, Lacunas e Perguntas consolidam o conteúdo das seções homônimas dos documentos 01–20 e 99; cada item referencia os documentos-fonte para rastreabilidade.
- A classificação de impacto das lacunas (Baixo/Médio/Alto) é qualitativa e serve para priorização, não é medição.
- Cross-links usam caminhos relativos
NN-arquivo.mde assumem que todos os arquivos listados no TOC permanecem no diretóriodocs/.
Metadados¶
| Campo | Valor |
|---|---|
| Produto | Quorum (quorum-sec-scan) |
| Versão documentada | v0.8.3 (AS-IS) |
| Fonte de verdade | branch main |
| Scanners | 12 (trivy, grype, checkov, kics, dockle, kubescape, polaris, kube-score, terrascan, tfsec, regula, conftest) |
| Linguagem | Go 1.26 (CLI com cobra) |
| Camada consultiva | Opt-in --advice (desligada por padrão); Fases 0–3 implementadas (internal/enrich, internal/rag, internal/advisor, internal/evals) |
| Distribuição | Docker GHCR :full (linux/amd64) / :slim (amd64+arm64) + binários GoReleaser; cosign keyless, SLSA build-provenance e SBOM SPDX atestado (imagem e por-binário), mais atestação do knowledge-pack |
| Owner/repo | Martinez1991/quorum-sec-scan |
| Registry | ghcr.io/martinez1991/quorum-sec-scan |
| Licença | Apache-2.0 |
| Idioma da doc | pt-BR |
| Data de revisão | 2026-07-04 |
| Status | Em revisão — pendente de respostas dos stakeholders (ver "Perguntas em aberto") |