Skip to content

Commit b158f65

Browse files
committed
Update API as per the ongoing discussion
Signed-off-by: chiragkyal <ckyal@redhat.com>
1 parent c3d2305 commit b158f65

1 file changed

Lines changed: 34 additions & 16 deletions

File tree

enhancements/storage/csi-secrets-store-rotation-and-wif.md

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ type SecretsStoreCSIDriverConfigSpec struct {
283283

284284
// tokenRequests controls service account token configuration for
285285
// workload identity federation (WIF) with cloud providers.
286+
// When omitted, the operator preserves any existing tokenRequests
287+
// already configured on the CSIDriver object without modification.
286288
// +optional
287289
TokenRequests *SecretsStoreTokenRequests `json:"tokenRequests,omitempty"`
288290
}
@@ -328,15 +330,18 @@ type SecretsStoreTokenRequests struct {
328330

329331
// ManagedTokenRequests holds the configuration for operator-managed
330332
// service account token requests.
333+
// +kubebuilder:validation:MinProperties=1
331334
type ManagedTokenRequests struct {
332335
// audiences specifies service account token audiences that kubelet will
333336
// provide to the CSI driver during NodePublishVolume calls. These tokens
334337
// enable workload identity federation (WIF) with cloud providers such as
335338
// AWS, Azure, and GCP.
339+
// When empty, the operator clears all tokenRequests from the CSIDriver object.
336340
// +optional
337-
// +listType=atomic
341+
// +listType=map
342+
// +listMapKey=audience
338343
// +kubebuilder:validation:MaxItems=10
339-
Audiences []SecretsStoreTokenRequest `json:"audiences,omitempty"`
344+
Audiences *[]SecretsStoreTokenRequest `json:"audiences,omitempty"`
340345
}
341346

342347
// SecretRotationType determines the secret rotation behavior for the
@@ -371,16 +376,20 @@ type SecretsStoreSecretRotation struct {
371376
// custom holds the custom rotation configuration.
372377
// Only valid when type is "Custom".
373378
// +optional
374-
Custom *CustomSecretRotation `json:"custom,omitempty"`
379+
Custom CustomSecretRotation `json:"custom,omitzero"`
375380
}
376381

377382
// CustomSecretRotation holds configuration for custom secret rotation behavior.
383+
// +kubebuilder:validation:MinProperties=1
378384
type CustomSecretRotation struct {
379385
// rotationPollIntervalSeconds is the minimum time in seconds between
380386
// secret rotation attempts. The driver skips provider calls if less than
381387
// this interval has elapsed since the last successful rotation.
382-
// When omitted, the platform chooses a reasonable default (currently 120).
383-
// +default=120
388+
// Must be at least 1 second and no more than 31560000 seconds (~1 year).
389+
// When omitted, this means no opinion and the platform is left to choose a
390+
// reasonable default, which is subject to change over time.
391+
// +kubebuilder:validation:Minimum=1
392+
// +kubebuilder:validation:Maximum=31560000
384393
// +optional
385394
RotationPollIntervalSeconds *int32 `json:"rotationPollIntervalSeconds,omitempty"`
386395
}
@@ -400,13 +409,13 @@ type SecretsStoreTokenRequest struct {
400409
// expirationSeconds is the requested duration of validity of the
401410
// service account token. The token issuer may return a token with
402411
// a different validity duration.
403-
// When omitted, the token expiration is determined by the kube-apiserver
404-
// (defaults to 1 hour). Must be at least 600 seconds (10 minutes) and
405-
// no more than 4294967296 (1 << 32) seconds.
412+
// When omitted, the token expiration is determined by the kube-apiserver.
413+
// Must be at least 600 seconds (10 minutes) and no more than 315360000
414+
// seconds (~10 years).
406415
// +kubebuilder:validation:Minimum=600
407-
// +kubebuilder:validation:Maximum=4294967296
416+
// +kubebuilder:validation:Maximum=315360000
408417
// +optional
409-
ExpirationSeconds *int64 `json:"expirationSeconds,omitempty"`
418+
ExpirationSeconds int64 `json:"expirationSeconds,omitempty"`
410419
}
411420
```
412421

@@ -460,16 +469,24 @@ spec:
460469
#### Validation Rules
461470

462471
- `secretsStore` must be set if and only if `driverType` is `SecretsStore`
463-
- `rotationPollIntervalSeconds` defaults to 120 seconds (2 minutes). No minimum
464-
is enforced at the API level; the administrator is trusted to choose an appropriate value.
472+
- `SecretsStoreCSIDriverConfigSpec` has `MinProperties=1` to prevent `secretsStore: {}`.
473+
- `rotationPollIntervalSeconds` must be between 1 and 31560000 (~1 year). When omitted,
474+
the platform chooses a reasonable default (subject to change over time).
475+
- `expirationSeconds` must be between 600 (10 minutes) and 315360000 (~10 years).
476+
- `audiences` entries must have unique `audience` values, enforced automatically via
477+
`+listType=map` with `+listMapKey=audience`. This also enables SSA patch operations
478+
(e.g., adding a single audience without replacing the full list).
479+
- `ManagedTokenRequests` has `MinProperties=1` to prevent `managed: {}`. The only valid
480+
way to clear WIF configuration is `managed: { audiences: [] }` (explicit empty list).
481+
- `CustomSecretRotation` has `MinProperties=1` to prevent `custom: {}`.
465482
- `tokenRequests.type` is immutable once set to `"Managed"`:
466483
- The `type` field cannot be changed from `"Managed"` back to `"Unmanaged"` (CEL
467484
transition rule on the struct: `!has(oldSelf.type) || oldSelf.type != 'Managed' || self.type == 'Managed'`).
468485
- The `tokenRequests` struct cannot be removed from `secretsStore` if its `type`
469486
was `"Managed"` (CEL rule on the parent struct prevents removal).
470487
- This is a one-way transition: once the operator takes ownership of `tokenRequests`,
471488
the administrator cannot revert to unmanaged mode. To clear WIF configuration,
472-
set `type: "Managed"` with `managed.audiences` set to an empty list instead.
489+
set `managed.audiences` to an empty list (`audiences: []`).
473490
- `secretRotation` and `tokenRequests` are discriminated unions:
474491
- `secretRotation.type` is the discriminator with values `"None"` (disabled) or `"Custom"` (enabled with config).
475492
- `tokenRequests.type` is the discriminator with values `"Managed"` or `"Unmanaged"`.
@@ -544,10 +561,11 @@ reconciliation will trigger immediately when the administrator changes the
544561

545562
#### Default Behavior and Upgrade Safety
546563

547-
All new fields will have defaults that match the operator's current hardcoded
548-
behavior:
564+
All new fields use "no opinion" semantics when omitted — the operator applies
565+
defaults internally (not via CRD-level `+default`):
549566
- When `secretRotation` is omitted, the operator defaults to rotation enabled with a 2-minute poll interval
550-
- When `secretRotation.type` is `"Custom"`, `rotationPollIntervalSeconds` defaults to `120`
567+
- When `secretRotation.type` is `"Custom"` and `rotationPollIntervalSeconds` is omitted,
568+
the operator chooses a reasonable default (currently 120 seconds)
551569
- When `tokenRequests` is omitted, the operator preserves existing CSIDriver tokenRequests (Unmanaged behavior)
552570

553571
Clusters upgrading to the new operator version with no `driverConfig` set will see

0 commit comments

Comments
 (0)