Dynamic Provisioning Credentials Management
This document details how credentials flow through the Scality CSI Driver for S3 for dynamic provisioning, supporting driver-level (global), storage-class-level (per-StorageClass), and template-based (per-PVC) authentication methods.
graph TB
subgraph credentials["Credential Sources"]
subgraph driver["Driver-Level (Default)"]
HelmChart["Helm Chart values.yaml"]
end
subgraph storageclass["StorageClass-Level"]
SCProvSecret["Provisioner Secret csi.storage.k8s.io/provisioner-secret-*"]
SCNodeSecret["Node-Publish Secret csi.storage.k8s.io/node-publish-secret-*"]
end
end
subgraph operations["CSI Operations"]
Controller["CSI Controller CreateVolume"]
Node["CSI Node NodePublishVolume"]
end
S3Bucket["S3 Bucket (Creation/Deletion)"]
MP["mount-s3 Process"]
S3Storage["RING S3 Storage"]
%% Credential flow to operations
HelmChart -.->|"Fallback"| Controller
HelmChart -.->|"Fallback"| Node
SCProvSecret -->|"Primary"| Controller
SCNodeSecret -->|"Primary"| Node
%% Operation flow
Controller --> S3Bucket
Node --> MP
MP -->|"S3 Endpoint URL"| S3Storage
S3Bucket -.->|"S3 Endpoint URL"| S3Storage
There are 3 ways to manage credentials:
- Driver-Level Authentication - Global kubernetes secret containing credentials configured during driver installation
- StorageClass Fixed Authentication - Fixed kubernetes secret names containing credentials specified in StorageClass parameters
- StorageClass Template Authentication - Dynamic kubernetes secret names containing credentials using templating in StorageClass parameters
For Kubernetes secrets used in driver-level, StorageClass-level, and template-based authentication, the credentials should be stored using the same key names as specified in the values.yaml file. Default key names are:
access_key_id
for Access Key IDsecret_access_key
for Secret Access Keysession_token
(optional) for Session Token
Note
Use stringData
(not data
) because the Scality CSI driver for S3 expects plain text credential. Secret security is controlled by Kubernetes RBAC permissions.
Kubernetes Secret with RING S3 credentials | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
Method 1: Driver-Level Authentication
Global secret configured during driver installation. All dynamically provisioned volumes use this secret unless overridden by StorageClass parameters.
Step 1: Install with Helm (referencing secret) | |
---|---|
1 2 3 |
|
Step 2: Create StorageClass (no credentials needed) | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
Step 3: Create PVC (bucket will be created automatically) | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Method 2: StorageClass Fixed Authentication
Each StorageClass can specify fixed secret names for bucket creation and mounting operations. This allows different StorageClasses to use different S3 accounts or permission sets.
Understanding Provisioner vs Node-Publish Secrets
For dynamic provisioning, credentials are used at two different stages:
- Provisioner Secrets (
csi.storage.k8s.io/provisioner-secret-*
) - Used by CSI Controller during bucket creation (CreateVolume RPC). Requires administrative permissions to create/delete S3 buckets. - Node-Publish Secrets (
csi.storage.k8s.io/node-publish-secret-*
) - Used by CSI Node during volume mounting (NodePublishVolume RPC). Requires read/write access to bucket contents.
Security Best Practice
Use different credentials for provisioner (admin) and node-publish (user) operations to implement principle of least privilege.
Example 1: Same Credentials for Both Operations
StorageClass with fixed secret names for both provisioner and node-publish | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Example 2: Separate Admin and User Credentials
StorageClass with separate admin (provisioner) and user (node-publish) secret names | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Admin secret (for bucket operations) | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
User secret (for mounting S3 bucket) | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
Method 3: StorageClass Template Authentication
Template-based authentication allows dynamic secret selection per PVC using template variables. The external-provisioner resolves these templates before calling the CSI driver.
Template Resolution Timing
Templates are resolved by Kubernetes external-provisioner, not by the CSI driver. Secrets must exist when templates are evaluated during provisioning.
The only exception is ${pv.name}
template, as for dynamic provisioning, the PV name is supplied by the CSI driver. In such case, the secret must be created after the PV is created.
Supported Template Variables
Template Variable | What It Becomes | Supported In | Example Usage |
---|---|---|---|
${pv.name} |
pvc-a1b2c3d4-e5f6-7890 if PVC UID is a1b2c3d4-e5f6-7890 |
All parameters | "${pv.name}-secret" |
${pvc.name} |
my-app-data if PVC name is my-app-data |
All parameters | "${pvc.name}-credentials" |
${pvc.namespace} |
production if PVC is in production namespace |
All parameters | "${pvc.namespace}" |
${pvc.annotations['key']} |
team-alpha if PVC has annotation key: team-alpha |
node-publish-secret-name ONLY | "${pvc.annotations['team.io/name']}" |
StorageClass Parameters
Parameter | Purpose | Template Variables Supported |
---|---|---|
csi.storage.k8s.io/provisioner-secret-name |
Secret name for bucket creation | ${pv.name} , ${pvc.name} , ${pvc.namespace} |
csi.storage.k8s.io/provisioner-secret-namespace |
Secret namespace for bucket creation | ${pv.name} , ${pvc.namespace} |
csi.storage.k8s.io/node-publish-secret-name |
Secret name for mounting S3 bucket | ${pv.name} , ${pvc.name} , ${pvc.namespace} , ${pvc.annotations['key']} |
csi.storage.k8s.io/node-publish-secret-namespace |
Secret namespace for mounting S3 bucket | ${pv.name} , ${pvc.namespace} |
Key Limitations & Best Practices per CSI specification
- Annotations (
${pvc.annotations['key']}
) are ONLY supported fornode-publish-secret-name
, NOT for provisioner secrets - PV names follow predictable pattern:
pvc-<PVC-UID>
- Templates can be mixed with static text (e.g.,
${pvc.name}-admin
) - For
${pv.name}
templates: Consider usingvolumeBindingMode: WaitForFirstConsumer
to allow time for secret creation after PVC UID is known
Example 1: Per-PVC Credentials using PVC Name
StorageClass using PVC name for credential selection | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Create secret matching PVC name | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Example 2: Team-Based Credentials using Annotations
Annotation Limitation
Annotations (${pvc.annotations['key']}
) are ONLY supported in node-publish-secret-name
. For provisioner secrets, use fixed names or other template variables.
StorageClass using PVC annotations for node-publish secrets only | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Team secrets in dedicated namespace | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
Example 3: Using ${pv.name} Template with WaitForFirstConsumer
StorageClass using PV name (requires WaitForFirstConsumer) | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
|