Checklists¶
Este documento reúne cinco checklists acionáveis para o ciclo de vida do
Quorum (quorum-sec-scan, v0.8.3): Desenvolvimento, QA, Segurança,
Deploy/Release e Produção/Operação. Cada item é específico ao fluxo real do
projeto — uma ferramenta CLI/Docker de consensus security scanning escrita
em Go 1.26, distribuída como imagens assinadas no GHCR e binários nativos via
GoReleaser. Os itens são verificáveis (com um comando ou critério de aceite) e
ancorados no comportamento do código (cmd/quorum, internal/*) e dos
workflows (.github/workflows/{ci,e2e,release,tag-major}.yml, action.yml).
Princípio que atravessa todas as checklists: "false split > false merge" e "0 findings não é prova de segurança". Um item só está "pronto" quando você consegue provar que os scanners rodaram (status
ran) — não quando o relatório voltou vazio.
Links úteis: Visão geral · Arquitetura · DevOps · Infraestrutura · Observabilidade · Roadmap.
Mapa do fluxo (onde cada checklist atua)¶
flowchart LR
DEV["1. Desenvolvimento\n(branch + código + testes locais)"]
PR["Pull Request → main"]
CI["CI: ci.yml + e2e.yml\n(vet, test -race, coverage, build, consenso real)"]
QA["2. QA\n(verificação funcional + testes de contrato)"]
SEC["3. Segurança\n(fronteira de confiança, supply chain)"]
MERGE["Merge na main"]
TAG["Tag semver vX.Y.Z"]
REL["4. Deploy/Release\nrelease.yml: imagens + binários\ncosign + SLSA + SBOM atestados"]
OPS["5. Produção/Operação\nmount, socket, fail-on, baseline, verificação"]
DEV --> PR --> CI
CI --> QA
CI --> SEC
QA --> MERGE
SEC --> MERGE
MERGE --> TAG --> REL --> OPS
OPS -. feedback / triagem de baseline .-> DEV
| Estágio real | Gatilho | Workflow / artefato | Checklist |
|---|---|---|---|
| Código numa branch | trabalho local | make test/vet/build |
1. Desenvolvimento |
PR para main |
pull_request |
ci.yml, e2e.yml |
2. QA |
| Revisão da cadeia | PR / pré-release | release.yml, action.yml, Dockerfile.full |
3. Segurança |
Tag vX.Y.Z |
push de uma tag semver |
release.yml (imagens+binários) |
4. Deploy/Release |
Tag móvel v0/v0.8 |
release publicado |
tag-major.yml (auto-avança) |
4. Deploy/Release |
| Uso em pipeline | docker run / action |
imagem :full/:slim |
5. Produção/Operação |
1. Checklist de Desenvolvimento¶
Objetivo: garantir que uma mudança seja fiel à arquitetura do Quorum, passe pelos
gates locais antes do PR e honre os contratos dos adapters. Reproduz localmente o
que o ci.yml exige.
1.1 Setup e branch¶
- [ ] Go 1.26+ instalado (
go version) — é a versão fixada emci.yml,e2e.ymlerelease.yml. - [ ] Trabalho feito numa branch a partir da
main(nunca commit direto namain); o fluxo é sempre via PR. - [ ] Scanners OSS necessários no
PATHpara teste manual ponta a ponta, ou uso da imagem:full. Há 12 adapters registrados (internal/adapter/*.go, viainit()/Register): - [ ] VULN/SCA:
trivy,grype. - [ ] MISCONFIG/IaC:
trivy,checkov,kics,terrascan,tfsec,regula(+conftestpara policy-as-code). - [ ] K8S_POSTURE:
kubescape,polaris,kube-score. - [ ] IMG_HARDENING:
dockle. - [ ] SECRET:
trivy(com redação doMatch). - Ferramentas ausentes são reportadas como
unavailablee não quebram o build.
1.2 Aderência à arquitetura (as-is)¶
- [ ] A mudança respeita as fronteiras de pacotes:
cmd/quorum(CLI cobra) vs.internal/{adapter,orchestrator,correlate,consensus,alias,cache,crosswalk,filter,model,purl,report,severity}. - [ ] Nada introduz dependência de um frontend web, banco de dados relacional ou API REST — fora do escopo do produto (apenas CLI/Docker).
- [ ] O núcleo determinístico permanece sem IA: qualquer IA/LLM vive na
camada consultiva opt-in (
internal/{enrich,rag,advisor}), está desligada por padrão e é apenas de apresentação — nunca tocacorrelationKey,fingerprint,confidence, severidade agregada ou o gate de fail-on. - [ ] Nova saída/normalização converge para o modelo canônico
model.Finding(nenhum formato bruto de scanner vaza para fora do adapter). Os novos campos consultivos (Remediation,References,Advice) pendem deMergedFindinge são preenchidos apenas sob--advice. - [ ] Se a mudança afeta a correlação, o
correlationKeypermanece determinístico por tipo (VULN/MISCONFIG/K8S_POSTURE/etc —DESIGN §6) e o princípio false split > false merge se sustenta (na dúvida, isolar e marcarunmapped). - [ ] O secret/
Matchdo Trivy é redigido antes de sair do adapter (não vazar uma credencial para o relatório).
1.3 Adapters (quando aplicável)¶
- [ ] O adapter implementa toda a interface
Adapter:Name/Version/Supports/Capabilities/Run. - [ ] Existe um teste de contrato contra um fixture versionado em
internal/adapter/testdata(uma mudança de formato deve quebrar o teste antes de quebrar a produção). - [ ]
Version(ctx)é leve o bastante para o probe de 60s (Options.ProbeTime) e distingue corretamente ausência vs. lentidão. - [ ]
Supports(target)reflete os alvos reais do scanner (ex.:grypenão suportak8s;dockle/kube-scoresão single-target;trivysuporta os três tipos). - [ ] Passthrough honrado: o adapter anexa
extraArgs(<name>)(lido deQUORUM_<NAME>_ARGS) aos seus argumentos, sem quebrar o parse da saída. - [ ] Buffer de stdout limitado por
QUORUM_MAX_OUTPUT_BYTES(padrão 512 MiB) — saída acima disso é abortada com um erro claro (anti-OOM).
1.4 Camada consultiva (quando aplicável)¶
- [ ] Fase 0 (determinística, sem modelo): templates de remediação curados +
referências OWASP casados por
canonicalControl/ruleId/category/type(pacoteinternal/enrich; dados emknowledge/*.yaml— aws/azure/gcp/k8s/image/categories). Templates novos/editados mantêm a saída byte-idêntica quando--adviceestá desligado. - [ ] Fase 2 (RAG-as-artifact, determinística): recuperação a partir de um corpus
OWASP versionado e com digest fixado (
knowledge/owasp/corpus.yaml, pacoteinternal/rag). Recuperação lexical por padrão (sem modelo); semântica apenas quando o corpus é embedado viaquorum advise-index, e oscanescolhe automaticamente a semântica quando o corpus tem vetores — o digest fixado é preservado. - [ ] Fase 1 (LLM local opt-in,
internal/advisor): reproduzível viatemperature=0+ um cache em disco chaveado porfingerprint+provider+model;--fix=suggestprecisa passar por um re-scan verify-the-fix (aplicar numa cópia temporária, re-escanear com o mesmo scanner, manter só se o finding sumiu e o arquivo parseia) e nunca aplica automaticamente. Degradação graciosa: se o modelo estiver inacessível o relatório sai sem o conselho de IA e o scan nunca falha. - [ ] Fase 3 (provedor remoto opt-in): envia apenas o finding normalizado, nunca
código-fonte; condicionada a
--advice-allow-egress, bloqueada por--offlinee recusa--fix. - [ ] Todo anexo de IA é rotulado "AI-generated, advisory only".
- [ ] Evals atualizados quando o comportamento consultivo muda:
internal/evalsmede a cobertura determinística de remediação, a relevância das referências OWASP e a taxa de verify-the-fix (roda no CI, sem modelo pesado).
1.5 Gates locais (espelho do ci.yml)¶
- [ ]
make vet(ougo vet ./...) sem findings. - [ ]
make test/go test -race ./...verde (testes unitários + de contrato + de eval); cobertura reportada no CI. - [ ]
make build/go build -trimpath -o dist/quorum ./cmd/quorumcompila. - [ ] Smoke:
./dist/quorum list-scannerslista os 12 adapters registrados. - [ ] Teste funcional manual:
./dist/quorum scan <target> --format jsonproduz um relatório e o resumo em stderr mostra o status por scanner. - [ ] Smoke consultivo (opcional):
./dist/quorum scan <target> --adviceanexa remediação/referências determinísticas sem alterar os fingerprints; o mesmo scan sem--adviceproduz saída byte-idêntica.
1.6 Higiene do PR¶
- [ ] Crosswalk novo/alterado em
crosswalk/*.yamlsegue o schema e o hub por família de nuvem/plataforma: - [ ]
aws.yaml/azure.yaml/gcp.yaml— hub AVD (S3/IAM/EBS/SG/RDS/ KMS/CloudTrail/VPC-flow-logs; Azure Storage/Key Vault; GCP bucket/ firewall/SQL). - [ ]
k8s.yaml— hub C-#### (kubescape) correlacionandokubescape×polaris×kube-score(privilege-escalation, privileged, non-root, limites de cpu/mem, probes, read-only-fs, linux-hardening, automount-SA, network-policy, host-network, host-PID/IPC, capabilities, secrets). - Uma regra sem mapeamento não é "adivinhada" (permanece
unmapped); o crosswalk é derivado de saída real (favorece false split sobre false merge). - [ ] Uma mudança em
./policy(Rego) paraconftestvem com um teste — oconftestnão tem regras próprias, ele avalia SEU Rego (padrão./policy). - [ ] Documentação atualizada quando o comportamento muda (
README.md,README.pt-BR.md,DESIGN.md, estedocs/e a documentação publicada no GitHub Pages via MkDocs Material). - [ ] PR aberto contra
main; aguardaci.ymlee2e.ymlverdes.
2. Checklist de QA¶
Objetivo: validar o comportamento observável do Quorum — consenso real, exit
codes, formatos e transparência de status — não apenas "os testes unitários
passaram". Ancorado no e2e.yml, que roda scanners reais (não fixtures).
2.1 Suíte automatizada (PR)¶
- [ ]
ci.ymlverde: vet +go test -race ./...+ cobertura + build + smoke. - [ ]
e2e.ymlverde nos cenários de consenso: - [ ] IaC/MISCONFIG (Trivy + Checkov/KICS/tfsec/terrascan/regula sobre
examples/terraform) comsummary.multiDetected >= 1. - [ ] SCA/VULN (Trivy + Grype sobre
alpine:3.10) comsummary.multiDetected >= 1. - [ ] K8S_POSTURE (kubescape × polaris × kube-score) correlacionando
via
crosswalk/k8s.yaml. - [ ] Testes de contrato dos adapters cobrem o fixture atualizado da versão real da ferramenta.
2.2 Transparência de execução (status por scanner)¶
- [ ] O relatório expõe status por scanner:
ran | skipped | unavailable | error | timeout. - [ ] O cenário "ferramenta ausente" produz
unavailablee não falha o scan. - [ ] O cenário "timeout por scanner" (
--timeoutcurto) produz statustimeoute uma mensagem de erro associada, nãoran. - [ ]
conftestsem políticas em./policyreportaerror(esperado — policy-as-code é opt-in), nãorancom 0 findings. - [ ] Validar manualmente que "0 findings" vem acompanhado dos status — um 0 com
tudo
rané diferente de um 0 com tudounavailable.
2.3 Exit codes (gate)¶
| Cenário de teste | Comando | Exit esperado |
|---|---|---|
Sem --fail-on, ou nada atinge o limiar |
scan … |
0 |
Finding ≥ --fail-on |
scan … --fail-on high |
1 |
| Erro de uso / runtime | scan sem target, --type inválido, --log-format inválido |
2 |
- [ ]
0quando nenhum finding atinge--fail-on(ou a flag está ausente). - [ ]
1quando há um finding com severidade ≥--fail-on(gate dispara, loggate: found … >= --fail-on … → exit 1). - [ ]
2em erro de uso/runtime (ex.:--fail-oninválido,--formatinválido,--log-formatdiferente detext|json, uma baseline inexistente passada explicitamente via--baseline, um target começando com-recusado, um target acima deQUORUM_MAX_TARGET_BYTES, um--advice-providerinválido, ou--advice-provider=remotesem--advice-allow-egress).
2.4 Formatos de saída e telemetria¶
- [ ] SARIF (padrão): contém
partialFingerprints["quorum/v1"]=sha256(correlationKey)eproperties.detectedBy/detectionCount/confidence. - [ ] JSON: campo
fingerprint,summary.multiDetected,scanners[]com status e contagem, rollup de severidade. - [ ] XML: a mesma estrutura serializada (pipelines legadas/estilo JUnit).
- [ ]
--output/-oescreve num arquivo: o caminho passa porfilepath.Clean, cria o diretório pai se preciso e escreve com perm0600(o relatório pode conter detalhe sensível); sem-oescreve em stdout. - [ ]
--metrics <file>escreve métricas em formato texto Prometheus (textfile collector), perm0644(contagens não sensíveis). - [ ]
--log-format text|jsoncontrola o log de progresso em stderr (jsonemite{ts,level,msg}).
2.5 Severidade, baseline e min-severity¶
- [ ]
--min-severityremove findings abaixo do limiar do relatório e do gating; as supressões são logadas (filtered: … below min-severity <sev>). - [ ]
--baseline/.quorumignoresuprime porfingerprintoucorrelationKey; as supressões são sempre logadas (nunca descartadas silenciosamente; o log carrega a contagem de entradas e de itens suprimidos). - [ ] Uma linha de comentário (
#) e linhas em branco no.quorumignoresão ignoradas corretamente.
2.6 Resolução de aliases¶
- [ ] Com rede:
CVE-…(Trivy) eGHSA-…(Grype) para o mesmo bug correlacionam (alias local → cache~/.cache/quorum/aliases.json→ OSV.dev, CVE preferido). O id OSV é validado e passa porurl.PathEscape. - [ ]
--offline: nenhuma chamada à OSV; degradação graciosa (usa aliases locais + cache). - [ ] Uma falha de rede simulada não derruba o scan (degradação graciosa).
- [ ] O cache de aliases é escrito com perm
0600e carrega umschemaVersioncompatível (um arquivo corrompido/de versão antiga é ignorado, não quebra).
2.7 Camada consultiva (apenas sob --advice)¶
- [ ] Byte-idêntico sem
--advice: o mesmo scan com e sem a flag produz saída idêntica (a camada consultiva é só de apresentação; nunca tocacorrelationKey/fingerprint/confidence/severidade/o gate). - [ ] A Fase 0 anexa
Remediation/Referencesdeterminísticos casados por controle/regra/categoria/tipo; sem necessidade de rede. - [ ] Fase 2: a recuperação lexical funciona com o corpus de digest fixado offline;
após
quorum advise-index, oscanescolhe automaticamente a recuperação semântica. - [ ]
--advice-provider=localdegrada graciosamente quando o endpoint está inacessível (relatório sai sem o conselho de IA, scan não falha); reproduzível viatemperature=0+ cache por fingerprint. - [ ]
--fix=suggestsó mantém um patch que passa no re-scan verify-the-fix (finding sumiu + arquivo ainda parseia) e nunca aplica automaticamente. - [ ]
--advice-provider=remoteenvia apenas o finding normalizado (títulos, caminhos, controles — nunca o fonte), exige--advice-allow-egress, é bloqueado por--offlinee recusa--fix. - [ ] Todo anexo de IA é rotulado "AI-generated, advisory only".
- [ ] Métricas sob
--advicepresentes quando--metricsé usado:quorum_advice_enriched{kind=remediation|references|recommendation},quorum_advice_provider{provider},quorum_advice_fix{stage=proposed|verified}(verified/proposed = a taxa de verify-the-fix).
3. Checklist de Segurança¶
Objetivo: tratar a própria cadeia do Quorum como uma fronteira de confiança e
validar as garantias de supply chain (DESIGN §12). Cobre tanto o que o Quorum
produz quanto o que ele consome (binários de scanner empacotados).
3.1 Supply chain do release¶
- [ ] Imagens são assinadas com cosign sem chave (OIDC), sobre o digest do manifest, com retry — verificar antes de usar:
- [ ] Atestação de build-provenance SLSA presente e verificável (imagem):
- [ ] SBOM SPDX atestado (
actions/attest-sbom, via syft) verificável — além da atestaçãosbom: truedo BuildKit: - [ ] Binários nativos:
checksums.txt+ assinatura cosign (cosign verify-blob) + atestação SLSA porsubject-checksums(gh attestation verify quorum_<ver>_<os>_<arch>.tar.gz --repo …) + SBOM SPDX por binário (GoReleaser/syft). - [ ] Knowledge pack atestado: o knowledge pack consultivo + crosswalk recebem
uma atestação de build-provenance SLSA a cada release (job
knowledgedorelease.yml) — verifique o corpus antes de confiar na camada consultiva offline: - [ ] O próprio
release.ymlre-verifica a atestação (imagem e binário) como etapa do release, com retry — um release com atestação quebrada deve falhar.
3.2 Permissões e identidade no CI¶
- [ ]
release.ymlmantémpermissionsmínimas:contents: read(jobimages),packages: write,id-token: write(cosign keyless),attestations: write(SLSA + SBOM + knowledge pack). - [ ] O job
binariesusacontents: writeapenas para criar o release (maisid-token/attestations: write). - [ ] O gatilho de release é restrito a tags semver
v[0-9]+.[0-9]+.[0-9]+— tags móveis (v0,v0.8, usadas para fixar a action) não disparam um build; elas são avançadas portag-major.ymlno eventorelease.
3.3 GitHub Action composta (action.yml)¶
- [ ] Por padrão
verify: "true"→ cosign-verifica a imagem:fullantes de rodá-la (instala o cosign se ausente). - [ ] Em produção,
imageé fixada por@sha256:<digest>(não uma tag móvel) e a action é fixada por@<sha>. - [ ]
docker-socketrevisado: paratype: imageo socket/var/run/docker.socké auto-montado (evita um falso-zero ao escanear uma imagem local recém-buildada);offdesativa mesmo para imagem,trueforça para outros tipos. Sem o socket, um scan de imagem local emite um warning. - [ ] Inputs de passthrough (
trivy-args,grype-args,checkov-args,kics-args,dockle-args,kubescape-args) revisados — podem carregar secrets (ex.:checkov --bc-api-keypara Prisma/Bridgecrew) e por isso não são ecoados no log. - [ ] Inputs consultivos revisados:
advice,advice-provider,advice-endpoint,advice-model,advice-embed-model,advice-max,advice-cache,advice-allow-egress,advice-api-key,fix. Paralocala action auto-adicionahost-gateway; pararemoteaadvice-api-keyé encaminhada via env (nunca na linha de comando) e o egress exige consentimento explícito. - [ ] Inputs sensíveis (
baseline,crosswalk,offline) revisados quanto a impacto de segurança (ex.: uma baseline não estar suprimindo um risco real).
3.4 Binários de scanner empacotados (imagem :full)¶
- [ ] Reconhecido que os binários OSS empacotados fazem parte da fronteira de
confiança do consumidor (
THIRD_PARTY_NOTICES.mdlista as licenças). - [ ] Bases de imagem fixadas por
@sha256; downloads de scanner (kubescape,tfsec,terrascan,regula,conftest) verificados por checksum noDockerfile.full. - [ ] DB do Grype pré-cacheado no
:full, de fonte confiável (Anchore), buildado comGRYPE_DB_VALIDATE_AGE=false(não expira em runners sem egress) — a versão bate com o schema suportado.
3.5 Seguro por padrão (hardening)¶
- [ ]
--offlinedisponível para ambientes sem egress (desliga a OSV e bloqueia--advice-provider=remote). - [ ] O egress de IA é desligado por padrão e opt-in:
--advice-provider=remoteexige--advice-allow-egressexplícito, envia apenas o finding normalizado (nunca o fonte) e recusa--fix.--advice-provider=locale as fases determinísticas nunca saem do host. - [ ] Injeção de argumento bloqueada: um target começando com
-é recusado (use./-name). - [ ] Limites anti-DoS ativos:
QUORUM_MAX_OUTPUT_BYTES(512 MiB) eQUORUM_MAX_TARGET_BYTES(20 GiB) — sobrescrever/desativar por env. - [ ]
--outputnormalizado (filepath.Clean) e escrito com perm0600; métricas com0644. - [ ] Supressões (
--baseline,--min-severity) são auditáveis: sempre logadas; a revisão garante que nenhuma entrada está mascarando um finding ativo. - [ ] Cache de aliases (
~/.cache/quorum/aliases.json, perm0600, comschemaVersion) tratado como dado não confiável/derivado (pode ser apagado sem perda de correção); o cache consultivo (--advice-cache) é igualmente derivado e seguro de apagar. - [ ] O secret do Trivy (
Match) é redigido — o relatório não vaza uma credencial. - [ ] Falsos negativos por um mount malformado são prevenidos (ver
checklist 5.1) — um
/workvazio reporta 0 findings.
4. Checklist de Deploy/Release¶
Objetivo: executar um release reproduzível e assinado. O release é disparado por um
push de uma tag semver vX.Y.Z; release.yml builda/publica imagens
(:full, :slim) e binários (GoReleaser), assina e atesta tudo (cosign + SLSA +
SBOM SPDX + knowledge pack).
4.1 Pré-tag¶
- [ ]
mainestá verde (ci.yml+e2e.yml) no commit a ser tagueado. - [ ] A versão escolhida segue semver estrito
vX.Y.Z(ex.:v0.8.3) — orelease.ymlsó dispara parav[0-9]+.[0-9]+.[0-9]+. - [ ] CHANGELOG/notas conferidos; o GoReleaser tem histórico completo
(
fetch-depth: 0) para gerar o changelog. - [ ] O crosswalk empacotado revisado (
crosswalk/{aws,azure,gcp,k8s}.yaml) — é empacotado em/opt/quorum/crosswalknas imagens e binários. - [ ] Políticas Rego em
./policy(se houver) revisadas — vão junto para uso doconftest. - [ ] O knowledge pack consultivo revisado (
knowledge/*.yaml,knowledge/owasp/corpus.yaml) — o digest fixado do corpus está intacto e o pack vai empacotado para a Fase 0/2 offline.
4.2 Disparando o release¶
- [ ] Tag criada e enviada:
- [ ] O workflow
release.ymliniciou para a tag (não para uma tag móvel).
4.3 Imagens (job images)¶
- [ ]
:fullpublicada emlinux/amd64com as tags:full,:<version>,:<version>-full,:latest(todos os 12 scanners empacotados; DB do Grype pré-cacheado). - [ ]
:slimpublicada emlinux/amd64,linux/arm64com as tags:slim,:<version>-slim(apenas o orquestrador). - [ ]
provenance: trueesbom: trueno build-push (BuildKit). - [ ]
cosign sign(com retry) aplicado ao digest do manifest (cobre todas as tags que apontam para ele). - [ ]
actions/attest-build-provenancegerou e enviou a atestação SLSA para o GHCR. - [ ]
actions/attest-sbomgerou e enviou o SBOM SPDX atestado (syft →sbom.spdx.json). - [ ] A etapa "Verify provenance attestation" passou (re-checagem ponta a ponta, com retry).
4.4 Binários (job binaries, apenas em tag)¶
- [ ] GoReleaser publicou arquivos por OS/arch +
checksums.txt+ assinatura cosign, com SBOMs SPDX por binário (syft). - [ ] Atestação SLSA por
subject-checksums: dist/checksums.txtgerada. - [ ] A etapa de verificação ("spot-check" de um artefato) passou (com retry).
4.5 Knowledge pack (job knowledge)¶
- [ ] O knowledge pack consultivo + crosswalk receberam uma atestação de build-provenance SLSA neste release — verifique antes de confiar na camada consultiva:
4.6 GitHub Action / tag móvel¶
- [ ] Tag móvel
v0(ev0.8) auto-avançada portag-major.ymlno eventorelease— pin da actionuses: Martinez1991/quorum-sec-scan@v0. - [ ] Mover
v0/v0.8não dispara um novo build de release (o gatilho é restrito a semver).
4.7 Validação pós-publicação (lado do consumidor)¶
- [ ]
cosign verifyda imagem recém-publicada OK (ver 3.1). - [ ]
gh attestation verifyda imagem (provenance e SBOM), de um binário, e do corpus de knowledge OK. - [ ]
docker run --rm … :full list-scannerslista os 12 scanners empacotados. - [ ] Smoke real: um scan de um target conhecido produz consenso (
detectionCount > 1em pelo menos um finding).
sequenceDiagram
participant Dev
participant GH as GitHub (tag vX.Y.Z)
participant REL as release.yml
participant GHCR
participant Sigstore as Sigstore/OIDC
Dev->>GH: git push origin vX.Y.Z
GH->>REL: trigger (apenas semver)
REL->>GHCR: build & push :full / :slim (+SBOM/provenance BuildKit)
REL->>Sigstore: cosign sign (digest, keyless, retry)
REL->>GHCR: atesta build-provenance SLSA
REL->>GHCR: atesta SBOM SPDX (syft)
REL->>GHCR: atesta knowledge pack (SLSA)
REL->>GHCR: gh attestation verify (re-check, retry) ✓
REL->>GH: release GoReleaser (binários + checksums + sig + SBOM)
GH->>GH: tag-major.yml avança v0 / v0.8
5. Checklist de Produção/Operação¶
Objetivo: rodar o Quorum corretamente em pipelines, evitar o falso negativo
clássico (mount errado / socket ausente) e operar o gate com confiança. Aplica-se a
um docker run direto, a container:/CI e à action composta.
5.1 Mount correto e socket do Docker (o erro nº 1)¶
- [ ] Fonte montada em
/workcom os dois-pontos corretos do separadorhost:container: - [ ] Linux/macOS:
-v "$PWD:/work" - [ ] PowerShell:
-v "${PWD}:/work" - [ ] cmd.exe:
-v "%cd%:/work" - [ ] Não use um mount malformado como
-v "%cd%/work"(sem:), que monta um/workvazio → reporta 0 findings para tudo (falso negativo). - [ ] Workdir do contêiner coerente (
-w /work) quando o target é.. - [ ] Scan de imagem local (
--type imagede uma imagem recém-buildada): montar o socket do daemon do host, senão a imagem é invisível de dentro do contêiner → falso-zero: - [ ]
docker run:-v /var/run/docker.sock:/var/run/docker.sock. - [ ] Action: auto-montado para
type: image(opt-outdocker-socket: "off", forçar com"true"). - [ ] Validação anti-falso-negativo: confirmar no resumo que os scanners estão
ran(nãounavailable) e que o número de arquivos analisados faz sentido.
5.2 Verificar antes de rodar¶
- [ ] Imagem verificada com cosign antes do uso (ou
verify: truena action) — ver 3.1. - [ ] SLSA + SBOM verificados quando a política exige (
gh attestation verifypara provenance e para o SBOM SPDX); verifique a atestação do corpus de knowledge ao depender da camada consultiva offline. - [ ] Em produção, a imagem é fixada por
@sha256:<digest>e a action por@<sha>.
5.3 Configuração do scan¶
- [ ]
--typecorreto (image|repo|k8s) ou confirmado que a inferência (caminho existente →repo, senãoimage) acerta o target certo. - [ ]
--scannersdefine o pool desejado (ou é omitido para todos que suportam o target) — lembre quegrypenão fazk8sedockle/kube-scoresão single-target. - [ ]
--crosswalk: usando o/opt/quorum/crosswalkempacotado (auto-detectado na imagem quando./crosswalkestá ausente) ou apontando para seus próprios mapeamentos; o log inicial mostracrosswalk=N rules (<dir>). - [ ]
conftest: políticas Rego em./policy(ouQUORUM_CONFTEST_ARGS="--policy <dir>") — sem elas o scanner fica emerror, o que é esperado. - [ ] Passthrough por scanner via
QUORUM_<SCANNER>_ARGSquando precisar ampliar a cobertura ou destravar políticas (ex.:QUORUM_CHECKOV_ARGS="--bc-api-key <key> …"). Trate como secret (não ecoe). - [ ]
--timeoutpor scanner adequado ao runner (padrão5m); se houverunavailablede um probe lento/OOM (60s), aumente a memória do contêiner ou reduza--scanners. - [ ] Limites anti-DoS ajustados se preciso:
QUORUM_MAX_OUTPUT_BYTES(512 MiB),QUORUM_MAX_TARGET_BYTES(20 GiB).
5.4 Gate de build¶
- [ ]
--fail-on <sev>definido por política (o gate dispara exit1). - [ ] O pipeline trata os exit codes corretamente:
0ok ·1gate ·2erro (não confundir1com2). - [ ]
--min-severityusado para reduzir ruído sem mascarar o gate (revise que o limiar não esconde a severidade do--fail-on).
5.5 Baseline e triagem contínua¶
- [ ]
.quorumignoreversionado, com um fingerprint/correlationKey por linha + um comentário de justificativa + uma data de revisão. - [ ] Fingerprints copiados do próprio relatório
(
partialFingerprints["quorum/v1"]no SARIF /fingerprintno JSON). - [ ] Supressões revisadas periodicamente (toda supressão é logada — audite o log do CI).
5.6 Integração, artefatos e telemetria¶
- [ ] SARIF publicado no GitHub code scanning / DefectDojo (dedupe gratuito via
partialFingerprints). - [ ] O relatório (
-o quorum.sarif/.json/.xml, perm0600) salvo como artefato do pipeline (sempre, inclusive numa falha de gate). - [ ]
--metrics <file>exportado para o textfile collector do Prometheus quando existe observabilidade (contagens por scanner/severidade; maisquorum_advice_*quando--adviceestá ligado). - [ ]
--log-format jsonhabilitado quando o agregador de logs consome NDJSON. - [ ] Ambiente sem egress:
--offlineligado (desliga a OSV e bloqueia o advice remoto; o consenso de alias recai no cache local). O DB do Grype no:fullnão expira.
5.7 Camada consultiva opcional¶
- [ ] A camada consultiva é desligada por padrão; habilite com
--advicequando quiser remediação/referências legíveis anexadas — a saída permanece só de apresentação e nunca muda o gate. - [ ] As Fases 0/2 rodam offline e deterministicamente (templates curados + o
corpus OWASP de digest fixado);
quorum advise-indexembeda o corpus para recuperação semântica, preservando o pin. - [ ]
--advice-provider=localaponta para um endpoint compatível com OpenAI no host (ex.: Ollama via--advice-endpoint); reproduzível (temperature=0+--advice-cache); degrada graciosamente se o modelo estiver inacessível. - [ ]
--advice-provider=remoteusado apenas com consentimento explícito (--advice-allow-egress,QUORUM_ADVICE_API_KEY), é bloqueado por--offline, recusa--fixe envia apenas o finding normalizado. - [ ] As propostas de
--fix=suggestsão tratadas como apenas sugestões (re-scan verify-the-fix, nunca aplicadas automaticamente); um humano ainda revisa e aplica. - [ ] Todo anexo de IA é lido como "AI-generated, advisory only".
5.8 Operação e diagnóstico¶
- [ ] O resumo em stderr (
── quorum summary ──) inspecionado: status por scanner, contagem de multi-detected, severidades,elapsed. - [ ] Status
unavailable/timeout/errortratados como sinal — não como "limpo". Lembre: "0 findings não é prova de segurança". - [ ] Em OOM (
version probe killed/signal: killedou saída acima do limite): eleve o limite de memória do contêiner ou o cap. - [ ]
quorum list-scannersusado para confirmar quais dos 12 adapters estão registrados/empacotados na imagem em uso.
Premissas¶
- Versão de referência: documentação escrita para o Quorum v0.8.3
(revisão 2026-07-04), baseada no estado atual do repositório (
README.md,DESIGN.md,cmd/quorum/{root,scan,advise_index}.go,internal/adapter/*.go,internal/orchestrator/orchestrator.go,internal/{enrich,rag,advisor,evals},knowledge/*.yaml,.github/workflows/{ci,e2e,release,tag-major}.yml,action.yml,Dockerfile.full,.goreleaser.yaml,crosswalk/*.yaml). Itens marcados como comportamento (exit codes, status, flags, env) refletem o código as-is. - Escopo do produto: assume-se apenas CLI/Docker. Itens de checklist que em templates corporativos tratariam de frontend web, banco de dados relacional ou API REST são N/A por design e foram deliberadamente omitidos (não há superfície correspondente no código). IA/LLM não está fora de escopo, mas vive estritamente na camada consultiva opt-in (desligada por padrão, só de apresentação); o núcleo determinístico não tem IA.
- Owner/repo: os comandos de verificação usam
ghcr.io/martinez1991/quorum-sec-scaneMartinez1991/quorum-sec-scan, como emREADME.md/action.yml/release.yml. Em forks, ajuste o owner/identidade de certificado do cosign. - Ambiente típico de produção: assume-se execução num pipeline CI/CD
(GitHub Actions, GitLab CI ou
docker run), não um runtime de cluster — o Quorum não tem componente residente. Os itens de "Produção/Operação" referem-se a operar o scanner num pipeline. O RBAC via kubescape é single-engine (precisa de contexto de cluster) e está documentado como tal. - Plataformas:
:fullé sólinux/amd64(os binários de scanner são amd64);:slimcobreamd64+arm64. Checklists de mount/execução assumem um host capaz de rodar a imagem alvo (ex.: emulação para arm64). - Probe de versão: o valor de 60s (
Options.ProbeTime/defaultProbeTime) é tratado como fixo; se exposto via flag em versões futuras, o item 5.3 deve ser atualizado. - Versão no binário:
main.versiontem padrão0.1.0, sobrescrito em build-time via-ldflags "-X main.version=…"no release; v0.8.3 aqui refere-se à versão publicada do produto, não a um literal cravado no código.