Skip to content

Commit b4b0c69

Browse files
enxebrebryan-cox
authored andcommitted
Add the ability to auth via certs without storing them in etcd secret
Signed-off-by: Bryan Cox <[email protected]>
1 parent 85def75 commit b4b0c69

File tree

5 files changed

+83
-7
lines changed

5 files changed

+83
-7
lines changed

api/v1beta1/azureclusteridentity_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type AzureClusterIdentitySpec struct {
5959
// ClientSecret is a secret reference which should contain either a Service Principal password or certificate secret.
6060
// +optional
6161
ClientSecret corev1.SecretReference `json:"clientSecret,omitempty"`
62-
// certPath is the path where certificates exist. When set, it takes precedence over ClientSecret for types that uses certs like ServicePrincipalCertificate.
62+
// certPath is the path where certificates exist. When set, it takes precedence over ClientSecret for types that use certs like ServicePrincipalCertificate.
6363
// +optional
6464
CertPath string `json:"certPath,omitempty"`
6565
// TenantID is the service principal primary tenant id.

azure/scope/identity.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package scope
1818

1919
import (
2020
"context"
21+
"os"
2122
"reflect"
2223

2324
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
@@ -127,11 +128,20 @@ func (p *AzureCredentialsProvider) GetTokenCredential(ctx context.Context, resou
127128
cred, authErr = azidentity.NewClientSecretCredential(p.GetTenantID(), p.Identity.Spec.ClientID, clientSecret, &options)
128129

129130
case infrav1.ServicePrincipalCertificate:
130-
clientSecret, err := p.GetClientSecret(ctx)
131-
if err != nil {
132-
return nil, errors.Wrap(err, "failed to get client secret")
131+
var certsContent []byte
132+
if p.Identity.Spec.CertPath != "" {
133+
certsContent, err = os.ReadFile(p.Identity.Spec.CertPath)
134+
if err != nil {
135+
return nil, errors.Wrap(err, "failed to read certificate file")
136+
}
137+
} else {
138+
clientSecret, err := p.GetClientSecret(ctx)
139+
if err != nil {
140+
return nil, errors.Wrap(err, "failed to get client secret")
141+
}
142+
certsContent = []byte(clientSecret)
133143
}
134-
certs, key, err := azidentity.ParseCertificates([]byte(clientSecret), nil)
144+
certs, key, err := azidentity.ParseCertificates(certsContent, nil)
135145
if err != nil {
136146
return nil, errors.Wrap(err, "failed to parse certificate data")
137147
}

azure/scope/identity_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,25 @@ func TestGetTokenCredential(t *testing.T) {
316316
},
317317
},
318318
},
319+
{
320+
name: "service principal certificate with certificate filepath",
321+
cluster: &infrav1.AzureCluster{
322+
Spec: infrav1.AzureClusterSpec{
323+
AzureClusterClassSpec: infrav1.AzureClusterClassSpec{
324+
IdentityRef: &corev1.ObjectReference{
325+
Kind: infrav1.AzureClusterIdentityKind,
326+
},
327+
},
328+
},
329+
},
330+
identity: &infrav1.AzureClusterIdentity{
331+
Spec: infrav1.AzureClusterIdentitySpec{
332+
Type: infrav1.ServicePrincipalCertificate,
333+
TenantID: fakeTenantID,
334+
CertPath: "./test/certificate",
335+
},
336+
},
337+
},
319338
{
320339
name: "user-assigned identity",
321340
cluster: &infrav1.AzureCluster{

azure/scope/test/certificate

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDjrdEr9P0TaUES
3+
dspE6cyo22NU8yhRrbYlV9VH2vWvnPsThXcxhnd+cUqdNEBswhwgFlUQcg/eSVxw
4+
rr+3nh+bFTZWPcY+1LQYxfpKGsrCXQfB82LDJIZDX4gHYrWf3Z272jXN1XeFAKti
5+
wDKgDXXuPH7r5lH7vC3RXeAffqLwQJhZf+NoHNtv9MH9IdUkQfmDFZtI/CQzCrb6
6+
+vOS6EmUD/Q2FNHBzgxCguGqgNyBcQbxJ9Qng+ZjIFuhGYXJlsyRUtexyzTR5/v0
7+
VNK8UsZgRBFhXqrBv/RoCCG+xVJYtmd0QsrvNzDqG6QnjUB21zVXqzKEkW2gRtjX
8+
cw4vYQehAgMBAAECggEAS6xtjg0nAokk0jS+ZOpKlkMZAFaza3ZvyHipkHDz4PMt
9+
tl7Rb5oQZGvWT2rbEOrxey7BBi7LHGhIu8ExQp/hRGPoBAETP7XlyCghWPkPtEtE
10+
dU/mXxLoN0NszHuf/2si7pmH8YqGZ6QB0tgr22ut60mbK+AJFsEEf4aSpBUspepJ
11+
2800sQHsqPE6L6kYkfZ2GRRY1V9vUrYEODKZpWzMhN3UA9nAKH9PB6xvP2OdyMNh
12+
hKgmUUMNIFtwr8pZlJn60cf0UrWrc5CvqQLuaGYlzDgUQGV4JEVjqm9F6lMfEPUw
13+
eN70MVe1pcLeLq2rGCVWU3gakh/HvJqlR/sa546HgwKBgQDyf1vkyX4w5sboi6DJ
14+
cl5dMULtMMRpB1OaMFVOJjI9gZJ8mCdRjqXdYo5aS2KIqxie8tGG9+SohxDAWl4t
15+
lSUtDsE44fSmILqC5zIawNRQnnkv0X8LwmYu0Qd7YAjJMlLTWyDRsjD9XRq4nsR+
16+
mJVwrt85iSpS5UFyryEzPbFj0wKBgQDwWzraeN0Eccf1iIYmQsYy+yMEAlHNR5yi
17+
gPXuAhSybv2JReRhdUb39hLr/LvKw0ZeXiLWXmYUGpbyzPyXIm0s+PL3LWl65GTF
18+
l+cfV5wfAdDkk6rAdEPEE2pxN85ChyaPYPoYr0ohmV97VQcYc5FqY+j1tM6R1RDt
19+
/fWBSa8iOwKBgQCpa1dtWWTDj4gqUdrswu2wmEkU47xlUIwVLm164u64z/zi9X6K
20+
2WmCaWfhJ8fYigjyi9zdOfXT1EFc0gX4PLozZ5qRPjQpmLYV3KbB0DTFemJaiTgE
21+
pDW1wa5DgQ3CW1lIduNP/fmCGfkgQTQw6jOF/XbRgMZEEg2OrVI5tYFopwKBgER9
22+
iqjEth5VGejCjY+LiZTvcUvsKUk4tc6stueqmiE6dW7PhsOqup1f9oZej1i5Cm1L
23+
n9u8LJRf+1GWzgd3HOsqyXlb7GnDeV/A6HBK88b2KoNn/Mk4mDLgYX1/rHvSrU9A
24+
ECRGlvY6ETZAxXPXQsGxVKnnatGtiFR5AKNlzs0PAoGAa5+X+DUqGh9aE5ID3wrv
25+
jkjxQ2KLFJCNSq8f9GSuvpvgXstHh6wKoM6vMwIShjgXuURH8Ub4uhRsWnxMildF
26+
7EE+QaWU9jnCm2HQYArfXrAWw6DBudiSkBqgKc6HjDHun5fXlYUo8UesNMQOrg7b
27+
bydQZ5/4V/1oSWPETk7jSr0=
28+
-----END PRIVATE KEY-----
29+
-----BEGIN CERTIFICATE-----
30+
MIIDCTCCAfGgAwIBAgIUFSntEn+Tv6HM2xJReECJpJcC7iUwDQYJKoZIhvcNAQEL
31+
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDEwODE5NTQxNFoXDTM0MDEw
32+
NTE5NTQxNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
33+
AAOCAQ8AMIIBCgKCAQEA463RK/T9E2lBEnbKROnMqNtjVPMoUa22JVfVR9r1r5z7
34+
E4V3MYZ3fnFKnTRAbMIcIBZVEHIP3klccK6/t54fmxU2Vj3GPtS0GMX6ShrKwl0H
35+
wfNiwySGQ1+IB2K1n92du9o1zdV3hQCrYsAyoA117jx+6+ZR+7wt0V3gH36i8ECY
36+
WX/jaBzbb/TB/SHVJEH5gxWbSPwkMwq2+vrzkuhJlA/0NhTRwc4MQoLhqoDcgXEG
37+
8SfUJ4PmYyBboRmFyZbMkVLXscs00ef79FTSvFLGYEQRYV6qwb/0aAghvsVSWLZn
38+
dELK7zcw6hukJ41Adtc1V6syhJFtoEbY13MOL2EHoQIDAQABo1MwUTAdBgNVHQ4E
39+
FgQUfry/KDtamwMlRQsFPbBhzdv2U5cwHwYDVR0jBBgwFoAUfry/KDtamwMlRQsF
40+
PbBhzdv2U5cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAyYst
41+
VvewKRRpuYRWc4XG6WnYphUdyZLMoIlq0syZ1aj6YbqoK9NMHAYEnCvSov6zIZOa
42+
trhuUcf9GFz5e0iJ2zIlDc312Iwsv41xiC/bs16kEn8Yf/SujEXasj7vmA3HrFWf
43+
wZTH/yFL5azo/f+lA1Q28YwqFpHmle0y0O53Uth4p0tmwlnu+CrO9fHp3kTlb7fD
44+
6mqfk9Nrt8tOC4aHYDoqtYUgZhx58xsHMOTetKeRlp8HMF9oROtriz4nYm6IhTwo
45+
5k1A13S3BjaxkZCyPXCgXssuXagNLasrr5Qq+Vgdb/nDhVehV8+Z4J0Ynzy9MZsE
46+
H1N1NfMtsA+PEqtPXA==
47+
-----END CERTIFICATE-----

config/crd/bases/infrastructure.cluster.x-k8s.io_azureclusteridentities.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ spec:
125125
type: object
126126
certPath:
127127
description: certPath is the path where certificates exist. When set,
128-
it takes precedence over ClientSecret for types that uses certs
129-
like ServicePrincipalCertificate.
128+
it takes precedence over ClientSecret for types that use certs like
129+
ServicePrincipalCertificate.
130130
type: string
131131
clientID:
132132
description: |-

0 commit comments

Comments
 (0)