mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:41:30 +00:00
a579a84c7f
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>
84 lines
3.6 KiB
Go
84 lines
3.6 KiB
Go
package domain
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// ManagedCertificate represents a certificate managed by the control plane.
|
|
type ManagedCertificate struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
CommonName string `json:"common_name"`
|
|
SANs []string `json:"sans"`
|
|
Environment string `json:"environment"`
|
|
OwnerID string `json:"owner_id"`
|
|
TeamID string `json:"team_id"`
|
|
IssuerID string `json:"issuer_id"`
|
|
TargetIDs []string `json:"target_ids"`
|
|
RenewalPolicyID string `json:"renewal_policy_id"`
|
|
CertificateProfileID string `json:"certificate_profile_id,omitempty"`
|
|
Status CertificateStatus `json:"status"`
|
|
ExpiresAt time.Time `json:"expires_at"`
|
|
Tags map[string]string `json:"tags"`
|
|
LastRenewalAt *time.Time `json:"last_renewal_at,omitempty"`
|
|
LastDeploymentAt *time.Time `json:"last_deployment_at,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// CertificateVersion represents a specific version of a certificate.
|
|
type CertificateVersion struct {
|
|
ID string `json:"id"`
|
|
CertificateID string `json:"certificate_id"`
|
|
SerialNumber string `json:"serial_number"`
|
|
NotBefore time.Time `json:"not_before"`
|
|
NotAfter time.Time `json:"not_after"`
|
|
FingerprintSHA256 string `json:"fingerprint_sha256"`
|
|
PEMChain string `json:"pem_chain"`
|
|
CSRPEM string `json:"csr_pem"`
|
|
KeyAlgorithm string `json:"key_algorithm,omitempty"`
|
|
KeySize int `json:"key_size,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// CertificateStatus represents the lifecycle status of a managed certificate.
|
|
type CertificateStatus string
|
|
|
|
const (
|
|
CertificateStatusPending CertificateStatus = "Pending"
|
|
CertificateStatusActive CertificateStatus = "Active"
|
|
CertificateStatusExpiring CertificateStatus = "Expiring"
|
|
CertificateStatusExpired CertificateStatus = "Expired"
|
|
CertificateStatusRenewalInProgress CertificateStatus = "RenewalInProgress"
|
|
CertificateStatusFailed CertificateStatus = "Failed"
|
|
CertificateStatusRevoked CertificateStatus = "Revoked"
|
|
CertificateStatusArchived CertificateStatus = "Archived"
|
|
)
|
|
|
|
// RenewalPolicy defines renewal parameters for a managed certificate.
|
|
type RenewalPolicy struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
RenewalWindowDays int `json:"renewal_window_days"`
|
|
AutoRenew bool `json:"auto_renew"`
|
|
MaxRetries int `json:"max_retries"`
|
|
RetryInterval int `json:"retry_interval_seconds"`
|
|
AlertThresholdsDays []int `json:"alert_thresholds_days"`
|
|
CertificateProfileID string `json:"certificate_profile_id,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// DefaultAlertThresholds returns the standard alert thresholds when none are configured.
|
|
func DefaultAlertThresholds() []int {
|
|
return []int{30, 14, 7, 0}
|
|
}
|
|
|
|
// EffectiveAlertThresholds returns the configured thresholds or defaults if empty.
|
|
func (p *RenewalPolicy) EffectiveAlertThresholds() []int {
|
|
if len(p.AlertThresholdsDays) > 0 {
|
|
return p.AlertThresholdsDays
|
|
}
|
|
return DefaultAlertThresholds()
|
|
}
|