Skip to content

Commit 154b004

Browse files
committed
fix: add mountWithWorkloadIdentityToken param
1 parent 6e91932 commit 154b004

File tree

6 files changed

+49
-14
lines changed

6 files changed

+49
-14
lines changed

docs/workload-identity-static-pv-mount.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
### Note
55
- This feature is not supported for NFS mount since NFS mount does not need credentials.
6-
- This feature no longer retrieves storage account key using federated(workload) identity credentials starting from v1.25.4 or v1.26.1 and later versions, while it requires `Storage Blob Data Contributor` role on the account instead of `Storage Account Contributor` role.
6+
- This feature would retrieve storage account key using federated identity credentials.
77

88
## Prerequisites
99
### 1. Create a cluster with oidc-issuer enabled and get the credential
@@ -33,7 +33,7 @@ export IDENTITY_TENANT=$(az aks show --name $CLUSTER_NAME --resource-group $RESO
3333
export ACCOUNT_SCOPE=$(az storage account show --name $ACCOUNT --query id -o tsv)
3434
3535
# please retry if you meet `Cannot find user or service principal in graph database` error, it may take a while for the identity to propagate
36-
az role assignment create --role "Storage Blob Data Contributor" --assignee $USER_ASSIGNED_CLIENT_ID --scope $ACCOUNT_SCOPE
36+
az role assignment create --role "Storage Account Contributor" --assignee $USER_ASSIGNED_CLIENT_ID --scope $ACCOUNT_SCOPE
3737
```
3838

3939
### 4. Create service account on AKS

pkg/blob/blob.go

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const (
100100
podNamespaceField = "csi.storage.k8s.io/pod.namespace"
101101
serviceAccountTokenField = "csi.storage.k8s.io/serviceAccount.tokens"
102102
clientIDField = "clientid"
103+
mountWithWITokenField = "mountwithworkloadidentitytoken"
103104
tenantIDField = "tenantid"
104105
mountOptionsField = "mountoptions"
105106
falseValue = "false"
@@ -490,6 +491,7 @@ func (d *Driver) GetAuthEnv(ctx context.Context, volumeID, protocol string, attr
490491
getAccountKeyFromSecret bool
491492
getLatestAccountKey bool
492493
clientID string
494+
mountWithWIToken bool
493495
tenantID string
494496
serviceAccountToken string
495497
)
@@ -543,6 +545,10 @@ func (d *Driver) GetAuthEnv(ctx context.Context, volumeID, protocol string, attr
543545
}
544546
case clientIDField:
545547
clientID = v
548+
case mountWithWITokenField:
549+
if mountWithWIToken, err = strconv.ParseBool(v); err != nil {
550+
return rgName, accountName, accountKey, containerName, authEnv, fmt.Errorf("invalid %s: %s in volume context", mountWithWITokenField, v)
551+
}
546552
case tenantIDField:
547553
tenantID = v
548554
case strings.ToLower(serviceAccountTokenField):
@@ -574,20 +580,30 @@ func (d *Driver) GetAuthEnv(ctx context.Context, volumeID, protocol string, attr
574580

575581
// if client id is specified, we only use workload identity for blobfuse auth
576582
if clientID != "" {
577-
klog.V(2).Infof("clientID(%s) is specified, use workload identity for blobfuse auth", clientID)
583+
if mountWithWIToken {
584+
klog.V(2).Infof("clientID(%s) is specified, use workload identity for blobfuse auth", clientID)
578585

579-
workloadIdentityToken, err := parseServiceAccountToken(serviceAccountToken)
580-
if err != nil {
581-
return rgName, accountName, accountKey, containerName, authEnv, err
582-
}
586+
workloadIdentityToken, err := parseServiceAccountToken(serviceAccountToken)
587+
if err != nil {
588+
return rgName, accountName, accountKey, containerName, authEnv, err
589+
}
583590

584-
authEnv = append(authEnv, "AZURE_STORAGE_SPN_CLIENT_ID="+clientID)
585-
if tenantID != "" {
586-
authEnv = append(authEnv, "AZURE_STORAGE_SPN_TENANT_ID="+tenantID)
587-
}
588-
authEnv = append(authEnv, "WORKLOAD_IDENTITY_TOKEN="+workloadIdentityToken)
591+
authEnv = append(authEnv, "AZURE_STORAGE_SPN_CLIENT_ID="+clientID)
592+
if tenantID != "" {
593+
authEnv = append(authEnv, "AZURE_STORAGE_SPN_TENANT_ID="+tenantID)
594+
}
595+
authEnv = append(authEnv, "WORKLOAD_IDENTITY_TOKEN="+workloadIdentityToken)
589596

590-
return rgName, accountName, accountKey, containerName, authEnv, err
597+
return rgName, accountName, accountKey, containerName, authEnv, err
598+
} else {
599+
klog.V(2).Infof("clientID(%s) is specified, use service account token to get account key", clientID)
600+
if subsID == "" {
601+
subsID = d.cloud.SubscriptionID
602+
}
603+
accountKey, err := d.cloud.GetStorageAccesskeyFromServiceAccountToken(ctx, subsID, accountName, rgName, clientID, tenantID, serviceAccountToken)
604+
authEnv = append(authEnv, "AZURE_STORAGE_ACCESS_KEY="+accountKey)
605+
return rgName, accountName, accountKey, containerName, authEnv, err
606+
}
591607
}
592608

593609
// 1. If keyVaultURL is not nil, preferentially use the key stored in key vault.

pkg/blob/blob_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,23 @@ func TestGetAuthEnv(t *testing.T) {
550550
name: "valid request",
551551
testFunc: func(t *testing.T) {
552552
d := NewFakeDriver()
553-
attrib := make(map[string]string)
553+
attrib := map[string]string{
554+
subscriptionIDField: "subID",
555+
resourceGroupField: "rg",
556+
storageAccountField: "accountname",
557+
storageAccountNameField: "accountname",
558+
secretNameField: "secretName",
559+
secretNamespaceField: "sNS",
560+
containerNameField: "containername",
561+
mountWithWITokenField: "false",
562+
pvcNamespaceKey: "pvcNSKey",
563+
getAccountKeyFromSecretField: "false",
564+
storageAuthTypeField: "key",
565+
msiEndpointField: "msiEndpoint",
566+
getLatestAccountKeyField: "true",
567+
tenantIDField: "tenantID",
568+
serviceAccountTokenField: "serviceAccountToken",
569+
}
554570
secret := make(map[string]string)
555571
volumeID := "rg#f5713de20cde511e8ba4900#pvc-fuse-dynamic-17e43f84-f474-11e8-acd0-000d3a00df41"
556572
d.cloud = &storage.AccountRepo{}

pkg/blob/controllerserver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ func (d *Driver) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest)
189189
case storageIdentityObjectIDField:
190190
case storageIdentityResourceIDField:
191191
case clientIDField:
192+
case mountWithWITokenField:
192193
case tenantIDField:
193194
case msiEndpointField:
194195
case storageAADEndpointField:

pkg/blob/controllerserver_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ func TestCreateVolume(t *testing.T) {
440440
mp[storageAuthTypeField] = "msi"
441441
mp[storageIdentityClientIDField] = "msi"
442442
mp[clientIDField] = "clientID"
443+
mp[mountWithWITokenField] = "true"
443444
mp[tenantIDField] = "tenantID"
444445
mp[storageIdentityObjectIDField] = "msi"
445446
mp[storageIdentityResourceIDField] = "msi"

pkg/blob/nodeserver_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ func TestNodePublishVolume(t *testing.T) {
249249
StagingTargetPath: sourceTest,
250250
VolumeContext: map[string]string{
251251
serviceAccountTokenField: `{"api://AzureADTokenExchange":{"token":"test-token","expirationTimestamp":"2023-01-01T00:00:00Z"}}`,
252+
mountWithWITokenField: "true",
252253
clientIDField: "client-id-value",
253254
},
254255
},

0 commit comments

Comments
 (0)