feat(helm): support extra volumes/mounts; add external API key mount-path validation#772
feat(helm): support extra volumes/mounts; add external API key mount-path validation#772JoeDerby wants to merge 16 commits into
Conversation
Commented out the validation rules for apiKey and existingSecretName in the schema.
Removed anyOf and oneOf constraints for apiKey and existingSecretName.
|
Hey @JoeDerby, thanks for putting this together — we really appreciate the contribution, and especially that you put put real thought into the validation and test coverage! Supporting external credential flows is something we want to Design considerationsThe core issue is that the PR introduces a very generic mechanism ( The other thing I want to be careful about is that Can
|
|
Thanks for the feedback @evan-cz . We're using AWS Secrets Manager with Secrets Store CSI Driver. existingSecretName can work for us, and we don't have a policy constraint that prohibits Kubernetes Secret objects. The reason we want to take the direct CSI-mounted file path was that secretObjects sync still requires a pod mounting the CSI volume before the Kubernetes Secret exists. As the Secrets Store CSI docs note, "The secrets will only sync once you start a pod mounting the secrets" (https://secrets-store-csi-driver.sigs.k8s.io/topics/sync-as-kubernetes-secret.html). The synced secret lifecycle is also coupled to consuming pods. In our case, existingSecretName would still require another pod/process to materialize and maintain that Secret when using CSI secretObjects sync, which is what we were trying to avoid. Given that a pod volume mount is still required to trigger secretObjects sync, the direct CSI-mount approach felt cleaner. I also agree that the current generic extraVolumes and extraVolumeMounts wiring is too broad. We can split this so API-key-related mounts are scoped only to components that require them, rather than using a global mount mechanism. |
|
Hey Joe. I opened up #819 for this (due to some permissions stuff in the GitHub Actions workflows, some of the required checks don't run for external contributions, so we need to make a second issue). I rebased your branch on the latest develop then squashed everything into a single commit and built off that. What do you think of this approach? You should be able to just set apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: cloudzero-api-key-csi
namespace: cza
spec:
provider: aws
parameters:
objects: |
- objectName: "dev/cloudzero-secret-api-key-foo"
objectType: "secretsmanager"
jmesPath:
- path: apiToken
objectAlias: valueThen you can set Would that solve your problem? |
|
Hi @evan-cz, I have just tested your new PR out this morning. This would solve the problem for us thanks. |
Community PR #772 added generic extraVolumes/extraVolumeMounts to support CSI-driven API key delivery from external vaults. The approach was too broad — it coupled generic volume mounting to credential validation and exposed the API key volume to every workload regardless of need. This replaces that with a single components.apiKey.secretProviderClass property that switches the API key volume source from a Kubernetes Secret to a Secrets Store CSI Driver volume. Functional Requirements: 1. Users must be able to mount the API key via the Secrets Store CSI Driver without creating a Kubernetes Secret object. Added components.apiKey.secretProviderClass. When set (and both top-level apiKey and existingSecretName are null), the chart generates a CSI volume using the secrets-store.csi.k8s.io driver instead of a Kubernetes Secret volume. The mount path (serverConfig.containerSecretFilePath) is unchanged. 2. Existing apiKey and existingSecretName must continue to work and take priority. The top-level properties are not deprecated or relocated. A new cloudzero-agent.apiKey.mode helper resolves the active provisioning mode (inline, secret, csi, or none) and is used by the volume mount, volume definition, and volumes-section guards. 3. The volume definition must not be duplicated across templates. Added a cloudzero-agent.apiKeyVolume helper that generates the correct volume definition (Secret or CSI) based on the resolved mode. This replaced six identical inline volume blocks across agent-deploy, agent-daemonset, aggregator-deploy, webhook-deploy, backfill-job, and config-loader-job templates. 4. The generic extraVolumes/extraVolumeMounts mechanism must be removed. Removed the extraVolumes and extraVolumeMounts values, schema properties, template helpers, and all wiring across the six workload templates. Removed the validateExternalApiKeyMountPath render-time guard since CSI mode no longer depends on extra volume mounts. Validation: - All 565 Helm unit tests pass (schema, template rendering, CSI volume rendering, precedence, and backwards compatibility) - Added helm/tests/apikey_csi_volume_test.yaml covering CSI volume rendering across all workload templates - Updated helm/tests/apikey_secret_validation_test.yaml with secretProviderClass schema validation and precedence tests - Removed helm/tests/api_key_mount_path_validation_test.yaml and helm/tests/extra_volumes_test.yaml (no longer applicable) - Deployed and validated end-to-end on EKS (AWS Secrets Manager) and AKS (Azure Key Vault) using the Secrets Store CSI Driver
Community PR #772 added generic extraVolumes/extraVolumeMounts to support CSI-driven API key delivery from external vaults. The approach was too broad — it coupled generic volume mounting to credential validation and exposed the API key volume to every workload regardless of need. This replaces that with a single components.apiKey.secretProviderClass property that switches the API key volume source from a Kubernetes Secret to a Secrets Store CSI Driver volume. Functional Requirements: 1. Users must be able to mount the API key via the Secrets Store CSI Driver without creating a Kubernetes Secret object. Added components.apiKey.secretProviderClass. When set (and both top-level apiKey and existingSecretName are null), the chart generates a CSI volume using the secrets-store.csi.k8s.io driver instead of a Kubernetes Secret volume. The mount path (serverConfig.containerSecretFilePath) is unchanged. 2. Existing apiKey and existingSecretName must continue to work and take priority. The top-level properties are not deprecated or relocated. A new cloudzero-agent.apiKey.mode helper resolves the active provisioning mode (inline, secret, csi, or none) and is used by the volume mount, volume definition, and volumes-section guards. 3. The volume definition must not be duplicated across templates. Added a cloudzero-agent.apiKeyVolume helper that generates the correct volume definition (Secret or CSI) based on the resolved mode. This replaced six identical inline volume blocks across agent-deploy, agent-daemonset, aggregator-deploy, webhook-deploy, backfill-job, and config-loader-job templates. 4. The generic extraVolumes/extraVolumeMounts mechanism must be removed. Removed the extraVolumes and extraVolumeMounts values, schema properties, template helpers, and all wiring across the six workload templates. Removed the validateExternalApiKeyMountPath render-time guard since CSI mode no longer depends on extra volume mounts. Validation: - All 565 Helm unit tests pass (schema, template rendering, CSI volume rendering, precedence, and backwards compatibility) - Added helm/tests/apikey_csi_volume_test.yaml covering CSI volume rendering across all workload templates - Updated helm/tests/apikey_secret_validation_test.yaml with secretProviderClass schema validation and precedence tests - Removed helm/tests/api_key_mount_path_validation_test.yaml and helm/tests/extra_volumes_test.yaml (no longer applicable) - Deployed and validated end-to-end on EKS (AWS Secrets Manager) and AKS (Azure Key Vault) using the Secrets Store CSI Driver
Community PR #772 added generic extraVolumes/extraVolumeMounts to support CSI-driven API key delivery from external vaults. The approach was too broad — it coupled generic volume mounting to credential validation and exposed the API key volume to every workload regardless of need. This replaces that with a single components.apiKey.secretProviderClass property that switches the API key volume source from a Kubernetes Secret to a Secrets Store CSI Driver volume. Functional Requirements: 1. Users must be able to mount the API key via the Secrets Store CSI Driver without creating a Kubernetes Secret object. Added components.apiKey.secretProviderClass. When set (and both top-level apiKey and existingSecretName are null), the chart generates a CSI volume using the secrets-store.csi.k8s.io driver instead of a Kubernetes Secret volume. The mount path (serverConfig.containerSecretFilePath) is unchanged. 2. Existing apiKey and existingSecretName must continue to work and take priority. The top-level properties are not deprecated or relocated. A new cloudzero-agent.apiKey.mode helper resolves the active provisioning mode (inline, secret, csi, or none) and is used by the volume mount, volume definition, and volumes-section guards. 3. The volume definition must not be duplicated across templates. Added a cloudzero-agent.apiKeyVolume helper that generates the correct volume definition (Secret or CSI) based on the resolved mode. This replaced six identical inline volume blocks across agent-deploy, agent-daemonset, aggregator-deploy, webhook-deploy, backfill-job, and config-loader-job templates. 4. The generic extraVolumes/extraVolumeMounts mechanism must be removed. Removed the extraVolumes and extraVolumeMounts values, schema properties, template helpers, and all wiring across the six workload templates. Removed the validateExternalApiKeyMountPath render-time guard since CSI mode no longer depends on extra volume mounts. Validation: - All 565 Helm unit tests pass (schema, template rendering, CSI volume rendering, precedence, and backwards compatibility) - Added helm/tests/apikey_csi_volume_test.yaml covering CSI volume rendering across all workload templates - Updated helm/tests/apikey_secret_validation_test.yaml with secretProviderClass schema validation and precedence tests - Removed helm/tests/api_key_mount_path_validation_test.yaml and helm/tests/extra_volumes_test.yaml (no longer applicable) - Deployed and validated end-to-end on EKS (AWS Secrets Manager) and AKS (Azure Key Vault) using the Secrets Store CSI Driver
Why?
This PR adds first-class support for attaching custom extraVolumes and extraVolumeMounts to CloudZero workloads, while preserving safe API key configuration validation.
It enables external file-based credential flows (for example CSI-driven mounts) without introducing a new feature toggle, and keeps default chart behaviour intact for existing users.
What
Added new chart values:
Wired those values into all relevant workloads:
agent-deploy
agent-daemonset
aggregator-deploy
config-loader-job
webhook-deploy
backfill-job
Added reusable Helm helpers for extra volumes/mounts rendering.
Updated docs in helm/README.md and value schema definitions.
Strengthened schema validation:
Added render-time validation guard:
Added/updated Helm unit tests for:
Users need to mount additional volumes (including but not limited to CSI-backed sources) across CloudZero components without changing default secret behaviour.
At the same time, we need to avoid silent credential misconfigurations. This PR balances flexibility with clear guardrails.
Backward Compatibility
How Tested
All Helm unit tests suite passed.
Deployed from Fork to test agent is working.
Scenarios explicitly verified: