fix: only embed Azure roots on darwin (#25312)

Partially reverts #25136 for non-darwin platforms.

In general we want to avoid pinning trust roots to embedded Certs, since that limits operational flexibility. If Azure changes CAs, operators should, at most, be able to update the OS trust store to keep Coder working correctly. Embedding roots means we need to upgrade the Coder binary.

Since Coder Server on macOS is not really supported for production use, embedding only in that case to ease development and testing is OK.
This commit is contained in:
Spike Curtis
2026-05-14 11:45:21 -04:00
committed by GitHub
parent e37bf4f7be
commit 132fa87bf3
6 changed files with 171 additions and 137 deletions
+2
View File
@@ -54,6 +54,8 @@ extend-exclude = [
"tailnet/testdata/**",
"site/src/pages/SetupPage/countries.tsx",
"provisioner/terraform/testdata/**",
"coderd/azureidentity/roots_darwin.go",
"coderd/azureidentity/azureidentity.go",
# notifications' golden files confuse the detector because of quoted-printable encoding
"coderd/notifications/testdata/**",
"agent/agentcontainers/testdata/devcontainercli/**",
+3 -99
View File
@@ -184,7 +184,9 @@ type metadata struct {
type Options struct {
// Roots is the trusted root certificate pool. If nil,
// the embedded root certificate pool is used.
// the default cert pool is used. On darwin, this is an
// embedded pool. On all other platforms it is the system
// pool.
Roots *x509.CertPool
// Intermediates are additional intermediate certificates to
// inject into the PKCS7 object for chain verification. Azure
@@ -335,104 +337,6 @@ func ParseCertificates() ([]*x509.Certificate, error) {
return certs, nil
}
// Roots are the root CAs that Azure instance-identity certificates chain to.
// These are embedded so verification works deterministically on all
// platforms, including macOS where the system verifier would otherwise be
// used and may reject otherwise valid Azure certificates due to stricter
// standards-compliance checks. See https://github.com/coder/coder/issues/12978.
var Roots = []string{
// DigiCert Global Root G2
`-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----`,
// DigiCert Global Root G3
`-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
-----END CERTIFICATE-----`,
// Baltimore CyberTrust Root.
// Required for chains rooted here, e.g. "Microsoft RSA TLS CA 01/02".
// Expired 2025-05-12 but kept so callers that pass a CurrentTime
// before the expiry can still verify historical signatures.
`-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----`,
}
// rootCertPool returns a CertPool containing the root CAs that Azure
// instance-identity certificates ultimately chain to. We embed these so
// callers do not have to populate Roots themselves, and so we never
// implicitly fall back to the platform's system verifier (notably Apple's
// Security framework on macOS/iOS) which enforces stricter standards-
// compliance checks than Go's pure-Go verifier and rejects some otherwise
// valid Azure leaf certificates.
var rootCertPool = sync.OnceValues(func() (*x509.CertPool, error) {
pool := x509.NewCertPool()
for _, pemCert := range Roots {
block, rest := pem.Decode([]byte(pemCert))
if block == nil {
return nil, xerrors.New("root: failed to decode PEM block")
}
if len(rest) != 0 {
return nil, xerrors.Errorf("root: invalid certificate, %d bytes remain", len(rest))
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, xerrors.Errorf("root: parse certificate: %w", err)
}
pool.AddCert(cert)
}
return pool, nil
})
// Certificates are manually downloaded from Azure, then processed with OpenSSL
// and added here. See: https://learn.microsoft.com/en-us/azure/security/fundamentals/azure-ca-details
//
@@ -8,7 +8,6 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/pem"
"math/big"
"runtime"
"testing"
@@ -62,40 +61,6 @@ func TestValidate(t *testing.T) {
}
}
// TestEmbeddedRoots ensures the package's embedded root certificates parse
// successfully. The Roots are used by Validate to avoid falling back to the
// platform's system verifier (notably Apple's Security framework on macOS),
// which previously caused TestValidate/regular to fail on macOS with
// `x509: "metadata.azure.com" certificate is not standards compliant`.
// See https://github.com/coder/coder/issues/12978.
func TestEmbeddedRoots(t *testing.T) {
t.Parallel()
require.NotEmpty(t, azureidentity.Roots, "embedded roots must not be empty")
seen := map[string]bool{}
for _, pemCert := range azureidentity.Roots {
block, rest := pem.Decode([]byte(pemCert))
require.NotNil(t, block, "PEM block should decode")
require.Zero(t, len(rest), "no trailing data after PEM block")
cert, err := x509.ParseCertificate(block.Bytes)
require.NoError(t, err)
// Each root must be self-signed (issuer == subject).
require.Equal(t, cert.Issuer.String(), cert.Subject.String(),
"root certificate must be self-signed: %s", cert.Subject.CommonName)
require.False(t, seen[cert.Subject.CommonName],
"duplicate embedded root: %s", cert.Subject.CommonName)
seen[cert.Subject.CommonName] = true
}
// Verify the three roots Azure instance-identity chains ultimately
// terminate at are all present.
for _, name := range []string{
"DigiCert Global Root G2",
"DigiCert Global Root G3",
"Baltimore CyberTrust Root",
} {
require.True(t, seen[name], "missing embedded root %q", name)
}
}
func TestExpiresSoon(t *testing.T) {
t.Parallel()
// TODO (@kylecarbs): It's unknown why Microsoft does not have new certificates live...
@@ -261,9 +226,6 @@ func (tc *testCertChain) validationOptions() azureidentity.Options {
func TestValidate_TamperedContent(t *testing.T) {
t.Parallel()
if runtime.GOOS == "darwin" {
t.Skip("pkcs7 signing uses SHA1 which may be restricted on macOS")
}
chain := newTestCertChain(t)
+111
View File
@@ -0,0 +1,111 @@
//go:build darwin
package azureidentity
import (
"crypto/x509"
"encoding/pem"
"sync"
"golang.org/x/xerrors"
)
// rootCertPool returns a CertPool containing the root CAs that Azure
// instance-identity certificates ultimately chain to. On macOS, we embed these
// because Apple's Security framework enforces stricter standards-compliance
// checks than Go's pure-Go verifier and rejects some otherwise valid Azure leaf
// certificates. However, we want to avoid hardcoding the roots on other
// platforms because if Azure changes their root CAs, we want operators to be
// able to validate without having to get a new Coder binary. macOS support for
// coderd is only intended for development and testing, so this is a small trade
// off.
var rootCertPool = sync.OnceValues(func() (*x509.CertPool, error) {
pool := x509.NewCertPool()
for _, pemCert := range embeddedRoots {
block, rest := pem.Decode([]byte(pemCert))
if block == nil {
return nil, xerrors.New("root: failed to decode PEM block")
}
if len(rest) != 0 {
return nil, xerrors.Errorf("root: invalid certificate, %d bytes remain", len(rest))
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, xerrors.Errorf("root: parse certificate: %w", err)
}
pool.AddCert(cert)
}
return pool, nil
})
// embeddedRoots are the root CAs that Azure instance-identity certificates
// chain to. These are embedded so verification works on macOS where the system
// verifier would otherwise be used and may reject otherwise valid Azure
// certificates due to stricter standards-compliance checks.
// See https://github.com/coder/coder/issues/12978.
var embeddedRoots = []string{
// DigiCert Global Root G2
`-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
-----END CERTIFICATE-----`,
// DigiCert Global Root G3
`-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
-----END CERTIFICATE-----`,
// Baltimore CyberTrust Root.
// Required for chains rooted here, e.g. "Microsoft RSA TLS CA 01/02".
// Expired 2025-05-12 but kept so callers that pass a CurrentTime
// before the expiry can still verify historical signatures.
`-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----`,
}
@@ -0,0 +1,45 @@
//go:build darwin
package azureidentity
import (
"crypto/x509"
"encoding/pem"
"testing"
"github.com/stretchr/testify/require"
)
// TestEmbeddedRoots ensures the package's embedded root certificates parse
// successfully. The roots are used by Validate to avoid falling back to the
// platform's system verifier (notably Apple's Security framework on macOS),
// which previously caused TestValidate/regular to fail on macOS with
// `x509: "metadata.azure.com" certificate is not standards compliant`.
// See https://github.com/coder/coder/issues/12978.
func TestEmbeddedRoots(t *testing.T) {
t.Parallel()
require.NotEmpty(t, embeddedRoots, "embedded roots must not be empty")
seen := map[string]bool{}
for _, pemCert := range embeddedRoots {
block, rest := pem.Decode([]byte(pemCert))
require.NotNil(t, block, "PEM block should decode")
require.Zero(t, len(rest), "no trailing data after PEM block")
cert, err := x509.ParseCertificate(block.Bytes)
require.NoError(t, err)
// Each root must be self-signed (issuer == subject).
require.Equal(t, cert.Issuer.String(), cert.Subject.String(),
"root certificate must be self-signed: %s", cert.Subject.CommonName)
require.False(t, seen[cert.Subject.CommonName],
"duplicate embedded root: %s", cert.Subject.CommonName)
seen[cert.Subject.CommonName] = true
}
// Verify the three roots Azure instance-identity chains ultimately
// terminate at are all present.
for _, name := range []string{
"DigiCert Global Root G2",
"DigiCert Global Root G3",
"Baltimore CyberTrust Root",
} {
require.True(t, seen[name], "missing embedded root %q", name)
}
}
+10
View File
@@ -0,0 +1,10 @@
//go:build !darwin
package azureidentity
import "crypto/x509"
// rootCertPool returns the system cert pool on non-Apple platforms.
func rootCertPool() (*x509.CertPool, error) {
return x509.SystemCertPool()
}