Skip to content

Commit 7620b7d

Browse files
committed
Feat add flag for registry initialization key order priority
A flag has been added to be able to choose which key will be fetched for encrypting secret Test add key order priority param to initKeyRegistry function Signed-off-by: Sybernatus <jerome.je.garcia@gmail.com>
1 parent a535d1b commit 7620b7d

4 files changed

Lines changed: 44 additions & 13 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,18 @@ It doesn't help that this feature has been historically called "key rotation", w
620620
Sealed secrets are not automatically rotated and old keys are not deleted
621621
when new keys are generated. Old `SealedSecret` resources can be still decrypted (that's because old sealing keys are not deleted).
622622

623+
### Key registry init priority order
624+
625+
When the controller starts, it will initialize the key registry. The most recent key is used to seal secrets. By default, this certificate is chosen based on the NotBefore attribute of the certificate. If you want to change the priority order of the keys in the registry, you can use the `--key-order-priority` flag.
626+
627+
The `--key-order-priority` flag accepts the following values:
628+
- `CertNotBefore`: (default) The key registry will be ordered based on the NotBefore attribute of the key certificate.
629+
- `SecretCreationTimestamp`: The key registry will be ordered based on the creation timestamp of the secret.
630+
631+
This flag influences the public key used to encrypt secrets and the certificate retrieved by `kubeseal --fetch-cert`.
632+
633+
634+
623635
### User secret rotation
624636

625637
The *sealing key* renewal and SealedSecret rotation are **not a substitute** for rotating your actual secrets.

cmd/controller/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ import (
2020
)
2121

2222
const (
23-
flagEnvPrefix = "SEALED_SECRETS"
24-
defaultKeyRenewPeriod = 30 * 24 * time.Hour
23+
flagEnvPrefix = "SEALED_SECRETS"
24+
defaultKeyRenewPeriod = 30 * 24 * time.Hour
25+
defaultKeyOrderPriority = "CertNotBefore"
2526
)
2627

2728
var (
@@ -36,6 +37,7 @@ func bindControllerFlags(f *controller.Flags, fs *flag.FlagSet) {
3637
fs.StringVar(&f.MyCN, "my-cn", "", "Common name to be used as issuer/subject DN in generated certificate.")
3738

3839
fs.DurationVar(&f.KeyRenewPeriod, "key-renew-period", defaultKeyRenewPeriod, "New key generation period (automatic rotation deactivated if 0)")
40+
fs.StringVar(&f.KeyOrderPriority, "key-order-priority", defaultKeyOrderPriority, "Ordering of keys based on NotBefore certificate attribute or secret creation timestamp.")
3941
fs.BoolVar(&f.AcceptV1Data, "accept-deprecated-v1-data", true, "Accept deprecated V1 data field.")
4042
fs.StringVar(&f.KeyCutoffTime, "key-cutoff-time", "", "Create a new key if latest one is older than this cutoff time. RFC1123 format with numeric timezone expected.")
4143
fs.BoolVar(&f.NamespaceAll, "all-namespaces", true, "Scan all namespaces or only the current namespace (default=true).")

pkg/controller/main.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type Flags struct {
4040
ValidFor time.Duration
4141
MyCN string
4242
KeyRenewPeriod time.Duration
43+
KeyOrderPriority string
4344
AcceptV1Data bool
4445
KeyCutoffTime string
4546
NamespaceAll bool
@@ -62,7 +63,7 @@ func initKeyPrefix(keyPrefix string) (string, error) {
6263
return validateKeyPrefix(keyPrefix)
6364
}
6465

65-
func initKeyRegistry(ctx context.Context, client kubernetes.Interface, r io.Reader, namespace, prefix, label string, keysize int) (*KeyRegistry, error) {
66+
func initKeyRegistry(ctx context.Context, client kubernetes.Interface, r io.Reader, namespace, prefix, label string, keysize int, keyOrderPriority string) (*KeyRegistry, error) {
6667
slog.Info("Searching for existing private keys")
6768
secretList, err := client.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{
6869
LabelSelector: keySelector.String(),
@@ -88,14 +89,30 @@ func initKeyRegistry(ctx context.Context, client kubernetes.Interface, r io.Read
8889
if err != nil {
8990
slog.Error("Error reading key", "secret", secret.Name, "error", err)
9091
}
91-
if err := keyRegistry.registerNewKey(secret.Name, key, certs[0], secret.GetCreationTimestamp().Time); err != nil {
92+
93+
// Select ordering time based on the keyOrderPriority flag
94+
orderingTime := getKeyOrderPriority(keyOrderPriority, certs[0], secret)
95+
96+
if err := keyRegistry.registerNewKey(secret.Name, key, certs[0], orderingTime); err != nil {
9297
return nil, err
9398
}
9499
slog.Info("registered private key", "secretname", secret.Name)
95100
}
96101
return keyRegistry, nil
97102
}
98103

104+
func getKeyOrderPriority(keyOrderPriority string, cert *x509.Certificate, secret corev1.Secret) time.Time {
105+
switch keyOrderPriority {
106+
case "CertNotBefore":
107+
return cert.NotBefore
108+
case "SecretCreationTimestamp":
109+
return secret.GetCreationTimestamp().Time
110+
default:
111+
slog.Error("Invalid keyOrderPriority. Use CertNotBefore or SecretCreationTimestamp", "keyOrderPriority", keyOrderPriority)
112+
}
113+
return cert.NotBefore
114+
}
115+
99116
func myNamespace() string {
100117
if ns := os.Getenv("POD_NAMESPACE"); ns != "" {
101118
return ns
@@ -169,7 +186,7 @@ func Main(f *Flags, version string) error {
169186
return err
170187
}
171188

172-
keyRegistry, err := initKeyRegistry(ctx, clientset, rand.Reader, myNs, prefix, SealedSecretsKeyLabel, f.KeySize)
189+
keyRegistry, err := initKeyRegistry(ctx, clientset, rand.Reader, myNs, prefix, SealedSecretsKeyLabel, f.KeySize, f.KeyOrderPriority)
173190
if err != nil {
174191
return err
175192
}

pkg/controller/main_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestInitKeyRegistry(t *testing.T) {
4949
client := fake.NewSimpleClientset()
5050
client.PrependReactor("create", "secrets", generateNameReactor)
5151

52-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024)
52+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024, "CertNotBefore")
5353
if err != nil {
5454
t.Fatalf("initKeyRegistry() returned err: %v", err)
5555
}
@@ -69,7 +69,7 @@ func TestInitKeyRegistry(t *testing.T) {
6969

7070
// Due to limitations of the fake client, we cannot test whether initKeyRegistry is able
7171
// to pick up existing keys
72-
_, err = initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024)
72+
_, err = initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024, "CertNotBefore")
7373
if err != nil {
7474
t.Fatalf("initKeyRegistry() returned err: %v", err)
7575
}
@@ -84,7 +84,7 @@ func TestInitKeyRotation(t *testing.T) {
8484
client := fake.NewSimpleClientset()
8585
client.PrependReactor("create", "secrets", generateNameReactor)
8686

87-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024)
87+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024, "CertNotBefore")
8888
if err != nil {
8989
t.Fatalf("initKeyRegistry() returned err: %v", err)
9090
}
@@ -125,7 +125,7 @@ func TestInitKeyRotationTick(t *testing.T) {
125125
client := fake.NewSimpleClientset()
126126
client.PrependReactor("create", "secrets", generateNameReactor)
127127

128-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024)
128+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", "label", 1024, "CertNotBefore")
129129
if err != nil {
130130
t.Fatalf("initKeyRegistry() returned err: %v", err)
131131
}
@@ -180,7 +180,7 @@ func TestReuseKey(t *testing.T) {
180180

181181
client.ClearActions()
182182

183-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024)
183+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024, "CertNotBefore")
184184
if err != nil {
185185
t.Fatalf("initKeyRegistry() returned err: %v", err)
186186
}
@@ -227,7 +227,7 @@ func TestRenewStaleKey(t *testing.T) {
227227
t.Errorf("writeKey() failed with: %v", err)
228228
}
229229

230-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024)
230+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024, "CertNotBefore")
231231
if err != nil {
232232
t.Fatalf("initKeyRegistry() returned err: %v", err)
233233
}
@@ -284,7 +284,7 @@ func TestKeyCutoff(t *testing.T) {
284284
t.Errorf("writeKey() failed with: %v", err)
285285
}
286286

287-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024)
287+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024, "CertNotBefore")
288288
if err != nil {
289289
t.Fatalf("initKeyRegistry() returned err: %v", err)
290290
}
@@ -351,7 +351,7 @@ func TestLegacySecret(t *testing.T) {
351351

352352
client.ClearActions()
353353

354-
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024)
354+
registry, err := initKeyRegistry(ctx, client, rand, "namespace", "prefix", SealedSecretsKeyLabel, 1024, "CertNotBefore")
355355
if err != nil {
356356
t.Fatalf("initKeyRegistry() returned err: %v", err)
357357
}

0 commit comments

Comments
 (0)