---
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:

| 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
```