Documentation
¶
Overview ¶
Package keyrotation drives cluster-key rotation for the in-cluster secret store.
Rotation is three steps with a strict order, because getting it wrong loses data rather than failing loudly:
- Mint a key and persist the ring. Nothing may be sealed with a key that is not yet on disk — a crash in that window leaves stored versions naming a key the cluster no longer has, and nothing can recover them.
- Re-wrap every version off the old key. Only the wrapped data key moves; the ciphertext is never rewritten, so this costs a few dozen bytes per version however large the secret is.
- Retire the old key, once nothing references it. Retiring early is the same data loss as step 1 in reverse.
The in-flight state lives in a key_rotation entity so a restart resumes rather than restarting, and so the age-based trigger and `miren secret rotate-key` share one path.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// CheckInterval is how often the current key's age is examined.
CheckInterval time.Duration
// MaxKeyAge is how old the current key may get before rotation starts.
// Zero disables the automatic trigger, leaving rotation to the operator.
MaxKeyAge time.Duration
}
Config tunes when a cluster rotates on its own.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the built-in rotation policy.
type Controller ¶
type Controller struct {
Log *slog.Logger
EC *entityserver.Client
Backend *cluster.Backend
DataPath string
Config Config
// contains filtered or unexported fields
}
Controller advances key rotations and starts them when the current key ages out.
func (*Controller) Begin ¶
func (c *Controller) Begin(ctx context.Context) error
Begin starts a rotation now, for an operator who does not want to wait for the age policy — which is every incident.
It refuses while one is in flight rather than stacking, since two rotations would each be trying to retire a key the other still needs.
func (*Controller) Start ¶
func (c *Controller) Start(ctx context.Context)
Start begins the rotation loop.