@@ -44,11 +44,13 @@ var (
4444)
4545
4646const (
47- resourceIDField = "resourceId"
48- clientIDField = "clientId"
49- tenantIDField = "tenantId"
50- clientSecretField = "clientSecret"
51- accountKeyField = "accountKey"
47+ resourceIDField = "resourceId"
48+ clientIDField = "clientId"
49+ tenantIDField = "tenantId"
50+ clientSecretField = "clientSecret"
51+ clientCertificateField = "clientCertificate"
52+ clientCertificatePasswordField = "clientCertificatePassword"
53+ accountKeyField = "accountKey"
5254)
5355
5456// BlobClient is a minimal Azure Blob client for fetching objects.
@@ -62,13 +64,17 @@ type BlobClient struct {
6264// order:
6365//
6466// - azidentity.ManagedIdentityCredential for a Resource ID, when a
65- // resourceIDField is found.
66- // - azidentity.ManagedIdentityCredential for a User ID, when a clientIDField
67- // but no tenantIDField found.
68- // - azidentity.ClientSecretCredential when a tenantIDField, clientIDField and
69- // clientSecretField are found.
70- // - azblob.SharedKeyCredential when an accountKeyField is found. The Account
71- // Name is extracted from the endpoint specified on the Bucket object.
67+ // `resourceId` field is found.
68+ // - azidentity.ManagedIdentityCredential for a User ID, when a `clientId`
69+ // field but no `tenantId` is found.
70+ // - azidentity.ClientCertificateCredential when `tenantId`,
71+ // `clientCertificate` (and optionally `clientCertificatePassword`) fields
72+ // are found.
73+ // - azidentity.ClientSecretCredential when `tenantId`, `clientId` and
74+ // `clientSecret` fields are found.
75+ // - azblob.SharedKeyCredential when an `accountKey` field is found.
76+ // The account name is extracted from the endpoint specified on the Bucket
77+ // object.
7278//
7379// If no credentials are found, a simple client without credentials is
7480// returned.
@@ -119,6 +125,9 @@ func ValidateSecret(secret *corev1.Secret) error {
119125 if _ , hasClientSecret := secret .Data [clientSecretField ]; hasClientSecret {
120126 valid = true
121127 }
128+ if _ , hasClientCertificate := secret .Data [clientCertificateField ]; hasClientCertificate {
129+ valid = true
130+ }
122131 }
123132 }
124133 if _ , hasResourceID := secret .Data [resourceIDField ]; hasResourceID {
@@ -132,8 +141,8 @@ func ValidateSecret(secret *corev1.Secret) error {
132141 }
133142
134143 if ! valid {
135- return fmt .Errorf ("invalid '%s' secret data: requires a '%s', '%s', or '%s' field, or a combination of '%s', '%s' and '%s'" ,
136- secret .Name , resourceIDField , clientIDField , accountKeyField , tenantIDField , clientIDField , clientSecretField )
144+ return fmt .Errorf ("invalid '%s' secret data: requires a '%s', '%s', or '%s' field, a combination of '%s', '%s' and '%s', or '%s', '%s' and '%s'" ,
145+ secret .Name , resourceIDField , clientIDField , accountKeyField , tenantIDField , clientIDField , clientSecretField , tenantIDField , clientIDField , clientCertificateField )
137146 }
138147 return nil
139148}
@@ -275,6 +284,13 @@ func tokenCredentialFromSecret(secret *corev1.Secret) (azcore.TokenCredential, e
275284 ID : azidentity .ClientID (clientID ),
276285 })
277286 }
287+ if clientCertificate , hasClientCertificate := secret .Data [clientCertificateField ]; hasClientCertificate {
288+ certs , key , err := azidentity .ParseCertificates (clientCertificate , secret .Data [clientCertificatePasswordField ])
289+ if err != nil {
290+ return nil , fmt .Errorf ("failed to parse client certificates: %w" , err )
291+ }
292+ return azidentity .NewClientCertificateCredential (string (tenantID ), string (clientID ), certs , key , nil )
293+ }
278294 if clientSecret , hasClientSecret := secret .Data [clientSecretField ]; hasClientSecret {
279295 return azidentity .NewClientSecretCredential (string (tenantID ), string (clientID ), string (clientSecret ), nil )
280296 }
0 commit comments