Repository navigation
feat(secret-manager): add csi provider on K8s #6858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
6889e25
feat(secret-manager): add csi provider on K8s
vanda-scw 56c9956
feat(secret-manager): editorial improvements
vanda-scw 29ea7ab
feat(secret-manager): editorial improvements
vanda-scw 3aea2f8
Apply suggestion from @ojroques
vanda-scw 3e05959
Apply suggestion from @ojroques
vanda-scw 06c0ede
Apply suggestion from @ojroques
vanda-scw d1aae90
Apply suggestion from @Loic-kd
vanda-scw 49c19e0
Apply suggestion from @mmfrayssens
vanda-scw fed0a45
Apply suggestion from @Loic-kd
vanda-scw 05b51db
feat(secret-manager): apply peer review comments
vanda-scw fc00ecb
Update pages/secret-manager/api-cli/deploying-secret-manager-csi-prov…
vanda-scw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
273 changes: 273 additions & 0 deletions
273
pages/secret-manager/api-cli/deploying-secret-manager-csi-provider-kubernetes.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,273 @@ | ||
| --- | ||
| title: Deploying the Scaleway Secret Manager CSI provider on Kubernetes | ||
| description: Learn how to install the Scaleway Secret Manager provider for Secrets Store CSI Driver on Kubernetes and mount secrets as volumes in your pods. | ||
| tags: secret-manager kubernetes csi secrets helm | ||
| dates: | ||
| validation: 2026-09-04 | ||
| posted: 2026-09-07 | ||
| categories: | ||
| - secret-manager | ||
| --- | ||
| import Requirements from '@macros/iam/requirements.mdx' | ||
|
|
||
| [Scaleway Secret Manager](/secret-manager/) is the managed service that lets you store and manage your secrets (API keys, passwords, certificates, etc.) in a secure and centralized way. | ||
|
|
||
| The [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/) is a [Kubernetes CSI](https://kubernetes-csi.github.io/docs/) driver that enables you to mount secrets from external secret stores as volumes in your Kubernetes pods. | ||
|
|
||
| The **Scaleway Secret Manager provider for Secrets Store CSI Driver** (also called "the Secret Manager provider" or "the provider" on this page) connects these two together: it allows you to get secrets stored in Scaleway Secret Manager and use the Secrets Store CSI Driver interface to mount them directly into your Kubernetes pods as files. | ||
|
|
||
| Unlike [External Secrets](https://external-secrets.io), which generates external secrets as Kubernetes `Secret` objects managed by an operator, the Secret Manager provider mounts the secret contents into pods without creating intermediary Kubernetes secrets. | ||
|
|
||
| In this tutorial, you will learn how to install the Secret Manager provider on your Kubernetes cluster, define which secrets to mount, and access them from your application pods. | ||
|
|
||
| <Requirements /> | ||
|
|
||
| - A Scaleway account logged into the [console](https://console.scaleway.com) | ||
| - [Owner](/iam/concepts/#owner) status or [IAM permissions](/iam/concepts/#permission) allowing you to perform actions in the intended Organization | ||
| - A Kubernetes cluster, for example a [Kubernetes Kapsule](/kubernetes/concepts/#kubernetes-kapsule) cluster, with `kubectl` configured to access it | ||
| - Installed [helm](https://helm.sh/), the Kubernetes package manager, on your local machine (version 3 or later) | ||
| - Created at least one secret in [Scaleway Secret Manager](/secret-manager/quickstart/) | ||
|
|
||
| If you plan to use a dedicated application or service account with a custom [IAM policy](/iam/how-to/create-policy/), the minimum set of permissions required is: | ||
|
|
||
| - `SecretManagerReadOnly` | ||
| - `SecretManagerSecretAccess` | ||
|
|
||
| ## Install the Secrets Store CSI Driver | ||
|
|
||
| The Scaleway Secret Manager provider is an add-on to the Secrets Store CSI Driver, so the driver must be installed in your cluster first. The easiest way to install it is with Helm: | ||
|
|
||
| ```bash | ||
| helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts | ||
| helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system | ||
| ``` | ||
|
|
||
| See the official [Secrets Store CSI Driver installation documentation](https://secrets-store-csi-driver.sigs.k8s.io/getting-started/installation.html) for alternative installation methods and options. | ||
|
|
||
| ## Install the Secret Manager provider | ||
|
|
||
| ### Install using Helm | ||
|
|
||
| The recommended installation method is via Helm 3: | ||
|
|
||
| ```bash | ||
| helm repo add scaleway https://helm.scw.cloud/ | ||
| helm repo update | ||
| helm upgrade --install scaleway-secrets-store-csi --namespace kube-system scaleway/scaleway-secrets-store-csi | ||
| ``` | ||
|
|
||
| The full set of configurable values is available in the [Helm chart `values.yaml` of the Scaleway Secrets Store CSI](https://github.com/scaleway/helm-charts/blob/master/charts/scaleway-secrets-store-csi/values.yaml). | ||
|
|
||
| ### Install using kubectl | ||
|
|
||
| You can also install the provider using the deployment configuration provided in the [`deployment` folder](https://github.com/scaleway/scaleway-secrets-store-csi/tree/main/deployment) of the [Scaleway Secrets Store CSI repository](https://github.com/scaleway/scaleway-secrets-store-csi): | ||
|
|
||
| ```bash | ||
| kubectl apply -n kube-system -f https://raw.githubusercontent.com/scaleway/scaleway-secrets-store-csi/main/deployment/secrets-store-csi-driver-provider-scw.yaml | ||
| ``` | ||
|
|
||
| This command installs the provider as a `DaemonSet` (so it runs on every node) together with its `ServiceAccount`, `ClusterRole`, and `ClusterRoleBinding`. | ||
|
|
||
| ## Create the Scaleway credentials Secret | ||
|
|
||
| To authenticate to Scaleway, create a Kubernetes Secret containing your Scaleway API credentials (that is, the access key and secret key of your API key). Remember to replace placeholders `my-access-key` and `my-secret-key` with your actual values. | ||
|
|
||
| See [How to create API keys](/iam/how-to/create-api-keys/) in the IAM documentation for details. | ||
|
|
||
| ```yaml | ||
| apiVersion: v1 | ||
| kind: Secret | ||
| metadata: | ||
| name: scaleway-credentials | ||
| namespace: default | ||
| type: Opaque | ||
| stringData: | ||
| accessKey: "my-access-key" | ||
| secretKey: "my-secret-key" | ||
| ``` | ||
|
|
||
| <Message type="note"> | ||
| The provider does not support authentication with a Kubernetes Service Account yet. | ||
| </Message> | ||
|
|
||
| ## Create a `SecretProviderClass` | ||
|
|
||
| A `SecretProviderClass` defines which secrets from Scaleway Secret Manager should be mounted. Create a `SecretProviderClass` in the namespace where your application runs, referencing the credentials Secret created in the previous step. Remember to replace the placeholders with your actual values. | ||
|
|
||
| ```yaml | ||
| apiVersion: secrets-store.csi.x-k8s.io/v1 | ||
| kind: SecretProviderClass | ||
| metadata: | ||
| name: scaleway-provider | ||
| namespace: default | ||
| spec: | ||
| provider: scaleway | ||
| parameters: | ||
| apiURL: "https://api.scaleway.com" | ||
| insecure: "false" | ||
| defaultOrganizationID: "573e26e8-45b7-4859-aa81-547de6e9acff" | ||
| defaultProjectID: "6a4027ce-58c3-4adb-9b69-7ff6e1f317d2" | ||
| defaultRegion: "fr-par" | ||
| objects: | | ||
| - secretID: "e6a5d04a-c2c2-49a3-8180-09452bf64e26" | ||
| revision: "latest_enabled" | ||
| targetPath: "my-secret" | ||
| - projectID: "dfdc0cab-c99b-479d-a8f0-1df78cd9f67e" | ||
| secretPath: "/test" | ||
| secretName: "my-other-secret" | ||
| revision: "latest_enabled" | ||
| ``` | ||
|
|
||
| The `parameters` section supports the following settings. | ||
|
|
||
| | Parameter | Description | Required | Default | | ||
| |-----------|-------------|----------|---------| | ||
| | `apiURL` | The Scaleway API URL | no | `https://api.scaleway.com` | | ||
| | `insecure` | Set to `"true"` to disable TLS verification (for testing against a local API) | no | `"false"` | | ||
| | `defaultOrganizationID` | Default Organization ID used when no Project is specified | yes | none | | ||
| | `defaultProjectID` | Default Project ID containing the secrets | no | `defaultOrganizationID` | | ||
| | `defaultRegion` | The [region](/secret-manager/concepts/#region) of your secrets | yes | none | | ||
| | `objects` | A YAML-formatted list that defines each secret to mount, specified either by its [secret ID](#access-a-secret-by-secret-id) or its [secret path](#access-a-secret-by-secret-path) | yes | none | | ||
|
|
||
| ### Access secrets | ||
|
|
||
| #### Access a secret by secret ID | ||
|
|
||
| To access a secret version by its ID, specify the `secretID` field. Remember to replace the placeholders with your actual values. | ||
|
|
||
| ```yaml | ||
| objects: | | ||
| - secretID: "e6a5d04a-c2c2-49a3-8180-09452bf64e26" | ||
| revision: "latest_enabled" | ||
| targetPath: "my-secret" | ||
| ``` | ||
|
|
||
| Where: | ||
|
vanda-scw marked this conversation as resolved.
Resolved
|
||
|
|
||
| | Parameter | Description | Required | Default | | ||
| |--------------|------------------------|----------|---------| | ||
| | `secretID` | The UUID of the secret | yes | none | | ||
| | `revision` | The revision to access, e.g., `latest_enabled`, `1`, `2`, etc. | no |`latest_enabled` | | ||
| | `targetPath` | The relative path where the secret will be mounted | yes | none | | ||
|
|
||
| #### Access a secret by secret path | ||
|
|
||
| <Message type="note"> | ||
| A secret must be specified either by ID or by path, but not both. If you specify an ID, the path fields are ignored. | ||
| </Message> | ||
|
|
||
| To access a secret version by its path, specify the `secretPath` and `secretName` fields. Remember to replace the placeholders with your actual values. | ||
|
|
||
| ```yaml | ||
| objects: | | ||
| - projectID: "dfdc0cab-c99b-479d-a8f0-1df78cd9f67e" | ||
| secretPath: "/test" | ||
| secretName: "my-other-secret" | ||
| revision: "latest_enabled" | ||
| ``` | ||
|
|
||
| Where: | ||
|
|
||
| | Parameter | Description | Required | Default | | ||
| |--------------|------------------------|----------|---------| | ||
| | `projectID` | The project ID containing the secret | no | `defaultProjectID` or `defaultOrganizationID` | | ||
| | `secretPath` | The absolute path to the secret folder | yes | none | | ||
| | `secretName` | The name of the secret | yes | none | | ||
| | `revision` | The revision to access, e.g., `latest_enabled`, `1`, `2`, etc. | no |`latest_enabled` | | ||
| | `targetPath` | The relative path where the secret will be mounted | no | `secretPath/secretName` | | ||
|
|
||
| ## Mount secrets in a pod | ||
|
|
||
| Now that the `SecretProviderClass` is defined, mount the secrets in your application pod by referencing it through a CSI volume. Create a pod similar to the following: | ||
|
|
||
| ```yaml | ||
| apiVersion: v1 | ||
| kind: Pod | ||
| metadata: | ||
| name: test-secret-pod | ||
| namespace: default | ||
| spec: | ||
| containers: | ||
| - name: busybox | ||
| image: busybox | ||
| command: ["sleep", "infinity"] | ||
| volumeMounts: | ||
| - name: secrets-store | ||
| mountPath: "/mnt/secrets" | ||
| readOnly: true | ||
| volumes: | ||
| - name: secrets-store | ||
| csi: | ||
| driver: secrets-store.csi.k8s.io | ||
| readOnly: true | ||
| volumeAttributes: | ||
| secretProviderClass: scaleway-provider | ||
| nodePublishSecretRef: | ||
| name: scaleway-credentials | ||
| ``` | ||
|
|
||
| The `csi` volume: | ||
| - uses the `secrets-store.csi.k8s.io` driver | ||
| - points to the `SecretProviderClass` via the `secretProviderClass` volume attribute | ||
| - references the credentials Secret created earlier through `nodePublishSecretRef` | ||
|
|
||
| Once the pod is running, the secrets are mounted as files under the `mountPath`. You can verify that the secrets are accessible inside the pod by executing the following: | ||
|
|
||
| ```bash | ||
| kubectl exec test-secret-pod -- ls -l /mnt/secrets | ||
| kubectl exec test-secret-pod -- cat /mnt/secrets/my-secret | ||
| ``` | ||
|
|
||
| <Message type="note"> | ||
| Mounted secrets are written to the filesystem of the node when the pod is scheduled. Changes made to the secret in Secret Manager (for example, a new revision) are not reflected automatically in a running pod. Recreate or restart the pod to pick up the latest revision. | ||
| </Message> | ||
|
|
||
| ## Uninstall the provider | ||
|
|
||
| 1. Delete any resources created by the provider, such as pods referencing the `SecretProviderClass` and the `scaleway-credentials` Secret: | ||
|
|
||
| ```bash | ||
| kubectl delete pod test-secret-pod | ||
| kubectl delete secret scaleway-credentials | ||
| kubectl delete secretproviderclass scaleway-provider | ||
| ``` | ||
|
|
||
| 2. After the resources have been deleted, uninstall the provider. To uninstall with Helm, execute the following command: | ||
|
|
||
| ```bash | ||
| helm delete scaleway-secrets-store-csi --namespace kube-system | ||
| ``` | ||
|
|
||
| 3. You can also remove the Secrets Store CSI Driver itself if you no longer need it: | ||
|
|
||
| ```bash | ||
| helm delete csi-secrets-store --namespace kube-system | ||
| ``` | ||
|
|
||
| ## Troubleshoot issues | ||
|
|
||
| ### Check logs | ||
|
|
||
| The provider runs as a DaemonSet, so there is one provider pod on every node. To troubleshoot issues with a specific application pod, look at the logs of the provider pod running on the same node as your application pod: | ||
|
|
||
| ```bash | ||
| kubectl get pods -n kube-system -o wide | ||
| # Find the Scaleway CSI provider pod running on the same node as your application pod | ||
| kubectl logs -n kube-system scaleway-secrets-store-csi-xxxxx | ||
| ``` | ||
|
|
||
| ### Enable debug mode | ||
|
|
||
| To enable debug mode when installing with Helm, set the `provider.debug` value to `true`: | ||
|
|
||
| ```bash | ||
| helm upgrade --install scaleway-secrets-store-csi --namespace kube-system scaleway/scaleway-secrets-store-csi \ | ||
| --set provider.debug=true | ||
| ``` | ||
|
|
||
| Alternatively, if you use a `values.yaml` file, set `debug` to `true`: | ||
|
|
||
| ```yaml | ||
| provider: | ||
| debug: true | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.