mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 17:31:30 +00:00
c69d5bb07afb009ca8dbbda839a34f428057e9bd
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
95d0d85391 |
Bundle Q (Coverage Audit Closure): property-based pilot + hygiene — L-001/L-002/L-003/L-004/I-001 closed
Five small closures wrapping the Low-tier and Info-tier audit findings. Q.1 — cmd/cli round-out (L-001 closed) ====================================== cmd/cli/dispatch_test.go: ~30 dispatch tests across handleCerts / handleAgents / handleJobs / handleImport / handleStatus. httptest.NewTLSServer mocks the API; cli.NewClient(_, _, _, _, true) constructs an insecure-skip-verify client. Each test pins the missing-args usage-print path AND the happy-path delegation. Result: 7.1% -> 63.5% coverage (gate: >=30%). Q.2 — awssm round-out (L-002 closed) ====================================== internal/connector/discovery/awssm/awssm_edge_test.go: New() default constructor, extractKeyInfo (ECDSA/Ed25519/unknown — was RSA-only), processSecret filter arms (NamePrefix mismatch / TagFilter mismatch / empty-value / GetSecretValue error), realSMClient stub-contract pin (ListSecrets / GetSecretValue / NewRealSMClient), and EmailAddresses SAN extraction. Result: 78.2% -> 96.0% coverage (gate: >=85%). Q.3 — Property-based testing pilot (L-003 closed) ====================================== gopter@v0.2.11 added to go.mod (test-only). internal/crypto/encryption_property_test.go: - TestProperty_EncryptDecryptRoundTrip — 50 successful tests, DecryptIfKeySet(EncryptIfKeySet(x, k), k) == x - TestProperty_WrongPassphraseRejected — 30 successful tests, AEAD never returns nil-error AND bytes-equal plaintext under wrong passphrase Both skipped under -short to keep developer loop fast (PBKDF2 600k rounds × 50 iters ≈ 15s on -race CI). internal/pkcs7/length_property_test.go: - TestProperty_ASN1LengthRoundTrip — three sub-properties: decodeLength(encode(x)) == x for x ∈ [0, 2³¹−1]; short-form invariant (length<128 → 1 byte == length); long-form invariant (length>=128 → high bit set + N bytes follow). 500 successful tests in <10ms. Q.4 — Architecture diagram multi-agent update (L-004 closed) ====================================== docs/qa-test-guide.md::Architecture: ASCII diagram updated to show 'certctl-agent (×N)' + callout explaining seed_demo.sql provisions 12 agent rows (1 active, 2 retired, 9 reserved/sentinel) for Parts 04, 05, 55 + FSM coverage. Operators running parallel-agent topologies guided to AGENT_COUNT=N + 'make qa-stats'. Q.5 — Test-naming CI guard (I-001 closed) ====================================== .github/workflows/ci.yml: Test-naming convention guard added after the QA-doc seed-count drift guard. Greps for func Test<X>( missing the <X>_<Scenario> suffix. Prints first 20 non-conformant as ::warning:: annotations. continue-on-error: true (informational). Excludes TestMain + TestProperty_*. Promotion to hard-fail tracked as I-001-extended. Verification ====================================== - python3 yaml.safe_load on ci.yml: OK - go vet ./cmd/cli/... ./internal/connector/discovery/awssm/... ./internal/crypto/... ./internal/pkcs7/...: clean - go test -short -count=1 across all four packages: PASS - go test -count=1 (full property tests): PASS - crypto 15.4s (50 + 30 × 600k PBKDF2) - pkcs7 5ms Audit deliverables ====================================== - gap-backlog.md: strikethroughs on L-001/L-002/L-003/L-004/I-001 with per-finding closure note - closure-plan.md: ticks Bundle Q [x] with per-item breakdown Closes: L-001, L-002, L-003, L-004, I-001 Bundle: Q (Property-Based + Hygiene) |
||
|
|
30ac7910c2 |
Bundle P (Coverage Audit Closure): QA doc strengthening — M-007/M-009/M-010/M-011/M-012 closed; M-008 deferred
Six structural strengthenings to certctl QA documentation surface, raising acquisition-readiness QA-doc score 4.0 -> 4.7. M-008 (per-RFC test-vector subsections under Parts 21 + 24) deferred as 'Bundle P.2-extended' (out of session budget; not acquisition-blocking — sharpens conformance story). P.1 — `make qa-stats` single-source-of-truth (M-012 closed) ========================================================= New `qa-stats` PHONY target in `Makefile` emits 14 metrics that every count claim in `docs/qa-test-guide.md` and `docs/testing-guide.md` is derived from: backend test files / Test functions / t.Run subtests, frontend test files, fuzz targets, t.Skip sites, qa_test.go Part_ subtests, testing-guide.md Parts, and unique seed IDs (mc-* / ag-* / iss-* / tgt-* / nst-*). Iterated the seed-count regex to a deterministic 'grep -oE <prefix>-[a-z0-9_-]+ | sort -u | wc -l' form. Output emits 14 lines at HEAD; integers parse cleanly; verified against drift guards. P.2 — CI drift guards (M-011 closed) ========================================================= Two new CI steps in `.github/workflows/ci.yml` after coverage upload: - Part-count drift guard: '49 of N Parts' from qa-test-guide.md vs '^## Part N:' header count in testing-guide.md. Fails on mismatch. - Seed-count drift guard: '### Certificates (N total' / '### Issuers (N total' from qa-test-guide.md vs unique mc-* / iss-* IDs in seed_demo.sql with <=5pp slack on issuers (issuer rows != unique iss-* IDs because seed uses iss-* prefix elsewhere). Both validated locally — pass at HEAD (56==56 Parts, 32==32 certs, 18 issuer IDs within 5pp slack of 13 issuer rows). YAML lint clean. P.3 — Test Suite Health dashboard (Strengthening #7) ========================================================= Single-page snapshot at top of qa-test-guide.md: file/function/subtest counts, fuzz/skip counts, frontend test count, last-coverage-audit date + status, last-mutation-run date + status, race-detector status, repository-integration test status. Designed for first-look auditor / acquirer / new-engineer scanning. P.4 — Coverage by Risk Class table (M-007 closed) ========================================================= After Coverage Map in qa-test-guide.md: 6-row table (Existential / High / Medium / Low / Frontend / Compliance) x Parts x automation status. Cross-references each row to coverage-matrix.md. Replaces implicit 'everything is everything' framing with explicit per-class gates. P.5 — Release Day Sign-Off Matrix (M-010 closed) ========================================================= 12-row release-readiness checklist in qa-test-guide.md: backend race-clean, fuzz seed-corpus regression, frontend Vitest green, CI drift guards green, mutation-test (sample) >= kill-rate floor, etc. Each row cites verification command + gate value. Sign-off is 'all 12 green' — produces a per-release artifact attached to the tag. P.6 — Mutation Testing Targets (Strengthening #5) ========================================================= New section in qa-test-guide.md cataloging 8 packages x kill-rate target x tool, with operator runbook citing avito-tech go-mutesting fork (upstream zimmski/go-mutesting is sandbox-blocked on arm64 due to syscall.Dup2). Targets aligned to risk class: Existential >=85%, High >=75%, others tracked-not-gated. P.7 — Per-Connector Failure-Mode Matrix (M-009 closed, condensed) ========================================================= New 'Part 9.0 Per-Connector Failure-Mode Matrix' in docs/testing-guide.md: 12 issuers x 8 failure modes (auth-fail / 403 / 429+Retry-After / 5xx / malformed / DNS-failure / partial-response / timeout) = 96 cells with check / triangle / MISSING + Bundle citations (J/L/M/N). Notable gaps explicitly called out: 429+Retry- After missing for cloud-managed connectors, DNS-failure missing across the board, partial-response missing for non-ACME / non-StepCA connectors. Each gap is a follow-on-bundle candidate. Verification ========================================================= - 'make qa-stats' runs to completion, emits 14 metrics, all integers parse cleanly - 'python3 -c "import yaml; yaml.safe_load(...)"' clean on ci.yml - Both CI drift guards executed locally — both PASS at HEAD - git diff --stat: 5 files changed, +249 / -1 Audit deliverables ========================================================= - gap-backlog.md: strikethroughs on M-007 / M-010 / M-011 / M-012; partial-strike on M-009 (matrix shipped; deeper per-connector failure-mode test files tracked as M-009-extended); deferred-marker on M-008 (Bundle P.2-extended); Bundle P closure-log entry - closure-plan.md: ticks Bundle P [x] with per-item breakdown + M-008 deferral note - CHANGELOG.md: full Bundle P [unreleased] entry above Bundle O - testing-guide.md: new Part 9.0 Per-Connector Failure-Mode Matrix - qa-test-guide.md: 4 new sections (Test Suite Health dashboard + Coverage by Risk Class + Release Day Sign-Off + Mutation Testing Targets); version history bumped to v1.3 - Makefile: new qa-stats PHONY target - ci.yml: 2 new drift-guard steps after coverage upload Closes: M-007, M-010, M-011, M-012 Closes (condensed): M-009 (matrix shipped; deeper test files = M-009-extended) Deferred: M-008 (Bundle P.2-extended; not acquisition-blocking) Bundle: P (QA Doc Strengthening) |
||
|
|
834389621c |
Bundle I (Coverage Audit Closure): QA-doc drift cleanup — H-007 + H-008 closed
Applies Patches 1-7 from coverage-audit-2026-04-27/tables/qa-doc-patches.md
(Patch 5 re-anchored against actual HEAD seed counts after Phase 0 recon
discovered the original patch's anticipated counts were themselves drifted).
docs/qa-test-guide.md:
- Patch 1: 'all 54 Parts' -> '49 of 56 Parts' + not-yet-automated callout
- Patch 2: Totals line replaced with verified-2026-04-27 breakdown + recompute commands
- Patch 3: Coverage Map gains Parts 23, 24, 55, 56 (each '0 (NOT AUTOMATED)')
- Patch 4: 'Not Yet Automated' subsection added under 'What This Test Does NOT Cover'
- Patch 5: Seed Data Reference re-anchored to authoritative HEAD counts:
32 certs (already correct), 12 agents (was 9), 13 issuers (was 9),
8 targets (already correct), 4 nst (already correct).
Replaced narrow ID enumerations with sed | grep recompute commands.
Added maintenance-note pointer to Strengthening #6 (CI guard).
- Patch 6: Version History entry v1.2 added
- Bonus: integration_test comparison row updated (12 agents + 13 issuers)
deploy/test/qa_test.go (Patch 7):
4 new t.Run('PartN_*', ...) blocks for Parts 23, 24, 55, 56 — each calls
t.Skip with a docs/testing-guide.md::Part N pointer + automation candidates.
Skip-with-rationale form keeps Part numbering consistent + makes the
manual-test pointer machine-readable. Replacing each Skip with a real
test body is gap-backlog work.
Verification:
grep -cE '^## Part [0-9]+:' docs/testing-guide.md == 56 PASS
grep -cE 't\.Run("Part[0-9]+_' deploy/test/qa_test.go == 53 PASS
go vet -tags qa ./deploy/test/... PASS
go test -tags qa -run='__nope__' ./deploy/test/... PASS (compile)
(Full SKIP-grep gate requires the live demo stack; t.Skip bodies trivial.)
Audit deliverables:
findings.yaml: H-007 (-0014), H-008 (-0015) status open -> closed
gap-backlog.md: strikethrough both rows + Bundle I closure-log entry
tables/qa-doc-drift.md: 'PATCHES APPLIED' header marker (not retro-edited)
acquisition-readiness.md: QA-doc rigor 2.5 -> 4.0
closure-plan.md: Bundle I checklist box ticked
CHANGELOG.md: [unreleased] Bundle I entry
|
||
|
|
52248be717 |
v2.0.47: HTTPS Everywhere — TLS-only control plane, agents/CLI/MCP
Breaking change release. Plaintext HTTP listener removed. The certctl control plane now terminates TLS 1.3 on :8443 via http.Server.ListenAndServeTLS. No CERTCTL_TLS_ENABLED=false escape hatch. No dual-listener mode. One-step cutover per docs/upgrade-to-tls.md. Server - cmd/server/tls.go: certHolder with SIGHUP hot-reload + atomic cert swap, buildServerTLSConfig (TLS 1.3 min, GetCertificate callback), preflightServerTLS validation - cmd/server/main.go: ListenAndServeTLS in place of ListenAndServe, watchSIGHUP wiring, cert/key path config threading - tls_test.go: 418-line regression coverage of reload, preflight, callback behavior, SAN validation Config - CERTCTL_TLS_CERT_PATH / CERTCTL_TLS_KEY_PATH (required) - Plaintext rejection: agents/CLI/MCP pre-flight-fail on http:// URLs with a pointer to docs/upgrade-to-tls.md Agents, CLI, MCP - All three pre-flight-reject http:// URLs with fail-loud diagnostic - CERTCTL_SERVER_CA_BUNDLE_PATH for private-CA trust - CERTCTL_SERVER_TLS_INSECURE_SKIP_VERIFY for dev-only bypass (loud warning on startup) - install-agent.sh emits both vars as commented template lines docker-compose - certctl-tls-init sidecar generates SAN-valid self-signed cert into deploy/test/certs/ on first boot - All demo-stack curls pin against ca.crt with --cacert Helm chart - Three TLS provisioning modes, exactly one required: - server.tls.existingSecret (operator-supplied) - server.tls.certManager.enabled (cert-manager integration) - server.tls.selfSigned.enabled (eval only — not for production) - server-certificate.yaml template for cert-manager mode - helm install without a TLS source fails at template render with a pointer to docs/tls.md CI - .github/workflows/ci.yml Helm Chart Validation step renders the chart in both existingSecret and cert-manager modes, plus an inverse guard-regression test that asserts helm template MUST refuse to render when no TLS source is configured. Previously the single `helm template` invocation hit the certctl.tls.required fail-loud guard and exit-1'd CI. Four invocations now: lint (existingSecret), template (existingSecret), template (cert-manager), template (no args — must fail). Integration tests - deploy/test/integration_test.go stands up the Compose stack over HTTPS, extracts the CA bundle, and exercises every certctl API over https://localhost:8443 - All 34 integration subtests green (per Phase 8 local CI-parity) Documentation - New: docs/tls.md (provisioning patterns, rotation, SIGHUP reload) - New: docs/upgrade-to-tls.md (one-step cutover, no-downgrade warnings, fleet-roll sequencing) - CHANGELOG.md: v2.2.0 "HTTPS Everywhere — The Irony" entry (file heading unchanged; release tag is v2.0.47) - All curls in docs/, examples/, deploy/helm/ guides use https://localhost:8443 --cacert Verification - grep -rn "ListenAndServe[^T]" cmd/ internal/ → 0 hits - grep -rn "\"http://" cmd/ internal/ → 2 benign hits (Caddy admin API default, SSRF doc comment) — zero certctl endpoints - Tasks #197–#206 (Phases 0–8) all closed in the tracker Files: 65 changed, 3489 insertions, 372 deletions (pre-CI-fix). |
||
|
|
5567d4b411 |
feat(M47): add Kubernetes Secrets target + AWS ACM PCA issuer connectors
Implement both M47 connectors with full cross-layer wiring: Kubernetes Secrets target: DNS-1123 validation, kubernetes.io/tls Secret create-or-update, chain concatenation, serial number validation, Helm RBAC gating. 18 tests. AWS ACM Private CA issuer: synchronous issuance (like Vault), ARN regex validation, RFC 5280 revocation reason mapping, CA cert retrieval, factory + env var seeding. 23 tests. Cross-cutting: domain types, service validation, config, factory, agent dispatch, frontend (TargetsPage, issuerTypes), OpenAPI, seed data, Helm chart, connectors docs, README. Testing docs (testing-guide, qa-test-guide, qa_test.go) with Parts thematically integrated near related connectors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
e5516d7286 |
test: add unified QA test suite (qa_test.go) replacing legacy bash smoke script
1717-line Go test file covering all 52 Parts of testing-guide.md against the Docker Compose demo stack. ~120 automated subtests (API, DB, source, perf), 11 skipped Parts with reasons, ~270 manual gaps documented. Audited against actual router, seed data, domain structs, and migrations — 8 factual bugs caught and fixed during review. Companion guide at docs/qa-test-guide.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |