Commit Graph

16 Commits

Author SHA1 Message Date
shankar0123 c6efa4ab39 docs: add Docker Compose environments guide and fix compose files
- New deploy/ENVIRONMENTS.md: comprehensive walkthrough of all 4 compose
  files with service-by-service explanations, beginner-friendly Docker
  concepts, and expert-level networking/config details
- Fix docker-compose.dev.yml: agent LOG_LEVEL → CERTCTL_LOG_LEVEL (was
  silently ignored without the CERTCTL_ prefix)
- Add CERTCTL_CONFIG_ENCRYPTION_KEY to base and test compose (enables
  M34/M35 dynamic issuer/target config encryption)
- Add CERTCTL_DISCOVERY_DIRS to base compose agent (enables filesystem
  certificate discovery in default deployment)
- Cross-link ENVIRONMENTS.md from README doc table and quickstart.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 21:57:17 -04:00
shankar0123 8f146e08d6 feat(M36): onboarding wizard for first-run experience
4-step wizard (Connect CA → Deploy Agent → Add Certificate → Done) shown
on fresh installs when no user-configured issuers or certificates exist.
Auto-seeded env var issuers (source="env") are excluded from first-run
detection. Wizard state latches to prevent query refetches from dismissing
it mid-flow. Split docker-compose into clean default (wizard-compatible)
and demo override (seed_demo.sql). Added missing migrations 000009/000010
to test compose.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 19:27:01 -04:00
shankar0123 adfb682754 feat: Go integration test suite replacing bash end-to-end tests
Refactors deploy/test/run-test.sh into a typed Go test file with
crypto/x509 certificate parsing, eliminating fragile openssl text
scraping. 12 phases, 35 subtests covering Local CA, ACME, step-ca,
revocation, discovery, renewal, EST, S/MIME, and API spot checks.

- testClient HTTP helper with Bearer auth
- testDB PostgreSQL helper (port 5432 now exposed)
- waitFor/waitForJobsDone polling helpers
- crypto/x509 for EKU, KeyUsage, SAN verification
- crypto/tls for NGINX deployment verification
- //go:build integration tag (not in CI yet)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 19:04:26 -04:00
shankar0123 0822f748a5 feat: S/MIME certificate support in integration tests + test env docs
Add S/MIME (emailProtection EKU) end-to-end test coverage:
- ValidateCommonName() now accepts email addresses for S/MIME certs
- S/MIME test profile (prof-test-smime) in seed data
- Phase 11 test: issuance, EKU, KeyUsage, email SAN verification
- EST config enabled in test Docker Compose
- Portable KeyUsage parsing (awk, works on BSD/GNU)
- Full test environment documentation (docs/test-env.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 18:32:57 -04:00
shankar0123 b059ec930f fix: end-to-end certificate lifecycle bugs + integration test environment
Fixes 12 production bugs preventing the full issuance→deployment flow
from working with ACME (Pebble/Let's Encrypt) and step-ca issuers:

ACME connector (acme.go):
- Save orderURI before WaitOrder overwrites it (Go crypto/acme bug)
- Add CreateOrderCert fallback via WaitOrder+FetchCert
- Remove defer-reset in ValidateConfig that caused nil pointer panic
- Add Insecure TLS option for self-signed ACME servers (Pebble)

step-ca connector (stepca.go, jwe.go):
- Real JWE provisioner key loading + decryption (was using ephemeral keys)
- Fix JWT audience (/1.0/sign), sha claim (key fingerprint), kid header
- Custom root CA trust via RootCertPath config
- Remove hardcoded 90-day validity default (let step-ca decide)

NGINX target connector (nginx.go):
- Use sh -c for validate/reload commands (shell interpretation)
- Use filepath.Dir instead of fragile string slicing
- Add private key file writing (agent-mode keys were never deployed)
- Make chain_path write conditional

Server/service layer:
- TriggerRenewalWithActor now creates actual Job records (was no-op)
- createDeploymentJobs falls back to DB query when cert.TargetIDs empty
- ProcessPendingJobs skips agent-routed deployment jobs
- Agent cert pickup path parsing: len(parts)<4 → len(parts)<3
- Health/ready/auth-info endpoints bypass auth middleware
- Write timeout 15s→120s for ACME issuance
- Cert fingerprint computed on CSR submission

Integration test environment (deploy/test/):
- 10-phase test script covering Local CA, ACME, step-ca, revocation,
  discovery, renewal, and API spot checks
- Docker Compose with 7 containers (server, agent, postgres, nginx,
  pebble, challtestsrv, step-ca) on isolated network
- TLS verification checks SAN (not just Subject CN) for modern CA compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 17:02:20 -04:00
shankar0123 397d2a1588 fix(helm): remove fail on empty postgresql password for lint/template
Default to "changeme" so helm lint and helm template pass with stock
values. Operators override at install time via --set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:30:13 -04:00
shankar0123 65567d0d83 fix(helm): type comparison error and lint-time fail on empty apiKey
- Use gt (int .Values.server.replicas) 1 to avoid incompatible type
  comparison between YAML integer and template literal
- Remove fail directive for empty apiKey — lint runs with defaults,
  operators set the key via --set at install time

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:28:05 -04:00
shankar0123 0abd984285 fix: staticcheck S1016 struct conversion + Helm with/else-if parse error
- Use type conversion DigestStatusCount(c) instead of struct literal
- Replace with...else-if (invalid in Go templates) with if...else-if chain
- Add *.bak and cmd/agent/*.key/*.pem to .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:25:25 -04:00
shankar0123 ec21c9bb29 feat(m28+m29+m30): ACME ARI, email digest, and Helm chart
M28: ACME Renewal Information (RFC 9702) — CA-directed renewal timing
with cert ID computation, directory endpoint discovery, graceful
degradation for non-ARI CAs. 19 tests.

M29: Email notifier wiring + scheduled certificate digest — SMTP
connector bridged to service layer via NotifierAdapter, DigestService
with HTML email template, 7th scheduler loop (24h), digest preview/send
API endpoints and GUI card. 21 tests.

M30: Production-ready Helm chart — server Deployment, PostgreSQL
StatefulSet, agent DaemonSet, ConfigMaps, Secrets, Ingress, security
contexts, health probes, example values for dev/prod/ACME scenarios.

Also: OpenAPI spec updates, MCP tool additions, CI helm-lint job,
documentation updates across 5 doc files and README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:18:35 -04:00
shankar0123 03472072b8 test + docs: close 12 test gaps (~250 new tests) and expand testing guide to 34 parts
Implements all P0-P2 test gaps from docs/test-gap-prompt.md:
- Deployment service tests (20), target service tests (18), scheduler tests (8)
- Agent binary tests (48), CSR renewal tests (8), short-lived cert tests (7)
- Domain model tests (25), context cancellation tests (9), concurrency tests (7)
- Handler negative-path tests (23 across 5 files)
- Frontend error handling tests (86) and API client tests (7)

Expands testing-guide.md from 28 to 34 parts covering certificate export,
S/MIME/EKU, OCSP/DER CRL, body size limits, Apache/HAProxy connectors,
and sub-CA mode. Fixes stale profile count (4->5) and updates sign-off table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 17:57:25 -04:00
shankar0123 8308beb5bb fix: Docker Compose missing migrations, network scan []int crash, demo seed data
Three bugs fixed:
- Docker Compose only mounted migration 000001; migrations 000002-000007
  (profiles, agent groups, revocation, discovery, network scans) never ran,
  breaking half the demo features. Now mounts all 7 migrations in order.
- Network Scans page crashed with pq.Array scan error because lib/pq
  doesn't support []int, only []int64. Changed Ports field accordingly.
- Dashboard pie chart displayed "RenewalInProgress" without spaces.
  Added formatStatus() helper for PascalCase → spaced display.

Also adds first-run demo experience improvements:
- 9 discovered certificates (filesystem + network scan mix)
- 3 discovery scans with recent timestamps
- 2 AwaitingApproval renewal jobs for approval workflow demo
- CERTCTL_NETWORK_SCAN_ENABLED=true in Docker Compose
- Network scan targets seeded with last_scan results
- Version badge updated to v2.0.5
- Docs updated (quickstart, advanced demo) to reference seeded data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 18:33:50 -04:00
shankar0123 7618c5a734 fix: externalize credentials and add agent key volume persistence
- POSTGRES_PASSWORD and CERTCTL_API_KEY read from .env file
- Added deploy/.env.example with documentation
- Agent key volume (agent_keys) for key persistence across restarts
- Agent healthcheck via pgrep
- Resource limits: server 1CPU/512M, agent 0.5CPU/256M

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 01:20:27 -04:00
shankar0123 e2821c448a Implement M8: agent-side key generation with ECDSA P-256
Private keys never leave agent infrastructure. Agents generate ECDSA P-256
key pairs locally, store them with 0600 permissions, and submit only the CSR
(public key) to the control plane. New AwaitingCSR job state pauses
renewal/issuance jobs until the agent submits its CSR. Server-side keygen
retained behind CERTCTL_KEYGEN_MODE=server for demo/development.

Key changes:
- Dual keygen mode via CERTCTL_KEYGEN_MODE (agent default, server for demo)
- AwaitingCSR job state with CommonName/SANs in work response
- Agent ECDSA P-256 keygen, local key storage, CSR-only submission
- CompleteAgentCSRRenewal server-side flow for agent-submitted CSRs
- DeploymentRequest.KeyPEM for agent-provided keys during deployment
- Dockerfile.agent creates /var/lib/certctl/keys with correct ownership

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 13:51:41 -04:00
shankar0123 9b4122b159 Fix runtime bugs, implement service layer, and overhaul documentation
Runtime fixes:
- Fix env var mismatch (CERTCTL_DB_URL → CERTCTL_DATABASE_URL)
- Fix table name mismatches (certificates → managed_certificates, notifications → notification_events)
- Add renewal_policy_id to certificate queries
- Remove non-existent created_at from notification queries
- Add env var fallback for agent CLI flags
- Graceful degradation for missing notifiers/issuers in demo mode
- Copy web/ directory in Dockerfile for dashboard serving

Service layer:
- Implement handler-service interface pattern across all services
- Wire up certificate, agent, job, policy, team, owner, audit, notification services

Documentation:
- Add concepts.md: beginner-friendly guide to TLS, CAs, private keys
- Rewrite quickstart.md with accurate API examples matching actual handlers
- Add demo-advanced.md: interactive demo with cert issuance and automated script
- Update architecture.md with correct table names and connector interfaces
- Update connectors.md to match actual Go interface signatures
- Update demo-guide.md with cross-references to new docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 21:38:11 -04:00
shankar0123 3a9fe8ba37 Complete V1 scaffold 2026-03-14 20:01:53 -04:00
shankar0123 d395776a95 Initial scaffold: certificate control plane v0.1.0 2026-03-14 08:22:17 -04:00