Skip to content

SSCSI-245: Add Secrets Store CSI driver configuration to ClusterCSIDriver API#2846

Open
chiragkyal wants to merge 3 commits into
openshift:masterfrom
chiragkyal:configure-secret-rotation-and-wif
Open

SSCSI-245: Add Secrets Store CSI driver configuration to ClusterCSIDriver API#2846
chiragkyal wants to merge 3 commits into
openshift:masterfrom
chiragkyal:configure-secret-rotation-and-wif

Conversation

@chiragkyal

@chiragkyal chiragkyal commented May 18, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds SecretsStore as a new CSIDriverType enum value in the
    ClusterCSIDriver API (operator.openshift.io/v1)

  • Introduces SecretsStoreCSIDriverConfigSpec with configuration for:

    • Secret rotation: toggle automatic rotation on/off and configure
      the poll interval (defaults to enabled with 2m interval)
    • Token requests: configure service account token audiences for
      workload identity federation (WIF)
  • Implements: SSCSI-254: Configurable secret rotation and WIF support for SSCSI enhancements#2012

Summary by CodeRabbit

  • New Features
    • Added support for the SecretsStore CSI driver type.
    • Introduced secret rotation configuration with policy and polling interval settings.
    • Added token request configuration for workload identity federation with audience and expiration settings.
    • Implemented validation rules to ensure secrets store configuration is only present when using the SecretsStore driver type.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 18, 2026
@openshift-ci

openshift-ci Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci

openshift-ci Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Hello @chiragkyal! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request extends the CSI driver configuration API to support Secrets Store drivers. The Go API type CSIDriverType gains a new SecretsStore constant, CSIDriverConfigSpec gains a new secretsStore union field, and three new configuration struct types are introduced: SecretsStoreCSIDriverConfigSpec, SecretsStoreSecretRotation, and SecretsStoreTokenRequest. The corresponding CRD schemas in all five cluster-profile variants are updated with matching enum extensions, secretsStore schema definitions, and x-kubernetes-validations that require secretsStore presence only when driverType is SecretsStore.

Changes

Secrets Store CSI driver support

Layer / File(s) Summary
API types and constants
operator/v1/types_csi_cluster_driver.go
Adds SecretsStore to CSIDriverType and a SecretsStore constant; adds secretsStore *SecretsStoreCSIDriverConfigSpec to CSIDriverConfigSpec; introduces SecretsStoreCSIDriverConfigSpec, SecretsStoreSecretRotation, SecretRotationPolicy and SecretsStoreTokenRequest Go types with kubebuilder validation/default tags.
CRD schemas and generated manifests
operator/v1/zz_generated.crd-manifests/*, operator/v1/zz_generated.featuregated-crd-manifests/*, payload-manifests/crds/*
Extends spec.driverConfig.driverType enum to include SecretsStore; adds spec.driverConfig.secretsStore schema (with secretRotation and tokenRequests fields, defaults and validation) across generated CRDs, feature-gated manifests, and payload manifests; adds x-kubernetes-validations to require secretsStore iff driverType == "SecretsStore".

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed PR contains no Ginkgo test files. Changes are limited to Go type definitions, CRD manifests, and generated code - not test code.
Test Structure And Quality ✅ Passed PR contains no Ginkgo test code additions or modifications. Check not applicable: only API types and CRD manifests were changed.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. Changes consist only of Go API types and CRD YAML manifests for Secrets Store CSI driver support.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests are added in this PR. Changes are limited to API type definitions and CRD YAML manifests. The SNO compatibility check does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed Pure API definition change (Go types and CRD schemas) with no deployment manifests, operators, pods, or scheduling constraints. Not applicable to topology-aware check.
Ote Binary Stdout Contract ✅ Passed PR modifies only API type definitions and CRD YAML files. The Go file contains only struct definitions with no process-level code or stdout-writing operations.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests are present in this PR; it contains only API definitions and auto-generated CRD manifests for Secrets Store CSI driver configuration. The check is not applicable.
No-Weak-Crypto ✅ Passed PR adds SecretsStore CSI driver API types and CRD schemas. No weak crypto implementations found: no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB mode, custom crypto, or non-constant-time comparisons.
Container-Privileges ✅ Passed PR modifies only API type definitions and CRD schemas, not container specifications. No container privilege flags are present.
No-Sensitive-Data-In-Logs ✅ Passed No logging of sensitive data found. PR adds type definitions with no logging statements or error handling that exposes tokens, credentials, or PII.
Title check ✅ Passed The title clearly and specifically describes the main change: adding Secrets Store CSI driver configuration support to the ClusterCSIDriver API. It directly summarizes the primary purpose of the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label May 18, 2026
@openshift-ci

openshift-ci Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign everettraven for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@chiragkyal

Copy link
Copy Markdown
Member Author

/test all

@chiragkyal

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@operator/v1/types_csi_cluster_driver.go`:
- Around line 405-411: Update the field comments for TokenRequests (type
SecretsStoreTokenRequest) and the expirationSeconds field to document the
default behavior when omitted: state that if TokenRequests is nil/empty, no
service account tokens will be requested and the CSI driver will use the
kube-apiserver's default APIAudiences (or no tokens provided), and if
expirationSeconds is omitted the token lifetime defaults to the kubelet/cluster
provider default (or a specific default value used by the implementation).
Modify the comment blocks adjacent to the TokenRequests declaration and the
expirationSeconds declaration to include these omission semantics and expected
default values/behavior so the optional nature is clear.
- Around line 162-165: The new stable API field SecretsStore
(*SecretsStoreCSIDriverConfigSpec) must be gated with an OpenShift feature gate;
add the kubebuilder marker comment
+openshift:enable:FeatureGate=YourFeatureGateName immediately above the
`SecretsStore` field declaration (the SecretsStore
*SecretsStoreCSIDriverConfigSpec line) so the field is only enabled when the
feature gate is on, and update any related docs/tests to use that feature gate
name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: c45c7b74-a5df-45a7-8fef-3c1a81dc9f5c

📥 Commits

Reviewing files that changed from the base of the PR and between 73d7ca9 and dd82f59.

⛔ Files ignored due to path filters (11)
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
📒 Files selected for processing (6)
  • operator/v1/types_csi_cluster_driver.go
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml

Comment on lines +162 to 165
// secretsStore is used to configure the Secrets Store CSI driver.
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}

@coderabbitai coderabbitai Bot May 18, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Gate the new stable v1 field behind a feature gate.

Line 162 introduces a new stable API field without a +openshift:enable:FeatureGate=... marker. That violates the stable API rollout requirement and can expose partially-supported config in GA surface.

Suggested direction
 	// secretsStore is used to configure the Secrets Store CSI driver.
+	// +openshift:enable:FeatureGate=SecretsStoreCSIDriver
 	// +optional
 	SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`

As per coding guidelines, **/types*.go: New fields on stable APIs should be introduced behind a feature gate using +openshift:enable:FeatureGate=MyFeatureGate.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// secretsStore is used to configure the Secrets Store CSI driver.
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}
// secretsStore is used to configure the Secrets Store CSI driver.
// +openshift:enable:FeatureGate=SecretsStoreCSIDriver
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@operator/v1/types_csi_cluster_driver.go` around lines 162 - 165, The new
stable API field SecretsStore (*SecretsStoreCSIDriverConfigSpec) must be gated
with an OpenShift feature gate; add the kubebuilder marker comment
+openshift:enable:FeatureGate=YourFeatureGateName immediately above the
`SecretsStore` field declaration (the SecretsStore
*SecretsStoreCSIDriverConfigSpec line) so the field is only enabled when the
feature gate is on, and update any related docs/tests to use that feature gate
name.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a day2 operator, not an OpenShift core operator. I think we can add this feature to GA directly.
@mytreya-rh what do you think?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chiragkyal I've been assigned for this review, but before starting a proper review I wanted to try and better understand the architecture here.

From doing some digging, it looks like this API is shipped as a CRD in the core OpenShift payload but that there are individual OLM-managed operators that end up reading this API with a name associated with that CSI driver operator. Is this correct?

Is there a central CSI operator that runs as part of core OpenShift that uses this API as well?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct.

The ClusterCSIDriver is shipped with the core OpenShift payload and is not owned by any single operator.

To my understanding cluster-storage-operator (CSO) deploys CSI driver operators (EBS, Azure, GCP, vSphere) and creates their ClusterCSIDriver CR instances.

Via Search for WithKind("ClusterCSIDriver") - it shows the uses across openshift/csi-operator (monorepo for platform + some OLM drivers) and individual operator repos (like secrets-store and gcp-filestorage)

For secrets-store specifically, it's an OLM-managed optional operator (not deployed by CSO). After OLM installs the operator, the admin creates the ClusterCSIDriver named secrets-store.csi.k8s.io.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For posterity, re-posting my comment in slack here:

I had a chat with @JoelSpeed about this yesterday as a sanity check.

We came to the conclusion that we can make this change without a gate and treat it the same way we would have treated a distinct layered-operator-owned API since that is historically how this has been treated.

One thing we would like to see added though is validation constraints that enforce that when the .metadata.name of a ClusterCSIDriver resource is set to a particular CSI driver, that in the spec, only the configuration options associated with that CSI driver can be configured.

As an example, for this particular case, when creating the ClusterCSIDriver for the secrets store csi driver using the name secrets-store.csi.k8s.io, spec.driverConfig.type can only be set to SecretsStore.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've added a CEL validation rule at the ClusterCSIDriver type level:

+kubebuilder:validation:XValidation:rule="self.spec.driverConfig.driverType == 'SecretsStore' ? self.metadata.name == 'secrets-store.csi.k8s.io' : (self.metadata.name != 'secrets-store.csi.k8s.io' || self.spec.driverConfig.driverType == '')",message="metadata.name 'secrets-store.csi.k8s.io' requires driverType 'SecretsStore', and driverType 'SecretsStore' requires metadata.name 'secrets-store.csi.k8s.io'"

Comment thread operator/v1/types_csi_cluster_driver.go Outdated
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from dd82f59 to 87f2c52 Compare May 29, 2026 09:01
@chiragkyal chiragkyal marked this pull request as ready for review May 29, 2026 09:02
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 29, 2026
@openshift-ci openshift-ci Bot requested review from JoelSpeed and everettraven May 29, 2026 09:02
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch 2 times, most recently from eb0e5bd to e08f398 Compare May 29, 2026 11:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml`:
- Around line 310-317: The schema for the CRD field expirationSeconds does not
enforce the documented lower bound of 600; update the OpenAPI schema for the
property named expirationSeconds in the CRD (within the properties block where
type: integer and format: int64 are defined) to include minimum: 600 so
admission validation will reject values below 600; ensure the minimum is set
alongside the existing type/format entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 02b1535f-ee7f-421e-b9f7-a4e43b5dd6c5

📥 Commits

Reviewing files that changed from the base of the PR and between eb0e5bd and e08f398.

⛔ Files ignored due to path filters (11)
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !openapi/**, !**/zz_generated*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/zz_generated.crd-manifests/*
  • operator/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml is excluded by !**/zz_generated.featuregated-crd-manifests/**
  • operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
📒 Files selected for processing (6)
  • operator/v1/types_csi_cluster_driver.go
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml
🚧 Files skipped from review as they are similar to previous changes (5)
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • operator/v1/types_csi_cluster_driver.go
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml

@chiragkyal

Copy link
Copy Markdown
Member Author

/cc @mytreya-rh

@openshift-ci openshift-ci Bot requested a review from mytreya-rh May 29, 2026 11:40
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from e08f398 to 4836779 Compare May 29, 2026 12:42

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
operator/v1/types_csi_cluster_driver.go (1)

116-125: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Gate the new stable SecretsStore API surface.

Lines 116-125 and 162-164 make SecretsStore part of the stable v1 discriminator/union, and the generated manifests in this PR already carry it into the ungated/default CRDs. If this is not intentionally GA-on-arrival, it needs to be feature-gated at the API layer so the stable surface does not expand for every cluster profile yet.

As per coding guidelines, **/types*.go: New fields on stable APIs should be introduced behind a feature gate using +openshift:enable:FeatureGate=MyFeatureGate.

Also applies to: 162-164

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@operator/v1/types_csi_cluster_driver.go` around lines 116 - 125, The
SecretsStore driver constant was added to the stable CSIDriverType union and
must be feature-gated; add the openshift feature-gate annotation to the API so
the new discriminator is not GA-on-arrival: locate the CSIDriverType declaration
and the SecretsStoreDriverType constant (symbols: CSIDriverType and
SecretsStoreDriverType) and add the kubebuilder/openshift annotation
`+openshift:enable:FeatureGate=SecretsStoreCSIDriver` (or your chosen gate name)
immediately above the relevant type/constant declarations (also apply the same
annotation to the other occurrence referenced around lines 162-164) so CRD
generation treats SecretsStore as gated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@operator/v1/types_csi_cluster_driver.go`:
- Around line 454-459: The ExpirationSeconds field on the CSIClusterDriver type
lacks the kubebuilder validation enforcing the documented minimum of 600
seconds; update the field tag for ExpirationSeconds (*int64
`json:"expirationSeconds,omitempty"`) to include
+kubebuilder:validation:Minimum=600 (and keep +optional) so the generated CRD
will reject values <600 and match the documented contract.

In
`@operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml`:
- Around line 289-296: The schema for the expirationSeconds field currently only
declares type/format but does not enforce the documented lower bound; update the
CRD manifest so the expirationSeconds property includes a numeric minimum of 600
(e.g. add "minimum: 600" alongside the existing "type: integer" and "format:
int64") to ensure values less than 600 are rejected by validation; locate the
expirationSeconds definition in the
VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml and add the minimum
constraint for that property.

---

Duplicate comments:
In `@operator/v1/types_csi_cluster_driver.go`:
- Around line 116-125: The SecretsStore driver constant was added to the stable
CSIDriverType union and must be feature-gated; add the openshift feature-gate
annotation to the API so the new discriminator is not GA-on-arrival: locate the
CSIDriverType declaration and the SecretsStoreDriverType constant (symbols:
CSIDriverType and SecretsStoreDriverType) and add the kubebuilder/openshift
annotation `+openshift:enable:FeatureGate=SecretsStoreCSIDriver` (or your chosen
gate name) immediately above the relevant type/constant declarations (also apply
the same annotation to the other occurrence referenced around lines 162-164) so
CRD generation treats SecretsStore as gated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: dc4e1222-9530-4acb-9ae8-509a500a44a1

📥 Commits

Reviewing files that changed from the base of the PR and between e08f398 and 4836779.

⛔ Files ignored due to path filters (3)
  • openapi/generated_openapi/zz_generated.openapi.go is excluded by !**/zz_generated*
  • operator/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated*
  • operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/zz_generated*
📒 Files selected for processing (14)
  • operator/v1/types_csi_cluster_driver.go
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AAA_ungated.yaml
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/AWSEuropeanSovereignCloudInstall.yaml
  • operator/v1/zz_generated.featuregated-crd-manifests/clustercsidrivers.operator.openshift.io/VSphereConfigurableMaxAllowedBlockVolumesPerNode.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml
🚧 Files skipped from review as they are similar to previous changes (4)
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml
  • payload-manifests/crds/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml

Comment thread operator/v1/types_csi_cluster_driver.go Outdated
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from 4836779 to d7c890b Compare June 1, 2026 07:37
@openshift-ci openshift-ci Bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Jun 1, 2026
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from d7c890b to baa69d9 Compare June 2, 2026 08:42
Extends CSIDriverConfigSpec with a new SecretsStore discriminated union
variant containing secretRotation and tokenRequests fields.

Signed-off-by: chiragkyal <[email protected]>
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from baa69d9 to 7a40d90 Compare June 2, 2026 10:42
@chiragkyal chiragkyal changed the title Add Secrets Store CSI driver configuration to ClusterCSIDriver API SSCSI-245: Add Secrets Store CSI driver configuration to ClusterCSIDriver API Jun 2, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 2, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 2, 2026

Copy link
Copy Markdown

@chiragkyal: This pull request references SSCSI-245 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Adds SecretsStore as a new CSIDriverType enum value in the
    ClusterCSIDriver API (operator.openshift.io/v1)

  • Introduces SecretsStoreCSIDriverConfigSpec with configuration for:

  • Secret rotation: toggle automatic rotation on/off and configure
    the poll interval (defaults to enabled with 2m interval)

  • Token requests: configure service account token audiences for
    workload identity federation (WIF)

  • Implements: SSCSI-254: Configurable secret rotation and WIF support for SSCSI enhancements#2012

Summary by CodeRabbit

  • New Features
  • Added support for the SecretsStore CSI driver type.
  • Introduced secret rotation configuration with policy and polling interval settings.
  • Added token request configuration for workload identity federation with audience and expiration settings.
  • Implemented validation rules to ensure secrets store configuration is only present when using the SecretsStore driver type.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Signed-off-by: chiragkyal <[email protected]>
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from 7a40d90 to 660698a Compare June 4, 2026 09:55

// secretsStore is used to configure the Secrets Store CSI driver.
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, because the configuration for this can never be secretsStore: {} based on the validations this does not need to be a pointer.

Instead this can be:

Suggested change
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
SecretsStore SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitzero"`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the latest changes, I think secretsStore can be empty, so having an easier differenciator between empty and unset, I think pointer makes more sense.

Moreover, for consistency with the other driver config fields in CSIDriverConfigSpec, which are all pointers.

Comment on lines +162 to 165
// secretsStore is used to configure the Secrets Store CSI driver.
// +optional
SecretsStore *SecretsStoreCSIDriverConfigSpec `json:"secretsStore,omitempty"`
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For posterity, re-posting my comment in slack here:

I had a chat with @JoelSpeed about this yesterday as a sanity check.

We came to the conclusion that we can make this change without a gate and treat it the same way we would have treated a distinct layered-operator-owned API since that is historically how this has been treated.

One thing we would like to see added though is validation constraints that enforce that when the .metadata.name of a ClusterCSIDriver resource is set to a particular CSI driver, that in the spec, only the configuration options associated with that CSI driver can be configured.

As an example, for this particular case, when creating the ClusterCSIDriver for the secrets store csi driver using the name secrets-store.csi.k8s.io, spec.driverConfig.type can only be set to SecretsStore.

// SecretsStoreSecretRotation configures the automatic secret rotation behavior
// for the Secrets Store CSI driver.
// +kubebuilder:validation:MinProperties=1
type SecretsStoreSecretRotation struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good opportunity to utilize the discriminated union pattern for configuration.

Additionally, we strongly discourage the use of Enabled and Disabled as enum values because they are not very descriptive.

I'd recommend a structure here like:

secretRotation:
  policy: None | Custom
  # custom can only be set when policy == Custom
  custom:
    pollIntervalSeconds: ...

For disabling secret rotation the configuration would look like:

secretRotation:
  policy: None

For configuring it to be different than the default it would look like:

secretRotation:
  policy: Custom
  custom:
    pollIntervalSeconds: 360

omission of the secretRotation field altogether represents that the end-user wants to use the platform default behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Restructured secretRotation as a discriminated union:

// +union
type SecretsStoreSecretRotation struct {
    // +unionDiscriminator
    // +required
    Type SecretRotationType `json:"type"` // None | Custom
    // +optional
    Custom *CustomSecretRotation `json:"custom,omitempty"`
}
  • type: None, disables rotation
  • type: Custom + custom: { rotationPollIntervalSeconds } - enables with config
  • Omission of secretRotation means platform default operation i.e enabled with a 2m interval
  • CEL rule enforces that custom is required when type is Custom and forbidden otherwise.

// Default is 120 (2 minutes).
// +default=120
// +optional
RotationPollIntervalSeconds *int32 `json:"rotationPollIntervalSeconds,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there reasonable lower and upper bounds we can enforce here?

For example, how realistic is it to set this to something like 1 second? What about 2147483647 seconds (~68 years)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The upstream Secrets Store CSI driver does not enforce any lower or upper bound on the rotation poll interval. It accepts any positive duration value. Can't we stay aligned with upstream rather than introduce arbitrary restrictions?

  • It requires rigorous testing to validate the chosen bounds are safe for all scenarios

The +default=120 ensures a sane default when the field is omitted. If a need for bounds is identified later, can it not be added in a follow-up?

// SecretsStoreTokenRequests configures how service account tokens are
// provided to the Secrets Store CSI driver for workload identity federation.
// +kubebuilder:validation:MinProperties=1
type SecretsStoreTokenRequests struct {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it should also be a discriminated union.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Restructured tokenRequests as a discriminated union:

// +union
type SecretsStoreTokenRequests struct {
    // +unionDiscriminator
    // +required
    Type TokenRequestsType `json:"type"` // Managed | Unmanaged
    // +optional
    Managed *ManagedTokenRequests `json:"managed,omitempty"`
}
  • type: Unmanaged - operator preserves existing CSIDriver tokenRequests
  • type: Managed + managed: { audiences[] } - operator owns tokenRequests
  • Omission of tokenRequests entirely means "no opinion" (platform default: Unmanaged/preserve existing)
  • Immutability: once type is set to Managed, it cannot be reverted
  • It also enforces managed is required when type is Managed and forbidden otherwise.

Comment thread operator/v1/types_csi_cluster_driver.go Outdated
// When "Managed", the operator sets tokenRequests from the audiences
// list, replacing any previously configured values.
// Once set to "Managed", policy cannot be reverted back to "Unmanaged".
// +default="Unmanaged"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration APIs, we try to avoid defaulting in this way because it contractually locks us into that default forever.

Instead, for configuration APIs we prefer that omission of the parent field represents that the end-user has "no opinion" and that the platform is left to choose the default value which may be subject to change over time.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed. The secretRotation and tokenRequests fields are now updated.

Comment thread operator/v1/types_csi_cluster_driver.go Outdated
Comment thread operator/v1/types_csi_cluster_driver.go Outdated
Comment on lines +497 to +502
// expirationSeconds is the requested duration of validity of the service account token.
// The token issuer may return a token with a different validity duration.
// When omitted, the token expiration is determined by the kube-apiserver.
// Must be at least 600 seconds (10 minutes).
// +optional
ExpirationSeconds *int64 `json:"expirationSeconds,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean to configure multiple audiences each with a different expiration seconds setting?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each audience in tokenRequests represents a separate service account token. Different cloud providers may require different token lifetime requirements.
Also this is same as the upstream storage.k8s.io/v1 CSIDriver.spec.tokenRequests field structure

A multi-cloud WIF scenario would configure multiple audiences:

tokenRequests:
  type: Managed
  managed:
    audiences:
      - audience: "sts.amazonaws.com"
        expirationSeconds: 3600
      - audience: "api://AzureADTokenExchange"
        expirationSeconds: 600

Signed-off-by: chiragkyal <[email protected]>
@chiragkyal chiragkyal force-pushed the configure-secret-rotation-and-wif branch from 117191b to c0734eb Compare June 8, 2026 20:23
@openshift-ci

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@chiragkyal: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/lint c0734eb link true /test lint

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants