Infraestrutura¶
Documento de referência da infraestrutura do Quorum (
quorum-sec-scan), v0.8.3. Revisão: 2026-07-04. Escrito em pt-BR, padrão enterprise.
O Quorum é uma ferramenta CLI/Docker de consensus security scanning. Ele não possui infraestrutura de runtime própria: não há serviço hospedado, cluster, banco de dados, fila, load balancer ou API exposta. O produto executa na máquina/pipeline do consumidor — um runner de CI, uma estação de trabalho de desenvolvedor ou um job de orquestração — e termina o processo ao final da varredura. Toda a "infraestrutura" do projeto, portanto, é infra de build e distribuição (a cadeia de fornecimento de software, supply chain), não de operação contínua.
Este documento descreve a infra real (imagens Docker, registry GHCR, GitHub Actions como plataforma de build, distribuição de binários e a postura de supply chain), e declara explicitamente como N/A os componentes clássicos de infraestrutura de runtime que não se aplicam a este modelo de produto.
Nota importante: o Quorum escaneia alvos Kubernetes e IaC (Terraform, CloudFormation, manifestos K8s, Dockerfiles etc.). Isso é capacidade de produto, não infraestrutura de runtime do Quorum. Não confunda "o Quorum analisa K8s" com "o Quorum roda em K8s".
1. Modelo de implantação¶
flowchart LR
subgraph build["Plataforma de BUILD (Quorum CI)"]
GHA["GitHub Actions<br/>release.yml"]
GR["GoReleaser"]
BX["Docker Buildx + QEMU"]
end
subgraph dist["DISTRIBUIÇÃO (artefatos assinados)"]
GHCR[("GHCR<br/>ghcr.io/martinez1991/<br/>quorum-sec-scan")]
REL[("GitHub Releases<br/>binários + checksums")]
end
subgraph runtime["RUNTIME (ambiente do CONSUMIDOR)"]
CI["Runner de CI<br/>(GitHub/GitLab/etc.)"]
DEV["Estação dev<br/>(Linux/macOS/Win)"]
end
GHA --> BX --> GHCR
GHA --> GR --> REL
GHCR -. docker pull .-> CI
GHCR -. docker pull .-> DEV
REL -. download binário .-> CI
REL -. download binário .-> DEV
| Camada | Quem é dono | O que existe | Observação |
|---|---|---|---|
| Build | Projeto Quorum | GitHub Actions, GoReleaser, Buildx | Efêmero; runners ubuntu-latest |
| Distribuição | Projeto Quorum | GHCR (imagens), GitHub Releases (binários) | Artefatos imutáveis e assinados |
| Runtime | Consumidor | Nenhum recurso provisionado pelo Quorum | Processo de vida curta |
2. Infraestrutura de RUNTIME — N/A (declarações)¶
O Quorum não opera nenhum dos componentes abaixo. Cada item é declarado N/A com a justificativa técnica.
| Componente | Status | Justificativa |
|---|---|---|
| Cloud (AWS/GCP/Azure) | N/A | Não há serviço hospedado. O binário/imagem roda no ambiente do consumidor. |
| Kubernetes (runtime próprio) | N/A | O Quorum é um processo CLI de vida curta; não há Deployment, Pod ou Operator do produto. (Ele escaneia manifestos/clusters K8s — isso é função de produto.) |
| Ingress / Gateway | N/A | Não há serviço HTTP de entrada — não existe API REST nem frontend. |
| Load Balancer | N/A | Não há tráfego de requisições a balancear; execução é monoprocesso. |
| CDN | N/A | Distribuição de artefatos delegada ao GHCR/GitHub Releases (que já têm sua própria borda). O projeto não opera CDN. |
| WAF | N/A | Sem superfície HTTP exposta a proteger. |
| Banco de dados relacional | N/A | Estado é efêmero; correlação/consenso acontecem em memória por execução. Único "estado" persistido é cache local de aliases em ~/.cache/quorum/aliases.json (arquivo com perm 0600 e schemaVersion, não DB). |
| Fila / mensageria | N/A | Fan-out de scanners é via goroutines no mesmo processo (orchestrator), não broker externo. |
| Autenticação / IAM de runtime | N/A | Não há contas de usuário nem API protegida. |
| Observabilidade de runtime (APM/metrics/tracing) | N/A | Sem serviço de longa duração; diagnóstico é via logs em stderr (com --log-format text\|json) e status por scanner (ran/skipped/unavailable/error/timeout). O flag --metrics <arquivo> emite um textfile Prometheus por execução — para scrape pelo node_exporter do consumidor, não um endpoint próprio. |
| Secrets de runtime | N/A | A execução normal não requer segredos. OSV.dev é consultado sem credencial; --offline desativa. O provider remoto da camada consultiva (opt-in) é o único caminho que usa chave (QUORUM_ADVICE_API_KEY) e vem desligado por padrão. Ver §8. |
Proposta futura (claramente separada — NÃO implementada)¶
Conforme DESIGN.md §13, há a ideia de um módulo runtime separado (Falco ou Tetragon, OpenSCAP de host) como produto à parte, com modelo de stream. Caso isso seja construído, passaria a existir infra de runtime (agentes, coleta contínua) — mas isso não faz parte do Quorum v0.8.x e está fora do escopo deste documento.
3. Imagens Docker (infra real de distribuição)¶
O Quorum publica duas variantes de imagem, com objetivos distintos. Ambas usam build
multi-stage a partir de golang:1.26-alpine (compilação) e alpine:3.20 (runtime), ambas
pinadas por @sha256 digest (ver §3.2). Ambas as variantes também empacotam o knowledge
pack consultivo (knowledge/ → /opt/quorum/knowledge: templates de remediação da Fase 0 +
o corpus OWASP com digest pinado), para que a camada consultiva opt-in funcione offline por
padrão.
| Variante | Dockerfile | Conteúdo | Plataformas | Tamanho/uso |
|---|---|---|---|---|
:slim |
Dockerfile |
Apenas o orquestrador (binário quorum) + crosswalks + knowledge pack |
linux/amd64, linux/arm64 |
Pequena. BYO-scanners: os scanners devem estar no PATH (montados ou presentes no runner). |
:full |
Dockerfile.full |
Orquestrador + todos os 12 scanners + grype DB pré-cacheado + knowledge pack | linux/amd64 apenas |
Autossuficiente para CI. Grande — o salto de 6 para 12 scanners (Python/venv do Checkov, assets do KICS, DB do grype e mais seis binários de IaC/K8s) aumentou o tamanho frente à v0.2.x. Os binários de scanner empacotados são amd64, daí a restrição de arquitetura. |
3.1 Tags publicadas¶
Geradas em release.yml (passo Resolve version and image name):
| Variante | Tags |
|---|---|
full |
:full, :<version>, :<version>-full, :latest |
slim |
:slim, :<version>-slim |
A tag
:latestaponta para afull. Para reprodutibilidade, prefira pin por digest (@sha256:...) em produção — ver §6.
3.2 Base images e dependências de runtime da imagem¶
Na v0.8.3 todas as camadas base e todas as origens de scanner são pinadas por digest ou
verificadas por checksum — não há mais tag mutável de base (o gap de alpine:3.20 da
v0.2.x foi fechado).
| Imagem | Base / origem | Pinning |
|---|---|---|
| Build stage (ambas) | golang:1.26-alpine@sha256:3ad57304… |
Pinada por @sha256 digest (estágio de build, descartado) |
| Runtime stage (ambas) | alpine:3.20@sha256:d9e853e8… |
Pinada por @sha256 digest |
| Trivy (full) | aquasec/trivy:0.71.2 |
Pinada por @sha256 digest (tag mantida para leitura) |
| KICS (full) | checkmarx/kics:v2.1.3-alpine |
Pinada por @sha256 digest; copia binário + assets ./queries lado a lado |
| Grype + Syft (full) | Instalador oficial anchore (install.sh) |
Versão fixa via ARG; checksum verificado pelo script |
| Dockle (full) | GitHub release tarball | Checksum SHA-256 verificado (via dockle_..._checksums.txt) |
| Kubescape (full) | GitHub release (binário kubescape-ubuntu-latest) |
Pinada por KUBESCAPE_SHA256 — sha256sum -c, sem fallback curl \| bash |
| Polaris (full) | GitHub release tarball | Checksum SHA-256 verificado (via checksums.txt) |
| kube-score (full) | GitHub release tarball | Checksum SHA-256 verificado (via checksums.txt) |
| tfsec (full) | GitHub release (binário tfsec-linux-amd64) |
Checksum SHA-256 verificado (via tfsec_checksums.txt) |
| Terrascan (full) | GitHub release tarball | Checksum SHA-256 verificado (via checksums.txt); terrascan init no build (políticas offline) |
| Regula (full) | GitHub release tarball | Checksum SHA-256 verificado (via checksums.txt) |
| Conftest (full) | GitHub release tarball | Checksum SHA-256 verificado (via checksums.txt) |
| Checkov (full) | pip install checkov==3.3.6 em venv isolado (/opt/checkov) |
Versão fixada (pin de versão pip) |
Pacotes do sistema na :full (via apk): ca-certificates bash curl tar python3 py3-pip git
docker-cli. A :slim instala apenas ca-certificates.
3.3 grype DB pré-cacheado (:full)¶
A :full faz grype db update && grype db status em build time e congela o banco de
vulnerabilidades na imagem (GRYPE_DB_CACHE_DIR=/opt/grype/db, GRYPE_DB_AUTO_UPDATE=false).
Isso garante que a primeira varredura funcione offline e não falhe com "database does not
exist". Além disso, GRYPE_DB_VALIDATE_AGE=false é definido: sem ele, o grype recusa um DB
com mais de 5 dias (db.max-allowed-built-age) e faz hard-fail em toda varredura assim que
a imagem envelhece alguns dias — aceitamos por design um DB "assado" (possivelmente stale) e
documentamos a cadência de rebuild. O DB fica congelado no momento do build — para atualizar,
rebuild a imagem ou defina GRYPE_DB_AUTO_UPDATE=true em runtime (requer rede).
3.4 Versões de scanner empacotadas (Dockerfile.full)¶
Os 12 scanners cobrem SCA/imagem (Trivy, Grype, Dockle), IaC/MISCONFIG (Checkov, KICS, tfsec,
Terrascan, Regula), postura K8S_POSTURE (Kubescape, Polaris, kube-score) e policy-as-code
(Conftest, que roda o seu Rego de ./policy).
| Scanner | ARG de versão |
Categoria |
|---|---|---|
| Trivy | TRIVY_VERSION=0.71.2 |
SCA / imagem / IaC (emite AVD) |
| Grype | GRYPE_VERSION=v0.114.0 |
SCA |
| Syft (suporte ao Grype) | SYFT_VERSION=v1.11.0 |
SBOM (dependência do Grype) |
| Dockle | DOCKLE_VERSION=0.4.14 |
Imagem / Dockerfile |
| KICS | KICS_VERSION=v2.1.3 |
IaC / MISCONFIG |
| Kubescape | KUBESCAPE_VERSION=v3.0.8 |
K8S_POSTURE (hub C-#### do crosswalk) |
| Checkov | CHECKOV_VERSION=3.3.6 |
IaC / MISCONFIG |
| Polaris | POLARIS_VERSION=10.2.0 |
K8S_POSTURE |
| kube-score | KUBE_SCORE_VERSION=1.20.0 |
K8S_POSTURE |
| tfsec | TFSEC_VERSION=1.28.14 |
IaC / Terraform (emite AVD; auto-correlaciona com Trivy) |
| Terrascan | TERRASCAN_VERSION=1.19.9 |
IaC / MISCONFIG |
| Regula | REGULA_VERSION=3.2.1 |
IaC / MISCONFIG (OPA, regras embutidas) |
| Conftest | CONFTEST_VERSION=0.68.2 |
Policy-as-code (OPA; Rego do consumidor em ./policy) |
tfsec está descontinuado upstream (dobrado no Trivy), mas é mantido como engine distinto: como emite ids AVD nativos, suas descobertas auto-correlacionam com o Trivy sem crosswalk dedicado.
Terrascan offline: o build roda
terrascan initpara embutir as políticas na imagem, de modo que a varredura não dependa de rede na primeira execução (mesma filosofia do grype DB).
4. Registry — GHCR¶
| Item | Valor |
|---|---|
| Registry | ghcr.io (GitHub Container Registry) |
| Repositório de imagem | ghcr.io/martinez1991/quorum-sec-scan (owner/repo em minúsculas) |
| Autenticação de push | docker/login-action@v3 com ${{ secrets.GITHUB_TOKEN }} (escopo packages: write) |
| Autenticação de pull | Pública (read) para consumidores; sem credencial necessária |
O push é feito pelo docker/build-push-action@v6 (push: true), que também gera provenance
e SBOM nativos do Buildx (provenance: true, sbom: true). Além disso, o release atesta
uma SBOM SPDX de primeira classe (actions/attest-sbom, gerada por anchore/sbom-action em
spdx-json) e a empurra para o GHCR ao lado da assinatura cosign — ver §5.1 e §6.
5. GitHub Actions como plataforma de build¶
Não há servidor de build dedicado. A "infra de build" é o GitHub Actions com runners
efêmeros ubuntu-latest. Workflows relevantes:
| Workflow | Gatilho | Função |
|---|---|---|
ci.yml |
push em main, PRs |
go vet, go test -race, cobertura, build, smoke (list-scanners) |
e2e.yml |
(consenso end-to-end) | Validação de consenso |
release.yml |
tag semver v[0-9]+.[0-9]+.[0-9]+; workflow_dispatch |
Build/publish/assinatura/atestação de imagens, binários e do knowledge pack |
tag-major.yml |
após release semver | Avança a tag móvel v0 (pin do Action composite) automaticamente |
5.1 Pipeline de release (release.yml)¶
flowchart TD
TAG["git tag vX.Y.Z<br/>(semver estrito)"] --> J1
subgraph J1["job: images (matrix full|slim)"]
A["actions/checkout"] --> B["QEMU + Buildx"]
B --> C["login GHCR (GITHUB_TOKEN)"]
C --> D["build-push-action<br/>provenance + sbom (BuildKit)"]
D --> E["cosign sign (keyless OIDC, com retry)<br/>assina o digest do manifesto"]
E --> F["attest-build-provenance<br/>(SLSA v1) push p/ GHCR"]
F --> G["gh attestation verify<br/>(falha o release se quebrado)"]
G --> M["syft SBOM (SPDX) + attest-sbom<br/>(SBOM atestada, push p/ GHCR)"]
end
TAG --> J2
subgraph J2["job: binaries (só em tag)"]
H["install syft<br/>(SBOMs do GoReleaser)"] --> I["GoReleaser release --clean"]
I --> K["attest-build-provenance<br/>(checksums.txt)"]
K --> L["gh attestation verify<br/>(spot-check 1 artefato)"]
end
TAG --> J3
subgraph J3["job: knowledge"]
N["actions/checkout"] --> O["computa knowledge.sha256<br/>(templates + corpus OWASP, ordenado)"]
O --> P["attest-build-provenance<br/>(subject-checksums)"]
P --> Q["gh attestation verify<br/>knowledge/owasp/corpus.yaml"]
end
A tag móvel
v0(usada para pinar o GitHub Action composite) NÃO dispara release — o gatilho é restrito a semver completovX.Y.Z; otag-major.ymla avança depois do release. Ver action.yml e §7.
5.2 Permissões do workflow de release¶
permissions:
contents: read # (job binaries eleva p/ write — cria release e sobe assets)
packages: write # push para GHCR
id-token: write # cosign keyless (Sigstore OIDC)
attestations: write # atestações SLSA build-provenance e SBOM
O job
knowledgeroda comcontents: read+id-token: write+attestations: write(atestação SLSA keyless sobre os arquivos do pack).
6. Supply chain e pinning (DESIGN §12)¶
Princípio do projeto: um scanner empacotado faz parte do SEU perímetro de confiança. A postura de supply chain na v0.8.3 é:
- Bases pinadas por
@sha256(golang:1.26-alpine,alpine:3.20) — não mais tag mutável. - Imagens de scanner pinadas por
@sha256digest (Trivy e KICS). - Kubescape pinado por
SHA256de release (sha256sum -c, sem fallbackcurl | bash). - Checksums verificados no build para Dockle, Polaris, kube-score, tfsec, Terrascan, Regula
e Conftest (cada um contra o respectivo
checksums.txt/*_checksums.txt); os instaladores anchore (Grype/Syft) validam checksum internamente. - Versões fixas por
ARG/pin de pip para todos os scanners. - Assinatura keyless cosign (identidade via GitHub OIDC — sem chaves a gerenciar), com retry (o endpoint OIDC + Sigstore/Fulcio/Rekor ocasionalmente expira o token no meio da assinatura de builds longos).
- Atestação SLSA build-provenance (
actions/attest-build-provenance), verificada no próprio release (gh attestation verify), de modo que uma atestação quebrada falha o build. - SBOM SPDX atestada (
actions/attest-sbom), de primeira classe e verificável, além da SBOM nativa do Buildx (sbom: true); GoReleaser também gera SBOMs por-binário (syft). - Knowledge pack consultivo atestado: o job
knowledgecomputa umknowledge.sha256ordenado sobre os templates de remediação + o corpus OWASP com digest pinado (knowledge/**+ YAML decrosswalk/**) e produz uma atestação SLSA build-provenance para ele, verificada no release. O pack viaja dentro de ambas as imagens (/opt/quorum/knowledge) mas também é um artefato de dados independente que o consumidor pode verificar por conta própria. - THIRD_PARTY_NOTICES.md publicado com as licenças de terceiros.
6.1 Verificação pelo consumidor¶
# Imagem (manifesto multi-arch) — assinatura cosign keyless
cosign verify ghcr.io/martinez1991/quorum-sec-scan:slim \
--certificate-identity-regexp \
"https://github.com/Martinez1991/quorum-sec-scan/.github/workflows/release.yml@.*" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
# Atestação SLSA build-provenance da imagem
gh attestation verify "oci://ghcr.io/martinez1991/quorum-sec-scan@sha256:<digest>" \
--repo Martinez1991/quorum-sec-scan
# SBOM SPDX atestada da imagem (mesmo fluxo de verificação)
gh attestation verify "oci://ghcr.io/martinez1991/quorum-sec-scan@sha256:<digest>" \
--repo Martinez1991/quorum-sec-scan --predicate-type https://spdx.dev/Document
# Binário nativo — atestação de provenance
gh attestation verify quorum_<version>_linux_amd64.tar.gz \
--repo Martinez1991/quorum-sec-scan
# Knowledge pack consultivo (corpus OWASP) — atestação de provenance
gh attestation verify knowledge/owasp/corpus.yaml \
--repo Martinez1991/quorum-sec-scan
6.2 Checklist de hardening da imagem (DESIGN §12)¶
- [x] Imagens de scanner Trivy/KICS pinadas por
@sha256. - [x] Bases
golang:1.26-alpineealpine:3.20pinadas por@sha256— gap da v0.2.x fechado. - [x] Kubescape pinado por
SHA256de release (sem fallbackcurl | bash). - [x] Dockle, Polaris, kube-score, tfsec, Terrascan, Regula e Conftest verificados por checksum SHA-256.
- [x] Versões de scanner fixadas por
ARG/pin de pip. - [x] Assinatura keyless cosign no digest do manifesto (com retry).
- [x] Atestação SLSA build-provenance verificada no release (falha se quebrada).
- [x] SBOM SPDX atestada (
attest-sbom) além da SBOM nativa do Buildx. - [x] Knowledge pack consultivo atestado por SLSA (job
knowledge, verificado contracorpus.yaml). - [x] grype DB pré-cacheado (e
GRYPE_DB_VALIDATE_AGE=false) para operação offline na primeira varredura. - [x] Terrascan com
terrascan initembutido para políticas offline. - [ ] Grype/Syft pinados por
@sha256da release — hoje via instalador anchore com versão fixa e checksum validado pelo script, mas sem digest imutável. Hardening adicional sugerido.
Recomendação para produção: o consumidor deve pinar a imagem do Quorum por
@sha256(o inputimagedo action documenta isso) em vez de usar:full/:latest.
7. GitHub Action composite (action.yml)¶
O repositório expõe um Action composite que envolve a imagem :full, permitindo
uses: em vez de escrever docker run à mão. Por padrão, ele cosign-verifica a imagem
antes de rodá-la (input verify: true).
- uses: Martinez1991/quorum-sec-scan@v0 # tag móvel v0 (avançada por tag-major.yml)
with:
target: .
type: repo
fail-on: high
image: ghcr.io/martinez1991/quorum-sec-scan:full # pinar por @sha256 em produção
scanner-args: "" # passthrough por scanner (ex.: chave de API)
docker-socket: "" # opcional; em type=image o socket é auto-montado
# ── camada consultiva (opt-in, desligada por padrão) ──
advice: "false" # anexa templates de remediação + referências OWASP
advice-provider: "none" # none | local | remote
advice-endpoint: "" # endpoint compatível com OpenAI (provider local)
advice-model: "" # modelo de recomendação
advice-embed-model: "" # modelo de embeddings (RAG semântico)
advice-max: "" # limita os anexos consultivos
advice-cache: "" # caminho do cache de advice em disco
advice-allow-egress: "false" # consentimento obrigatório para o provider remoto
advice-api-key: "" # encaminhada como QUORUM_ADVICE_API_KEY (remoto)
fix: "off" # off | suggest (patch verify-the-fix)
Internamente o action: (1) instala cosign se ausente; (2) verifica a assinatura keyless contra
a identidade OIDC do release.yml; (3) executa
docker run --rm -v <workdir>:/work -w /work <image> scan <target> ...; (4) em type: image,
auto-monta /var/run/docker.sock para evitar falso-zero ao escanear uma imagem local; (5)
propaga o exit code do Quorum (0 ok, 1 gate disparado, 2 erro) e expõe output-file.
Para advice-provider: local ele auto-adiciona --add-host host-gateway para que o container
alcance um endpoint no host (ex.: Ollama); para remote encaminha a API key via env.
Passthrough por scanner também está disponível via env
QUORUM_<SCANNER>_ARGS(ex.:QUORUM_CHECKOV_ARGS="--bc-api-key ..."destrava políticas Prisma no Checkov). Ver §8.
8. Secrets¶
| Contexto | Secret | Uso |
|---|---|---|
| Runtime (consumidor) | Nenhum (obrigatório) | A varredura não exige segredos. OSV.dev é público (sem chave); --offline desativa lookups de rede. Chaves opcionais (ex.: bc-api-key do Checkov) podem ser passadas via QUORUM_<SCANNER>_ARGS. O provider consultivo remoto (opt-in) usa QUORUM_ADVICE_API_KEY — desligado por padrão, condicionado a --advice-allow-egress e bloqueado por --offline. |
| CI/build (Quorum) | GITHUB_TOKEN (efêmero, do GitHub) |
Login no GHCR, criação de release, gh attestation verify. |
| Assinatura | Nenhuma chave | cosign keyless — a identidade vem do token OIDC do Actions; nada para armazenar/rotacionar. |
Não há chave privada de assinatura, credencial de cloud ou segredo de longa duração no projeto. Isso é uma propriedade direta do modelo CLI/keyless. Segredos que o Trivy porventura detecte no alvo têm o
Matchredigido na saída do Quorum (redaction). O provider consultivo remoto envia apenas o finding normalizado — nunca código-fonte — e recusa--fix.
9. Distribuição de binários nativos (GoReleaser)¶
Binários gerados por .goreleaser.yaml no job binaries do release
(apenas em tag).
| Item | Valor |
|---|---|
| OS | linux, darwin, windows |
| Arch | amd64, arm64 |
| Build | CGO_ENABLED=0, -trimpath, -ldflags "-s -w -X main.version=..." |
| Arquivo | quorum_<version>_<os>_<arch>.tar.gz (.zip no Windows) |
| Conteúdo do archive | binário + README.md, README.pt-BR.md, LICENSE, diretório crosswalk/ |
| Checksums | checksums.txt (formato sha256 nome) |
| SBOM | SBOMs por-binário geradas pelo GoReleaser (syft instalado no job) |
| Assinatura | cosign sign-blob sobre checksums.txt (.sig + .pem) |
| Atestação | SLSA build-provenance sobre dist/checksums.txt (cobre cada artefato listado) |
| Publicação | GitHub Releases (Martinez1991/quorum-sec-scan), prerelease: auto |
O archive empacota o diretório
crosswalk/. Em runtime, o flag--crosswalktem default./crosswalkcom fallback automático para/opt/quorum/crosswalk(caminho usado nas imagens Docker). O knowledge pack consultivo viaja nas imagens Docker (/opt/quorum/knowledge) e como artefato de dados atestado à parte, não dentro do archive do binário nativo.
10. Sizing, custo e capacidade¶
Como não há runtime hospedado, não há sizing de infra de operação (sem instâncias, réplicas, autoscaling ou custo de cloud do produto). As únicas considerações de capacidade são:
- Build: minutos de GitHub Actions em runners
ubuntu-latest(custo do projeto, não do consumidor). O:fullempacota 12 scanners + grype DB, então é o job de build mais pesado. - Distribuição: armazenamento de pacotes no GHCR e assets em GitHub Releases. A
:fullé maior que na v0.2.x pelo dobro de scanners (Python/venv do Checkov, assets do KICS, DB do grype e seis binários de IaC/K8s adicionais). - Runtime do consumidor: CPU/RAM do runner ou estação onde a varredura roda. O orquestrador
faz fan-out paralelo (goroutines) com timeout por scanner (default
5m) e probe de versão de60s; o consumo é dominado pelos scanners empacotados (especialmente Trivy/Grype com DB). - Guarda-corpos de DoS: caps de tamanho de saída (
QUORUM_MAX_OUTPUT_BYTES, default512MiB) e de alvo (QUORUM_MAX_TARGET_BYTES, default20GiB) evitam estouro de memória/disco em varreduras patológicas.
11. Recuperação de desastre / continuidade¶
| Cenário | Postura |
|---|---|
| Perda de runtime | N/A — não há estado de runtime a recuperar; cada execução é independente. |
| Indisponibilidade do GHCR | Consumidor usa imagem já puxada/pinada por digest, ou cai para binário nativo. |
| Indisponibilidade do OSV.dev | Degradação graciosa: aliases locais do scanner + cache (~/.cache/quorum/aliases.json); --offline evita totalmente a rede. |
| Alvo IaC/K8s sem rede | grype DB e políticas do Terrascan ficam pré-cacheados na :full, então a primeira varredura funciona offline. |
| Modelo consultivo inalcançável | Degradação graciosa: o relatório segue sem advice de IA e a varredura nunca falha; os templates determinísticos de Fase 0/Fase 2 e as referências OWASP continuam sendo anexados (viajam na imagem). |
| Atestação/assinatura corrompida no release | O job de release falha (verificação gh attestation verify — imagens, binários e knowledge pack), bloqueando publicação ruim. |
Premissas¶
- O repositório upstream e o owner GHCR são
Martinez1991/quorum-sec-scan/ghcr.io/martinez1991/quorum-sec-scan, conformeaction.ymlerelease.yml. Forks usarão outro owner. - "Infraestrutura" foi interpretada como infra de build + distribuição + supply chain, já que o produto não tem runtime hospedado. Componentes de runtime clássicos foram declarados N/A com justificativa, conforme a tarefa.
- Os tamanhos de imagem não estão medidos no repositório; descrições como "pequena/grande" são
qualitativas, derivadas do conteúdo dos Dockerfiles (a
:fullempacota 12 scanners + grype DB - políticas do Terrascan + knowledge pack; a
:slim, só o binário + crosswalks + knowledge pack). A afirmação de que a:fullcresceu frente à v0.2.x deriva do aumento de 6 para 12 scanners empacotados, não de uma medição. - Os digests
@sha256das bases são citados truncados; os valores completos estão emDockerfile/Dockerfile.fulle devem ser re-resolvidos ao fazer bump de versão. - O job
e2e.ymlfoi citado a partir do gatilho/propósito conhecido; seu conteúdo detalhado está fora do escopo deste documento de infraestrutura. - A afirmação de que a primeira varredura da
:fullfunciona offline pressupõe alvo compatível com o DB grype congelado e com as políticas do Terrascan embutidas no momento do build da imagem. - A camada consultiva é opt-in e desligada por padrão: sem
--advicea saída é byte-idêntica e nenhum caminho de IA/egress executa. O núcleo determinístico (correlationKey, fingerprint, confidence, severidade agregada, gate fail-on) não é tocado por ela.