shankar0123
5a682db8e2
EST RFC 7030 hardening master bundle Phases 10-11: libest sidecar e2e
...
+ Cisco IOS quirk fixtures + ManagedCertificate.Source provenance +
EST bulk-revoke endpoint + 13 typed audit action codes.
Phase 10.1 — libest reference-client sidecar:
- deploy/test/libest/Dockerfile: multi-stage Debian-bookworm-slim
build of Cisco's libest v3.2.0-2 from source (autoconf/automake/
libtool + libcurl4-openssl-dev + libssl-dev). Runtime stage
carries only estclient + bash + openssl + ca-certificates so the
exec surface stays small + predictable.
- docker-compose.test.yml libest-client entry (profiles: [est-e2e])
with bind mounts for /config/est (test workspace) + /config/certs
(certctl CA bundle for TLS pinning); IP 10.30.50.9 (10.30.50.8
was already taken by certctl-agent).
- deploy/test/est/.gitkeep keeps the bind-mount target tracked.
Phase 10.2 — 5 integration tests (//go:build integration) in
deploy/test/est_e2e_test.go:
- TestEST_LibESTClient_Enrollment_Integration (cacerts → simpleenroll
→ cert-shape assertion)
- TestEST_LibESTClient_MTLSEnrollment_Integration (mTLS sibling-route
cert auth; skip when bootstrap cert absent)
- TestEST_LibESTClient_ServerKeygen_Integration (RFC 7030 §4.4
multipart; skip when profile gate disabled)
- TestEST_LibESTClient_RateLimited_Integration (4th enroll trips
per-principal cap, asserts 429-shaped error)
- TestEST_LibESTClient_ChannelBinding_Integration (libest
--tls-exporter; skip when libest build lacks the flag).
- requireESTSidecar guard skips the suite when the operator forgot
--profile est-e2e; helpful error message includes the exact
command to bring the sidecar up.
Phase 10.3 — Cisco IOS quirk fixtures + 3 unit tests in
internal/api/handler/cisco_ios_quirks_test.go:
- testdata/cisco_ios_15x_pem_csr.txt: PEM body sent with
Content-Type application/x-pem-file. Handler dispatches on
body-prefix not Content-Type — accepts cleanly.
- testdata/cisco_ios_16x_trailing_newline_csr.txt: extra trailing
newlines after base64 body. strings.TrimSpace tolerates.
- testdata/cisco_ios_crlf_b64_csr.txt: CRLF-wrapped base64.
base64.StdEncoding handles CRLF + LF identically.
Phase 11.1 — ManagedCertificate.Source provenance:
- New domain.CertificateSource enum (Unspecified/EST/SCEP/API/Agent).
- Migration 000023_managed_certificates_source.up.sql adds source
TEXT NOT NULL DEFAULT '' so existing rows scan as
CertificateSourceUnspecified — back-compat: bulk-revoke filter
treats empty as "any source".
- Postgres repo Insert/Update/scan paths all wire the new column.
Phase 11.2 — EST bulk-revoke endpoint:
- BulkRevocationCriteria.Source field (Source-only requests rejected
as too broad — must accompany at least one narrower criterion).
- service.bulk_revocation.resolveCertificates post-filter by Source
(empty=any, no SQL change so existing CertificateFilter callers
unaffected).
- New BulkRevocationHandler.BulkRevokeEST method pins Source=EST +
dispatches; new route POST /api/v1/est/certificates/bulk-revoke
(M-008 admin-gated). openapi.yaml documented + parity-guard green.
Phase 11.3 — 13 typed audit action codes in
internal/service/est_audit_actions.go:
- est_simple_enroll_success / _failed
- est_simple_reenroll_success / _failed
- est_server_keygen_success / _failed
- est_auth_failed_basic / _mtls / _channel_binding
- est_rate_limited
- est_csr_policy_violation
- est_bulk_revoke
- est_trust_anchor_reloaded
- ESTService.processEnrollment + SimpleServerKeygen + ReloadTrust
split-emit BOTH the legacy bare action codes (back-compat for the
GUI activity-tab chip filters that match by exact string +
existing audit-log analysers) AND the new typed _success / _failed
variants (operator grep target + per-failure-mode counter).
Tests:
- internal/api/handler/bulk_revocation_est_test.go — 5 cases
(admin-true happy path pins Source=EST + non-admin 403 +
empty-criteria 400 + invalid-reason 400 + method-not-allowed).
- internal/service/est_audit_actions_test.go — 5 cases (SimpleEnroll
legacy+typed emission / SimpleReEnroll typed / IssuerError
typed-failed / PolicyViolation triple-emit /
unique-string invariant).
Pre-commit verification (sandbox): gofmt clean, go vet clean
(excluding repository/postgres testcontainers limit), staticcheck
clean across api/handler/api/router/domain/service/deploy/test,
go test -short -count=1 green for every non-postgres Go package +
integration build (`go build -tags integration ./deploy/test/...`)
clean. G-3 docs-drift guard reproduced locally clean (Phases 10-11
added zero new env vars).
Spec preserved at cowork/est-rfc7030-hardening-prompt.md. Phases
12-13 (docs/est.md + WiFi/802.1X / IoT bootstrap / FreeRADIUS
recipes; release prep + tag) remain — post-2.1.0 work.
2026-04-30 00:52:43 +00:00
shankar0123
5d98e373e3
feat: M15a — certificate revocation API, CRL endpoint, and revocation notifications
...
Implements core revocation infrastructure: POST /api/v1/certificates/{id}/revoke
with all 8 RFC 5280 reason codes, JSON-formatted CRL at GET /api/v1/crl, webhook
and email revocation notifications, best-effort issuer notification, and immutable
revocation audit trail. Includes 48 new tests across service, handler, integration,
and domain layers (600+ total). Fixes 3 pre-existing test bugs (team_test error
matching, agent_group delete status code, team handler per_page validation).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-22 10:59:18 -04:00
shankar0123
a579a84c7f
feat: M11a — certificate profiles, crypto policy enforcement, short-lived cert expiry
...
Add certificate profiles as named enrollment templates that control allowed
key algorithms, max TTL, permitted EKUs, required SAN patterns, and optional
SPIFFE URI SANs. CSR submissions are validated against profile rules at
signing time (key type + minimum size). Short-lived certs (TTL < 1 hour)
auto-expire via a new scheduler loop — expiry acts as revocation, no
CRL/OCSP needed.
New files:
- Migration 000003: certificate_profiles table, FK columns on
managed_certificates/renewal_policies, key metadata on certificate_versions
- domain/profile.go: CertificateProfile + KeyAlgorithmRule structs
- repository/postgres/profile.go: full CRUD with JSONB marshaling
- service/profile.go: ProfileService with validation + audit logging
- service/crypto_validation.go: CSR-against-profile validation (RSA/ECDSA/Ed25519)
- handler/profiles.go: 5 HTTP endpoints under /api/v1/profiles
- web/src/pages/ProfilesPage.tsx: profiles management page
Modified:
- renewal.go: CSR validation in CompleteAgentCSRRenewal, ExpireShortLivedCertificates
- scheduler.go: 30s short-lived expiry check loop
- certificate.go (repo): nullable profile FK, key metadata on versions
- main.go: profile repo/service/handler wiring, 8-param NewRenewalService
- router.go: 12-param RegisterHandlers with profile routes
- seed_demo.sql: 4 demo profiles (standard, mtls, short-lived, high-security)
- Frontend: types, API client, routing, sidebar nav
Tests: 40 new tests across handler (15), service (13), crypto validation (12)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-20 20:39:49 -04:00
shankar0123
66f04f7afe
style: run gofmt -s across all Go files
...
Fixes Go Report Card gofmt score from 52% to 100%.
Pure formatting changes — no logic modifications.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-17 19:32:29 -04:00
shankar0123
1d1b89c9b5
Implement M3: expiration threshold alerting with dedup and status transitions
...
- Add alert_thresholds_days JSONB column to renewal_policies (default [30,14,7,0])
- Add RenewalPolicy.AlertThresholdsDays field + EffectiveAlertThresholds() helper
- Add RenewalPolicyRepository interface + postgres implementation
- Rewrite CheckExpiringCertificates with per-policy threshold alerting
- Add SendThresholdAlert + HasThresholdNotification for deduplication via [threshold:N] tags
- Add Type and MessageLike filters to NotificationFilter + postgres query support
- Auto-transition certs to Expiring (>0 days) or Expired (<=0 days) status
- Record expiration_alert_sent audit events per threshold crossing
- Fix .gitignore: allow SQL migration files, scope server/agent build artifact rules
- Track previously untracked cmd/ and migrations/ directories
- Update docs (README, architecture, demo-advanced) for threshold alerting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-15 00:03:43 -04:00
shankar0123
d395776a95
Initial scaffold: certificate control plane v0.1.0
2026-03-14 08:22:17 -04:00