Commit Graph

3 Commits

Author SHA1 Message Date
cowork 9a01ec4023 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)
2026-04-27 18:36:47 +00:00
cowork d14411faf5 Bundle M.Cloud (Coverage Audit Closure): AzureKV + GCP-SM — H-004 closed
Closes the deferred 4th sub-batch from Bundle M; Bundle M is now FULLY CLOSED across all 4 sub-batches.

Coverage:

  AzureKV:  41.2% -> 85.6%  (+44.4pp; +15.6 above 70% target)

  GCP-SM:   43.1% -> 83.4%  (+40.3pp; +13.4 above 70% target)

Engineering: rewritingTransport (custom http.RoundTripper) intercepts

the hardcoded cloud-API URLs (login.microsoftonline.com /

oauth2.googleapis.com / secretmanager.googleapis.com) and rewrites Host

to point at an httptest.Server while preserving Path + Query. For GCP,

the service-account JSON file written to t.TempDir() carries token_uri

pointing at the test server (clean override path).

azurekv_failure_test.go (~280 LoC, 13 tests):

  - getAccessToken: happy + cached-reuse + 401 + malformed JSON +

    empty-token + network-error

  - ListCertificates: happy + token-failure + 5xx + malformed +

    multi-page pagination via nextLink

  - GetCertificate: happy + 404 + malformed JSON

  - New constructor smoke

gcpsm_failure_test.go (~430 LoC, 19 tests):

  - loadServiceAccountKey: happy + file-not-found + malformed-JSON +

    bad-PEM + empty-private-key

  - getAccessToken: happy (JWT-bearer flow) + cached-reuse + 401 +

    malformed + empty-token + load-credentials-failure

  - ListSecrets: happy + token-failure + 5xx + malformed

  - AccessSecretVersion: happy + 404 + bad-base64-payload

  - Name / Type identity

Verification:

  go vet ./internal/connector/discovery/{azurekv,gcpsm}/...    clean

  gofmt -l                                                     clean

  staticcheck -checks all                                      clean (only

    pre-existing ST1005 hits in master, unrelated to Bundle M.Cloud)

  go test -short -count=1                                      PASS

  go test -race -count=1                                       PASS, 0 races

Audit deliverables:

  findings.yaml: -0011 status open -> closed with full closure_note

  gap-backlog.md: H-004 strikethrough + Bundle M.Cloud closure-log entry

  coverage-matrix.md: 2 new rows for AzureKV + GCP-SM at post-Bundle coverage

  closure-plan.md: Bundle M [~] -> [x] (all 4 sub-batches closed)

  CHANGELOG.md: [unreleased] Bundle M.Cloud entry
2026-04-27 17:34:00 +00:00
Shankar e1630bcb44 feat(M50): cloud secret manager discovery — AWS SM, Azure KV, GCP SM
Extend certificate discovery from filesystem + network to cloud secret
managers. Three pluggable DiscoverySource connectors feed into the
existing discovery pipeline via sentinel agent pattern, with a 9th
scheduler loop for periodic cloud scanning.

- AWS Secrets Manager: aws-sdk-go-v2, tag/prefix filtering, 10 tests
- Azure Key Vault: stdlib HTTP + OAuth2, base64 DER/PEM, 16 tests
- GCP Secret Manager: stdlib HTTP + JWT OAuth2, label filter, 14 tests
- CloudDiscoveryService orchestrator with 9 tests
- 9th scheduler loop (6h default, atomic.Bool idempotency)
- Discovery page: color-coded source type badges
- 14 new env vars across CloudDiscoveryConfig structs
- Docs: connectors.md, architecture.md, features.md, README updated

49 new tests. All CI checks pass (go vet, race, lint, coverage).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 23:01:00 -04:00