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>
This commit is contained in:
shankar0123
2026-03-15 13:51:41 -04:00
parent 11a5ca6135
commit e2821c448a
15 changed files with 576 additions and 184 deletions
+3 -1
View File
@@ -20,9 +20,11 @@ type Connector interface {
}
// DeploymentRequest contains the parameters for deploying a certificate to a target.
// Note: This request NEVER contains a private key. The agent generates keys locally.
// In agent keygen mode, KeyPEM is populated from the agent's local key store.
// In server keygen mode (demo only), KeyPEM may be empty if the key was embedded in the cert version.
type DeploymentRequest struct {
CertPEM string `json:"cert_pem"`
KeyPEM string `json:"key_pem,omitempty"`
ChainPEM string `json:"chain_pem"`
TargetConfig json.RawMessage `json:"target_config"`
Metadata map[string]string `json:"metadata,omitempty"`