Files
certctl/docs/compliance-nist.md
T
shankar0123 72cda5877a docs: fix 16 discrepancies found by cross-validating all docs against source code
CLI syntax corrected across 5 files (concepts, demo-guide, demo-advanced,
architecture, features): list-certs→certs list, get-cert→certs get, etc.
Removed non-existent health/metrics commands, replaced with status.
Subcommand count 10→12 everywhere.

architecture.md: Go 1.22→1.25, endpoint count 91→93, ER diagram expanded
from 15 to 21 tables (added renewal_policies, certificate_revocations,
discovered_certificates, discovery_scans, network_scan_targets).

connectors.md: added GenerateCRL and SignOCSPResponse to issuer interface,
added Email and Webhook rows to notifier config table.

compliance docs: fixed keygen warning messages to match actual log output,
CERTCTL_STEPCA_PROVISIONER_KEY→CERTCTL_STEPCA_KEY_PATH, openssl genrsa→
crypto/ecdsa.GenerateKey, CERTCTL_SERVER_ADDR→CERTCTL_SERVER_HOST+PORT.

README.md: v2.0.0 version bump, solo developer mention, feature list,
table of contents, documentation table moved to top, 7 fact-check fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 03:51:33 -04:00

17 KiB
Raw Blame History

NIST SP 800-57 Key Management Alignment

NIST SP 800-57 Part 1 Rev 5 (May 2020) is the authoritative US government guidance on cryptographic key management. This document maps certctl's implementation to its recommendations. certctl follows NIST guidance where applicable; this guide documents the alignment and identifies gaps for future roadmap planning.

Key Generation (Section 6.1)

certctl generates certificate keys on agent infrastructure using Go's crypto/rand for entropy, backed by /dev/urandom on Linux and CryptGenRandom on Windows. Key generation happens as follows:

Agent-Side Key Generation (Production Default)

  • Agents generate ECDSA P-256 key pairs per certificate using crypto/ecdsa + crypto/elliptic (Go stdlib)
  • Key generation triggered by AwaitingCSR job state in renewal/issuance workflows
  • Agent creates Certificate Signing Request (CSR) with x509.CreateCertificateRequest, signed with the agent's private key
  • Only the CSR crosses the network to the control plane; private key material never leaves the agent
  • Configuration: CERTCTL_KEYGEN_MODE=agent (default, production)

Server-Side Key Generation (Demo Only)

  • Available for development and testing via CERTCTL_KEYGEN_MODE=server
  • Explicitly logged as a warning at startup: "server-side key generation enabled (CERTCTL_KEYGEN_MODE=server) — private keys touch control plane, demo only"
  • Docker Compose demo uses server mode for backward compatibility
  • Not recommended for production; agent mode is the secure default

Entropy Source

  • crypto/rand provides cryptographically secure random bytes
  • On Linux: backed by /dev/urandom via getrandom() syscall
  • On Windows: backed by CryptGenRandom() (now BCryptGenRandom())
  • Meets NIST SP 800-90B requirements for entropy generation

Key Storage and Protection (Sections 6.3, 6.4)

certctl implements tiered key storage with different protection profiles based on key purpose.

Agent Private Keys

  • Stored on agent filesystem at CERTCTL_KEY_DIR (default: /var/lib/certctl/keys)
  • File permissions: 0600 (read/write by agent process only, no world/group access)
  • One PEM file per certificate, organized by certificate ID
  • Accessible only to the agent process; isolated from other processes
  • For container deployments: use Docker volumes with restricted permissions (-v /var/lib/certctl/keys:0600)

Issuing CA Keys (Local CA Connector)

  • Loaded from disk at server startup via CERTCTL_CA_CERT_PATH and CERTCTL_CA_KEY_PATH env vars
  • Supports RSA (PKCS#1, PKCS#8) and ECDSA (SEC1, PKCS#8) key formats
  • Validates certificate constraints before use:
    • IsCA=true flag present
    • KeyUsageCertSign extension set
    • Valid certificate chain (for sub-CA mode)
  • Keys held in memory during server runtime (no on-disk caching after load)
  • Cleared from memory only on server shutdown

Sub-CA Mode (Enterprise Integration)

  • CA certificate and key signed by upstream enterprise root (e.g., Active Directory Certificate Services)
  • Certctl acts as subordinate CA, inheriting issuer DN from upstream CA
  • All issued certificates chain to enterprise trust anchor
  • CA key protection inherits upstream root's key management practices
  • Configured via: CERTCTL_CA_CERT_PATH=/path/to/ca.crt and CERTCTL_CA_KEY_PATH=/path/to/ca.key

NIST Gap: HSM Storage NIST SP 800-57 Part 1 recommends Hardware Security Module (HSM) storage for high-value keys (CA signing keys). certctl V2 uses filesystem storage on the server. HSM support is planned for V5 roadmap, enabling integration with:

  • AWS CloudHSM
  • Azure Dedicated HSM
  • Thales Luna, Gemalto SafeNet, YubiHSM (on-premises)
  • PKCS#11-compatible devices

Cryptoperiods (Section 5.3, Table 1)

NIST recommends cryptoperiods (key validity durations) based on key type and security requirements. certctl enforces cryptoperiods through certificate profiles and renewal policies.

Certificate Profile Enforcement

  • Certificate profiles (M11a) define max_ttl constraint per enrollment profile
  • All certificates issued through a profile cannot exceed the profile's max_ttl
  • Profile configuration example:
    {
      "id": "prof-web-prod",
      "name": "Production Web Certs",
      "max_ttl_seconds": 31536000,  // 1 year max
      "allowed_key_algorithms": ["ECDSA_P256"],
      "required_sans": ["example.com"]
    }
    

Renewal Thresholds

  • Renewal policies with configurable alert_thresholds_days: [30, 14, 7, 0] (days before expiry)
  • Background scheduler checks renewal eligibility every 1 hour
  • Certificates transitioned to Expiring status at 30 days, Expired at 0 days
  • Renewal workflow can be triggered manually or automatically

NIST Cryptoperiod Recommendations vs certctl Implementation

Key Type NIST Recommendation certctl Implementation
CA signing key 310 years Configured via CA certificate not-after date; inheritable from upstream CA in sub-CA mode
End-entity web server cert 13 years (trending shorter) Profile max_ttl configurable; ACME issuer typically 90 days; SC-081v3 mandating 47 days by 2029
Code signing cert 28 years Profile enforcement via max_ttl; not primary certctl use case
Short-lived credentials < 1 hour recommended Profile TTL < 1 hour; exempt from CRL/OCSP (expiry is sufficient revocation); auto-expiry on scheduler tick
OCSP signing key 12 years Embedded OCSP responder uses issuing CA key (same period as issuer) or delegated signing cert
TLS/SSL interoperability cert 12 years Trending 1 year or less; certctl's ACME/sub-CA/step-ca issuers all support short periods

Key States and Transitions (Section 5.2)

NIST defines lifecycle states for keys: pre-activation, active, suspended, deactivated, compromised, and destroyed. certctl maps these to certificate and job states:

NIST Key State certctl Equivalent Implementation
Pre-activation Pending job state / AwaitingCSR Job created but key not yet generated; awaiting agent CSR submission (agent-mode) or server keygen (demo mode)
Active Certificate status Active Cert deployed to targets and in use; within validity period (not before < now < not after)
Suspended Job state AwaitingApproval Interactive approval holds deployment job pending human review; resumes on approval or cancels on rejection
Deactivated Certificate status Expired Past not-after date; auto-transitioned by scheduler every 2 minutes; renewal eligible
Compromised Certificate status Revoked Issued via POST /api/v1/certificates/{id}/revoke with RFC 5280 revocation reason
Destroyed Archived (implementation detail) Operator responsibility; certctl retains all certs in audit trail for compliance; no destructive deletion API

State Transition Audit Trail All transitions logged to immutable audit_events table with:

  • Event type (e.g., certificate_revoked, renewal_job_completed)
  • Actor (authenticated user or agent ID)
  • Timestamp (RFC3339)
  • Resource (certificate ID)
  • Reason (revocation reason code, approval reason, etc.)
  • HTTP method, path, status (for API calls)

Example audit entry for revocation:

{
  "id": "ae-2024-0615",
  "event_type": "certificate_revoked",
  "actor": "ops-alice@example.com",
  "timestamp": "2024-06-15T14:23:00Z",
  "resource_id": "cert-web-prod-2024",
  "resource_type": "certificate",
  "description": "Revoked: reason=keyCompromise",
  "body_hash": "sha256:a1b2c3d..."
}

Algorithm Recommendations (Section 5.1, SP 800-131A)

NIST SP 800-131A Rev 2 (January 2024) categorizes cryptographic algorithms as Approved, Conditionally Approved, or Disallowed. certctl implements only NIST-approved algorithms:

Algorithm NIST Status certctl Support Notes
ECDSA P-256 Approved (128-bit security strength) Default for agent-side keygen Meets NIST curve requirements (FIPS 186-4)
ECDSA P-384 Approved (192-bit security strength) Supported via profile configuration Higher security margin; slower than P-256
ECDSA P-521 Approved (256-bit security strength) Supported via profile configuration Rarely needed; overkill for TLS
RSA 2048 Approved minimum (112-bit security, transitioning) Supported via all issuers Deprecated path; migrate to 3072+ by 2030 per NIST
RSA 3072 Approved (128-bit security) Supported via all issuers Recommended minimum for long-term security
RSA 4096 Approved (192-bit security) Supported via all issuers Supported but slower; overkill for most TLS
SHA-256 Approved Used throughout CSR signing, certificate fingerprints, audit body hashing, CRL/OCSP signing
SHA-384 Approved (192-bit) Supported where algorithm selection available Used in some CA signing scenarios
SHA-512 Approved (256-bit) Supported where algorithm selection available Rarely needed; SHA-256 suffices for most use cases
SHA-1 Deprecated Not used in certctl Browsers reject SHA-1 certs; certctl never generates them

Algorithm Enforcement via Profiles Certificate profiles enforce allowed key algorithms:

{
  "id": "prof-web-prod",
  "allowed_key_algorithms": ["ECDSA_P256", "ECDSA_P384", "RSA3072"]
}

Post-Quantum Cryptography (Tracking) NIST has finalized PQC standards (FIPS 204, FIPS 205) in August 2024:

  • ML-KEM (Kyber): Approved key encapsulation mechanism
  • ML-DSA (Dilithium): Approved digital signature algorithm
  • SLH-DSA (SPHINCS+): Approved stateless hash-based signature scheme

certctl will track NIST's PQC roadmap and plan integration when hybrid PQC+classical certificate formats reach browser/infrastructure support. Currently, pure PQC certificates are not widely interoperable.

Key Distribution and Transport (Section 6.2)

NIST SP 800-57 Part 1 Section 6.2 addresses secure key distribution to minimize exposure during transit. certctl implements a zero-transmission-of-private-keys model:

Private Key Distribution

  • Agent-side keygen model: Private keys never leave agent infrastructure
  • CSR transmitted over HTTPS (TLS 1.2+) with mutual TLS optional
  • API key authentication via Authorization: Bearer <api-key> header
  • All API calls logged to immutable audit trail

Signed Certificate Distribution

  • Certificates (public component) distributed via GET /agents/{id}/work over HTTPS
  • Work endpoint enriches deployment jobs with certificate PEM and metadata
  • Certificate PEM is idempotent (same cert always returns same bytes)

Target Deployment

  • Deployment to targets via local filesystem write (NGINX, Apache, HAProxy)
  • No network transmission of private keys to targets
  • Agents read local private key from CERTCTL_KEY_DIR on deployment
  • For appliances without agents (F5 BIG-IP, IIS), proxy agent pattern:
    • Proxy agent runs in same trust zone as appliance
    • Proxy agent holds target API credentials (iControl, WinRM)
    • Control plane never communicates with appliance directly
    • Deployment request includes certificate and proxy agent ID
    • Proxy agent executes deployment via appliance API

Revocation Distribution

  • Certificate Revocation List (CRL) via GET /api/v1/crl/{issuer_id}
    • Returns DER-encoded X.509 CRL signed by issuing CA
    • 24-hour validity period
    • Includes all revoked serials, reasons, and revocation timestamps
    • Subject to URL caching; OCSP preferred for real-time revocation
  • OCSP via GET /api/v1/ocsp/{issuer_id}/{serial}
    • Returns DER-encoded OCSP response (OCSPResponse ASN.1 structure)
    • Signed by issuing CA (or delegated OCSP signing cert)
    • Responds with good/revoked/unknown status
    • Real-time, more bandwidth-efficient than CRL polling

Revocation and Compromise (NIST SP 800-57 Part 3)

NIST SP 800-57 Part 3 covers revocation (Section 2.5) when keys are suspected compromised or no longer needed. certctl implements comprehensive revocation infrastructure:

Revocation API

  • Endpoint: POST /api/v1/certificates/{id}/revoke
  • Request body:
    {
      "reason": "keyCompromise",
      "reason_text": "Private key exposed in log file"
    }
    
  • Supports all 8 RFC 5280 revocation reason codes:
    • unspecified — no specific reason provided
    • keyCompromise — private key suspected compromised
    • caCompromise — issuing CA key compromised
    • affiliationChanged — subject org/affiliation changed
    • superseded — cert superseded by newer cert
    • cessationOfOperation — key no longer in use
    • certificateHold — temporary hold (rarely used)
    • privilegeWithdrawn — subject authorization withdrawn

Revocation Recording

  • Certificate status updated to Revoked
  • Entry recorded in certificate_revocations table with:
    • Certificate serial number
    • Revocation timestamp
    • Revocation reason code
    • Issuer ID
  • Idempotent (revoking an already-revoked cert is safe; returns 200 OK)

Issuer Notification (Best-Effort)

  • Control plane calls issuer.RevokeCertificate(ctx, serial, reason) on issuing connector
  • Failure does not block the revocation (async, logged, retried)
  • Supported issuers:
    • Local CA: generates new CRL immediately
    • ACME: submits revocation to ACME server (RFC 8555 Section 7.6)
    • step-ca: calls /revoke API
    • OpenSSL: executes user-provided revocation script

Revocation Notifications

  • Notifiers triggered after revocation recorded: Slack, Teams, PagerDuty, OpsGenie, email, webhook
  • Message includes certificate common name, issuer, reason, actor, timestamp
  • Delivery is asynchronous and retried on failure

CRL and OCSP Distribution

  • CRL updated on every revocation (or scheduled refresh for non-issued revocations)
  • OCSP responder queries revocation table in real-time
  • Short-lived certificate exemption: certs with TTL < 1 hour skip CRL/OCSP (expiry is sufficient revocation)

Revocation Audit Trail All revocation events logged:

  • Event type: certificate_revoked
  • Actor: authenticated user or service
  • Reason code: RFC 5280 enum
  • Timestamp: RFC3339
  • Issuer notification status: success or error reason

Alignment Summary Table

NIST SP 800-57 Area Status Coverage Notes
Key Generation Aligned 100% Agent-side ECDSA P-256 using crypto/rand; server mode flagged as demo-only
Key Storage ⚠️ Partially Aligned 80% Filesystem with 0600 perms; HSM support planned V5
Cryptoperiods Aligned 100% Profile-enforced max_ttl; threshold-based renewal alerting
Key States Aligned 100% Full lifecycle tracking with immutable audit trail
Algorithms Aligned 100% NIST-approved algorithms only; post-quantum tracking in progress
Key Distribution Aligned 100% Private keys never transmitted; CSR/cert over TLS; agent-local deployment
Revocation Aligned 100% CRL, OCSP, all RFC 5280 reason codes; real-time updates

Gaps and Remediation Roadmap

V2 (Current)

  • Agent-side key generation
  • Profile-enforced cryptoperiods
  • CRL and OCSP distribution
  • RFC 5280 revocation support
  • Immutable audit trail

V3 (Planned: 2026)

  • Role-based access control (limit revocation/approval to authorized operators)
  • Bulk revocation by profile/owner/agent (fleet-level revocation policy)

V5 (Planned: 2027+)

  • HSM support for CA key storage
  • PKCS#11 integration for hardware tokens
  • FIPS 140-2/3 validated crypto module (BoringCrypto build or external FIPS library)
  • Key destruction API (explicit secure erasure of agent keys)
  • Key escrow / recovery mechanism (backup encrypted private keys for disaster recovery)

Post-Quantum (2027+)

  • ML-KEM and ML-DSA support when browser/TLS ecosystem supports hybrid certificates
  • Migration path documentation (how to transition existing RSA certs to PQC)

References

Questions or Corrections?

This document reflects certctl's implementation as of March 2026. For the latest code, refer to:

  • Key generation: cmd/agent/main.go (agent keygen) and internal/service/renewal.go (server keygen)
  • Key storage: internal/config/config.go (CERTCTL_KEY_DIR, CERTCTL_CA_CERT_PATH)
  • Revocation: internal/service/revocation.go and internal/api/handler/certificates.go
  • Audit trail: internal/api/middleware/audit.go