Skip to content

Commit 997b05a

Browse files
committed
feat: implement Vault credential refresh logic and update user manual
1 parent 87a473c commit 997b05a

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

controllers/k8s_scan/deployment_handler.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,21 @@ func (n *DeploymentHandler) Reconcile(ctx context.Context) (ctrl.Result, error)
178178
}
179179
}
180180

181-
return ctrl.Result{}, nil
181+
// If any external cluster uses VaultAuth, request an earlier requeue so the
182+
// operator refreshes Vault credentials before they expire. Default to half
183+
// the requested TTL, with a floor of 10 minutes and a ceiling of 1 hour.
184+
result := ctrl.Result{}
185+
for i := range n.Mondoo.Spec.KubernetesResources.ExternalClusters {
186+
cluster := &n.Mondoo.Spec.KubernetesResources.ExternalClusters[i]
187+
if cluster.VaultAuth != nil {
188+
requeue := vaultRequeueInterval(cluster.VaultAuth.TTL)
189+
if result.RequeueAfter == 0 || requeue < result.RequeueAfter {
190+
result.RequeueAfter = requeue
191+
}
192+
}
193+
}
194+
195+
return result, nil
182196
}
183197

184198
func (n *DeploymentHandler) syncCronJob(ctx context.Context) error {

controllers/k8s_scan/deployment_handler_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ func (s *DeploymentHandlerSuite) TestReconcile_ExternalCluster_VaultAuth() {
500500

501501
result, err := d.Reconcile(s.ctx)
502502
s.NoError(err)
503-
s.True(result.IsZero())
503+
s.Equal(30*time.Minute, result.RequeueAfter, "should requeue at default interval when no TTL is set")
504504

505505
// Verify kubeconfig Secret was created
506506
kubeconfigSecret := &corev1.Secret{}
@@ -599,7 +599,7 @@ func (s *DeploymentHandlerSuite) TestReconcile_ExternalCluster_VaultAuth_WithCAC
599599

600600
result, err := d.Reconcile(s.ctx)
601601
s.NoError(err)
602-
s.True(result.IsZero())
602+
s.Equal(30*time.Minute, result.RequeueAfter, "should requeue at default interval when no TTL is set")
603603

604604
// Verify mock received the Vault CA cert bytes
605605
s.Equal([]byte("-----BEGIN CERTIFICATE-----\nvault-ca\n-----END CERTIFICATE-----"), receivedVaultCA)
@@ -758,7 +758,7 @@ func (s *DeploymentHandlerSuite) createDeploymentHandlerWithVaultMock(vaultFetch
758758
MondooOperatorConfig: &mondoov1alpha2.MondooOperatorConfig{},
759759
MondooClientBuilder: mondooclient.NewClient,
760760
VaultTokenFetcher: vaultFetcher,
761-
SATokenPath: tmpFile.Name(),
761+
SATokenPath: tmpName,
762762
}
763763
}
764764

controllers/k8s_scan/vault.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/base64"
99
"fmt"
1010
"strings"
11+
"time"
1112

1213
vault "github.com/hashicorp/vault-client-go"
1314
"github.com/hashicorp/vault-client-go/schema"
@@ -93,6 +94,35 @@ func DefaultVaultTokenFetcher(ctx context.Context, saToken string, config v1alph
9394
return token, nil
9495
}
9596

97+
// vaultRequeueInterval calculates a reconcile requeue interval based on the Vault TTL.
98+
// It targets half the TTL so credentials are refreshed well before expiry, with a
99+
// floor of 10 minutes and a ceiling of 1 hour.
100+
func vaultRequeueInterval(ttl string) time.Duration {
101+
const (
102+
minInterval = 10 * time.Minute
103+
maxInterval = 1 * time.Hour
104+
defaultInterval = 30 * time.Minute
105+
)
106+
107+
if ttl == "" {
108+
return defaultInterval
109+
}
110+
111+
d, err := time.ParseDuration(ttl)
112+
if err != nil {
113+
return defaultInterval
114+
}
115+
116+
half := d / 2
117+
if half < minInterval {
118+
return minInterval
119+
}
120+
if half > maxInterval {
121+
return maxInterval
122+
}
123+
return half
124+
}
125+
96126
// VaultKubeconfigSecretName returns the name for the Vault kubeconfig Secret.
97127
func VaultKubeconfigSecretName(prefix, clusterName string) string {
98128
return fmt.Sprintf("%s-vault-kubeconfig-%s", prefix, clusterName)
@@ -126,7 +156,7 @@ current-context: default
126156
users:
127157
- name: vault
128158
user:
129-
token: %s
159+
token: "%s"
130160
`, clusterConfig, token)
131161
}
132162

docs/user-manual.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ externalClusters:
453453

454454
> **Note: Credential refresh timing**
455455
>
456-
> Vault credentials are refreshed each time the operator reconciles (typically every 7 days, or when configuration changes). Ensure the requested TTL is longer than the operator's reconcile interval. If you need more frequent credential rotation, consider adjusting the operator's reconcile schedule.
456+
> When VaultAuth is configured, the operator automatically reconciles at half the requested TTL (clamped between 10 minutes and 1 hour) to refresh credentials before they expire. For example, a `ttl: "1h"` results in a 30-minute refresh interval. If no TTL is specified, the operator defaults to refreshing every 30 minutes.
457457

458458
## Container Image Scanning
459459

0 commit comments

Comments
 (0)