Documentation
¶
Index ¶
- Constants
- Variables
- func MintAndStoreCA(ctx context.Context, s MintStore, master *keystore.Master, logger *slog.Logger, ...) (*models.CA, bool, error)
- func RotateAndStoreCA(ctx context.Context, s store.Store, master *keystore.Master, ...) (*models.CA, error)
- func ShouldRenew(notBefore, notAfter time.Time) bool
- type Blocklist
- type CAManager
- type CAResolver
- type CAStore
- type HostCertInfo
- type MintRequest
- type MintStore
- type Rotation
- type SignRequest
Constants ¶
const DefaultAgentCertDuration = 30 * 24 * time.Hour
DefaultAgentCertDuration is the lifetime of host certificates minted for agent-managed hosts that auto-rotate via the poll loop (ADR 0004). 30 days strikes a balance between rotation overhead and revocation latency.
const DefaultMobileCertDuration = 365 * 24 * time.Hour
DefaultMobileCertDuration is the lifetime of host certificates minted for Mobile Nebula clients (kind=mobile). Mobile rotation requires the operator to re-download a bundle and the user to re-import it manually, so a longer lifetime reduces operator burden. The signer clamps to remaining CA validity (see signer.go), so practical lifetime is min(365d, CA_remaining). Revocation via the blocklist remains the immediate security control.
Variables ¶
var ErrMasterRequired = errors.New("master keystore is required")
Functions ¶
func MintAndStoreCA ¶
func MintAndStoreCA(ctx context.Context, s MintStore, master *keystore.Master, logger *slog.Logger, req MintRequest) (*models.CA, bool, error)
MintAndStoreCA creates a new CA for the given operator and persists it to the store. If SkipIfActive is set and the operator already has an active CA, the existing one is returned with minted=false. Returns (ca, true, nil) on successful creation, (existing, false, nil) if skipped due to existing CA, or (nil, false, err) on failure.
func RotateAndStoreCA ¶
func RotateAndStoreCA( ctx context.Context, s store.Store, master *keystore.Master, logger *slog.Logger, oldCA *models.CA, ) (*models.CA, error)
RotateAndStoreCA creates a new CA that succeeds the given oldCA and persists it to the store. It implements CA rotation: minting a new certificate with the same lifetime as its predecessor, and establishing the predecessor link for trust bundle management.
The rotation is idempotent: if an active successor already exists for oldCA, it is returned without creating a duplicate. This handles cases where rotation is retried after partial failures.
func ShouldRenew ¶
ShouldRenew returns true if the certificate should be renewed. Renewal is needed when remaining TTL is less than 20% of total duration.
Types ¶
type Blocklist ¶
type Blocklist struct {
// contains filtered or unexported fields
}
Blocklist tracks blocked certificate fingerprints.
type CAManager ¶
type CAManager struct {
// contains filtered or unexported fields
}
CAManager holds a loaded CA certificate and its signing key in memory.
func LoadCAFromMaterial ¶
func LoadCAFromMaterial(certPEM []byte, rawKey ed25519.PrivateKey) (*CAManager, error)
LoadCAFromMaterial builds a CAManager from a PEM-encoded CA certificate and the raw ed25519 private key. Used by the DB-backed multi-CA path where key material is decrypted on demand via the keystore package.
func (*CAManager) CACert ¶
func (m *CAManager) CACert() cert.Certificate
CACert returns the CA certificate.
func (*CAManager) CACertFingerprint ¶
CACertFingerprint returns the SHA256 fingerprint of the CA certificate.
func (*CAManager) RawKey ¶
func (m *CAManager) RawKey() ed25519.PrivateKey
RawKey returns the in-memory ed25519 private key. Used by the migration path to re-encrypt a legacy file-based CA under the master key. Treat the returned slice as sensitive and zeroise once done.
func (*CAManager) Sign ¶
func (m *CAManager) Sign(req SignRequest) (cert.Certificate, error)
Sign creates and signs a host certificate using the CA.
func (*CAManager) Wipe ¶
func (m *CAManager) Wipe()
Wipe overwrites the in-memory plaintext signing key with zeros so it no longer lingers on the Go heap waiting for GC. Callers MUST defer this immediately after LoadByID / NewCA, per the keystore package's "zeroise the plaintext as soon as it is no longer needed" contract. After Wipe(), any subsequent Sign() will produce invalid signatures. Closes GHSA-8h84-fhqq-q58v.
Nil-safe so `defer caMgr.Wipe()` placed before the error check is also safe — load failures return nil and the defer becomes a no-op.
type CAResolver ¶
type CAResolver struct {
// contains filtered or unexported fields
}
CAResolver loads CAs from the database, decrypts their private key material with the master keystore, and returns a CAManager bound to the requested CA. The unwrapped key material lives only inside the returned manager; CAResolver does NOT cache anything across calls so a disable / rotation takes effect immediately.
func NewCAResolver ¶
func NewCAResolver(store CAStore, master *keystore.Master) *CAResolver
NewCAResolver builds a resolver. The master keystore must be the same one used when CAs were created/imported.
type CAStore ¶
CAStore is the subset of the application store interface required by CAResolver. Kept narrow so this package can depend only on what it uses.
type HostCertInfo ¶
HostCertInfo holds certificate timing for renewal checks.
func FindHostsForRenewal ¶
func FindHostsForRenewal(hosts []HostCertInfo) []HostCertInfo
FindHostsForRenewal filters hosts that need certificate renewal.
type MintRequest ¶
type MintRequest struct {
// Operator is the owner of the CA to be minted.
Operator *models.Operator
// Name is the user-facing name for the CA (e.g. "alice-default").
Name string
// Duration is the validity period for the cert (e.g. 10 * 365 * 24 * time.Hour).
Duration time.Duration
// SkipIfActive, when true, causes the function to return an existing active CA
// for the operator instead of minting a new one (idempotent behavior).
SkipIfActive bool
}
MintRequest describes parameters for MintAndStoreCA.
type MintStore ¶
type MintStore interface {
// CreateCA persists a new CA record to the store.
CreateCA(ctx context.Context, c *models.CA) error
// ListCAsByOwner returns all CAs owned by the given operator.
ListCAsByOwner(ctx context.Context, ownerID string) ([]*models.CA, error)
// AddAuditEntry records an action in the audit log (best-effort).
AddAuditEntry(ctx context.Context, actor, action, resource, details string) error
}
MintStore is the narrow interface for store operations needed by MintAndStoreCA. It isolates pki from a concrete dependency on store.Store, enabling better testing and layering.
type Rotation ¶
type Rotation struct {
// contains filtered or unexported fields
}
Rotation manages a CA rotation: old CA + new CA in parallel.
func NewRotation ¶
NewRotation creates a new CA and sets up a rotation from the old CA.
func (*Rotation) TrustBundle ¶
TrustBundle returns PEM bytes containing both CA certificates. Agents should trust both during the transition period.