diff --git a/apis/actions.github.com/v1alpha1/autoscalingrunnerset_types.go b/apis/actions.github.com/v1alpha1/autoscalingrunnerset_types.go index 24ccc8e328..e24d7dabd2 100644 --- a/apis/actions.github.com/v1alpha1/autoscalingrunnerset_types.go +++ b/apis/actions.github.com/v1alpha1/autoscalingrunnerset_types.go @@ -264,6 +264,38 @@ type ProxyServerConfig struct { // +optional CredentialSecretRef string `json:"credentialSecretRef,omitempty"` + + // +optional + // TLS configures mTLS (mutual TLS) for the proxy connection. + // When set, the client will present a certificate to the proxy server. + TLS *ProxyTLSConfig `json:"tls,omitempty"` +} + +// ProxyTLSConfig configures mTLS for proxy connections. +type ProxyTLSConfig struct { + // ClientCertSecretRef is a reference to a Kubernetes secret containing + // the client certificate and key for mTLS authentication. + // The secret must contain 'tls.crt' and 'tls.key' keys. + // +optional + ClientCertSecretRef string `json:"clientCertSecretRef,omitempty"` + + // CACertSecretRef is a reference to a Kubernetes secret containing + // the CA certificate to verify the proxy server's certificate. + // The secret must contain a 'ca.crt' key. + // +optional + CACertSecretRef string `json:"caCertSecretRef,omitempty"` + + // CACertConfigMapRef is a reference to a ConfigMap containing + // the CA certificate to verify the proxy server's certificate. + // The ConfigMap must contain a 'ca.crt' key. + // Alternative to CACertSecretRef when CA cert is not sensitive. + // +optional + CACertConfigMapRef string `json:"caCertConfigMapRef,omitempty"` + + // InsecureSkipVerify disables server certificate verification. + // WARNING: This should only be used for testing. + // +optional + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` } type VaultConfig struct { diff --git a/apis/actions.github.com/v1alpha1/zz_generated.deepcopy.go b/apis/actions.github.com/v1alpha1/zz_generated.deepcopy.go index df2dabc81a..9f601152e2 100644 --- a/apis/actions.github.com/v1alpha1/zz_generated.deepcopy.go +++ b/apis/actions.github.com/v1alpha1/zz_generated.deepcopy.go @@ -696,12 +696,12 @@ func (in *ProxyConfig) DeepCopyInto(out *ProxyConfig) { if in.HTTP != nil { in, out := &in.HTTP, &out.HTTP *out = new(ProxyServerConfig) - **out = **in + (*in).DeepCopyInto(*out) } if in.HTTPS != nil { in, out := &in.HTTPS, &out.HTTPS *out = new(ProxyServerConfig) - **out = **in + (*in).DeepCopyInto(*out) } if in.NoProxy != nil { in, out := &in.NoProxy, &out.NoProxy @@ -723,6 +723,11 @@ func (in *ProxyConfig) DeepCopy() *ProxyConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyServerConfig) DeepCopyInto(out *ProxyServerConfig) { *out = *in + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(ProxyTLSConfig) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyServerConfig. @@ -735,6 +740,21 @@ func (in *ProxyServerConfig) DeepCopy() *ProxyServerConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxyTLSConfig) DeepCopyInto(out *ProxyTLSConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyTLSConfig. +func (in *ProxyTLSConfig) DeepCopy() *ProxyTLSConfig { + if in == nil { + return nil + } + out := new(ProxyTLSConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceMeta) DeepCopyInto(out *ResourceMeta) { *out = *in diff --git a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalinglisteners.yaml b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalinglisteners.yaml index 184d877538..b1297c7c8c 100644 --- a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalinglisteners.yaml +++ b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalinglisteners.yaml @@ -192,6 +192,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -200,6 +230,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8782,6 +8842,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8790,6 +8880,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalingrunnersets.yaml b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalingrunnersets.yaml index 26f76125ae..191f819475 100644 --- a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalingrunnersets.yaml +++ b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_autoscalingrunnersets.yaml @@ -8366,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8374,6 +8404,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16518,6 +16578,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16526,6 +16616,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunners.yaml b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunners.yaml index b72318d8dc..9c870fe6d9 100644 --- a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunners.yaml +++ b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunners.yaml @@ -143,6 +143,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -151,6 +181,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8268,6 +8328,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8276,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunnersets.yaml b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunnersets.yaml index a2c8f787be..01209775e4 100644 --- a/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunnersets.yaml +++ b/charts/gha-runner-scale-set-controller-experimental/crds/actions.github.com_ephemeralrunnersets.yaml @@ -146,6 +146,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -154,6 +184,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8271,6 +8331,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8279,6 +8369,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalinglisteners.yaml b/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalinglisteners.yaml index 184d877538..b1297c7c8c 100644 --- a/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalinglisteners.yaml +++ b/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalinglisteners.yaml @@ -192,6 +192,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -200,6 +230,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8782,6 +8842,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8790,6 +8880,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalingrunnersets.yaml b/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalingrunnersets.yaml index 26f76125ae..191f819475 100644 --- a/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalingrunnersets.yaml +++ b/charts/gha-runner-scale-set-controller/crds/actions.github.com_autoscalingrunnersets.yaml @@ -8366,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8374,6 +8404,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16518,6 +16578,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16526,6 +16616,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunners.yaml b/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunners.yaml index b72318d8dc..9c870fe6d9 100644 --- a/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunners.yaml +++ b/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunners.yaml @@ -143,6 +143,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -151,6 +181,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8268,6 +8328,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8276,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunnersets.yaml b/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunnersets.yaml index a2c8f787be..01209775e4 100644 --- a/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunnersets.yaml +++ b/charts/gha-runner-scale-set-controller/crds/actions.github.com_ephemeralrunnersets.yaml @@ -146,6 +146,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -154,6 +184,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8271,6 +8331,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8279,6 +8369,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml b/charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml index 45817de28f..82c16d65b5 100644 --- a/charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml +++ b/charts/gha-runner-scale-set/templates/autoscalingrunnerset.yaml @@ -124,6 +124,21 @@ spec: {{- if .Values.proxy.http.credentialSecretRef }} credentialSecretRef: {{ .Values.proxy.http.credentialSecretRef }} {{- end }} + {{- if .Values.proxy.http.tls }} + tls: + {{- if .Values.proxy.http.tls.clientCertSecretRef }} + clientCertSecretRef: {{ .Values.proxy.http.tls.clientCertSecretRef }} + {{- end }} + {{- if .Values.proxy.http.tls.caCertSecretRef }} + caCertSecretRef: {{ .Values.proxy.http.tls.caCertSecretRef }} + {{- end }} + {{- if .Values.proxy.http.tls.caCertConfigMapRef }} + caCertConfigMapRef: {{ .Values.proxy.http.tls.caCertConfigMapRef }} + {{- end }} + {{- if .Values.proxy.http.tls.insecureSkipVerify }} + insecureSkipVerify: {{ .Values.proxy.http.tls.insecureSkipVerify }} + {{- end }} + {{- end }} {{- end }} {{- if .Values.proxy.https }} https: @@ -131,6 +146,21 @@ spec: {{- if .Values.proxy.https.credentialSecretRef }} credentialSecretRef: {{ .Values.proxy.https.credentialSecretRef }} {{- end }} + {{- if .Values.proxy.https.tls }} + tls: + {{- if .Values.proxy.https.tls.clientCertSecretRef }} + clientCertSecretRef: {{ .Values.proxy.https.tls.clientCertSecretRef }} + {{- end }} + {{- if .Values.proxy.https.tls.caCertSecretRef }} + caCertSecretRef: {{ .Values.proxy.https.tls.caCertSecretRef }} + {{- end }} + {{- if .Values.proxy.https.tls.caCertConfigMapRef }} + caCertConfigMapRef: {{ .Values.proxy.https.tls.caCertConfigMapRef }} + {{- end }} + {{- if .Values.proxy.https.tls.insecureSkipVerify }} + insecureSkipVerify: {{ .Values.proxy.https.tls.insecureSkipVerify }} + {{- end }} + {{- end }} {{- end }} {{- if and .Values.proxy.noProxy (kindIs "slice" .Values.proxy.noProxy) }} noProxy: {{ .Values.proxy.noProxy | toYaml | nindent 6}} diff --git a/charts/gha-runner-scale-set/values.yaml b/charts/gha-runner-scale-set/values.yaml index 4b4640cf9e..8703208032 100644 --- a/charts/gha-runner-scale-set/values.yaml +++ b/charts/gha-runner-scale-set/values.yaml @@ -45,14 +45,28 @@ githubConfigSecret: ## proxy can be used to define proxy settings that will be used by the ## controller, the listener and the runner of this scale set. +## +## For basic auth, use credentialSecretRef pointing to a secret with `username` and `password` keys. +## For mTLS (mutual TLS), use the tls section with client certificate configuration. # # proxy: # http: # url: http://proxy.com:1234 # credentialSecretRef: proxy-auth # a secret with `username` and `password` keys # https: -# url: http://proxy.com:1234 +# url: https://proxy.com:1234 # credentialSecretRef: proxy-auth # a secret with `username` and `password` keys +# ## mTLS configuration for proxies that require client certificate authentication +# tls: +# ## Secret containing client certificate and key (must have 'tls.crt' and 'tls.key' keys) +# ## You can create this with: kubectl create secret tls proxy-client-cert --cert=client.crt --key=client.key +# clientCertSecretRef: proxy-client-cert +# ## Secret containing CA certificate to verify proxy server (must have 'ca.crt' key) +# caCertSecretRef: proxy-ca-cert +# ## Or use a ConfigMap for the CA cert (must have 'ca.crt' key) +# # caCertConfigMapRef: proxy-ca-configmap +# ## Skip server certificate verification (NOT recommended for production) +# # insecureSkipVerify: false # noProxy: # - example.com # - example.org diff --git a/config/crd/bases/actions.github.com_autoscalinglisteners.yaml b/config/crd/bases/actions.github.com_autoscalinglisteners.yaml index 184d877538..b1297c7c8c 100644 --- a/config/crd/bases/actions.github.com_autoscalinglisteners.yaml +++ b/config/crd/bases/actions.github.com_autoscalinglisteners.yaml @@ -192,6 +192,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -200,6 +230,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8782,6 +8842,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8790,6 +8880,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/config/crd/bases/actions.github.com_autoscalingrunnersets.yaml b/config/crd/bases/actions.github.com_autoscalingrunnersets.yaml index 26f76125ae..191f819475 100644 --- a/config/crd/bases/actions.github.com_autoscalingrunnersets.yaml +++ b/config/crd/bases/actions.github.com_autoscalingrunnersets.yaml @@ -8366,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8374,6 +8404,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16518,6 +16578,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -16526,6 +16616,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/config/crd/bases/actions.github.com_ephemeralrunners.yaml b/config/crd/bases/actions.github.com_ephemeralrunners.yaml index b72318d8dc..9c870fe6d9 100644 --- a/config/crd/bases/actions.github.com_ephemeralrunners.yaml +++ b/config/crd/bases/actions.github.com_ephemeralrunners.yaml @@ -143,6 +143,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -151,6 +181,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8268,6 +8328,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8276,6 +8366,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/config/crd/bases/actions.github.com_ephemeralrunnersets.yaml b/config/crd/bases/actions.github.com_ephemeralrunnersets.yaml index a2c8f787be..01209775e4 100644 --- a/config/crd/bases/actions.github.com_ephemeralrunnersets.yaml +++ b/config/crd/bases/actions.github.com_ephemeralrunnersets.yaml @@ -146,6 +146,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -154,6 +184,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8271,6 +8331,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string @@ -8279,6 +8369,36 @@ spec: properties: credentialSecretRef: type: string + tls: + description: |- + TLS configures mTLS (mutual TLS) for the proxy connection. + When set, the client will present a certificate to the proxy server. + properties: + caCertConfigMapRef: + description: |- + CACertConfigMapRef is a reference to a ConfigMap containing + the CA certificate to verify the proxy server's certificate. + The ConfigMap must contain a 'ca.crt' key. + Alternative to CACertSecretRef when CA cert is not sensitive. + type: string + caCertSecretRef: + description: |- + CACertSecretRef is a reference to a Kubernetes secret containing + the CA certificate to verify the proxy server's certificate. + The secret must contain a 'ca.crt' key. + type: string + clientCertSecretRef: + description: |- + ClientCertSecretRef is a reference to a Kubernetes secret containing + the client certificate and key for mTLS authentication. + The secret must contain 'tls.crt' and 'tls.key' keys. + type: string + insecureSkipVerify: + description: |- + InsecureSkipVerify disables server certificate verification. + WARNING: This should only be used for testing. + type: boolean + type: object url: description: Required type: string diff --git a/controllers/actions.github.com/multiclient/multi_client.go b/controllers/actions.github.com/multiclient/multi_client.go index 64483550bc..7f4cb8e77a 100644 --- a/controllers/actions.github.com/multiclient/multi_client.go +++ b/controllers/actions.github.com/multiclient/multi_client.go @@ -3,6 +3,7 @@ package multiclient import ( "context" "crypto/sha256" + "crypto/tls" "crypto/x509" "fmt" "net/http" @@ -87,11 +88,12 @@ func (m *Scaleset) GetClientFor(ctx context.Context, opts *ClientForOptions) (Cl } type ClientForOptions struct { - GithubConfigURL string - AppConfig appconfig.AppConfig - Namespace string - RootCAs *x509.CertPool - ProxyFunc func(*http.Request) (*url.URL, error) + GithubConfigURL string + AppConfig appconfig.AppConfig + Namespace string + RootCAs *x509.CertPool + ProxyFunc func(*http.Request) (*url.URL, error) + TLSClientCertificates []tls.Certificate } func (o *ClientForOptions) identifier() (string, error) { @@ -123,6 +125,10 @@ func (o *ClientForOptions) identifier() (string, error) { identifier += fmt.Sprintf(",rootCAs:%q", o.RootCAs.Subjects()) } + if len(o.TLSClientCertificates) > 0 { + identifier += fmt.Sprintf(",tlsClientCerts:%d", len(o.TLSClientCertificates)) + } + return uuid.NewHash(sha256.New(), uuid.NameSpaceOID, []byte(identifier), 6).String(), nil } @@ -142,6 +148,9 @@ func (o *ClientForOptions) newClient() (*scaleset.Client, error) { if o.ProxyFunc != nil { options = append(options, scaleset.WithProxy(o.ProxyFunc)) } + for _, cert := range o.TLSClientCertificates { + options = append(options, scaleset.WithTLSClientCertificate(cert)) + } if o.AppConfig.Token != "" { c, err := scaleset.NewClientWithPersonalAccessToken( diff --git a/controllers/actions.github.com/resourcebuilder.go b/controllers/actions.github.com/resourcebuilder.go index 45ccf1245c..7adcb3144e 100644 --- a/controllers/actions.github.com/resourcebuilder.go +++ b/controllers/actions.github.com/resourcebuilder.go @@ -75,6 +75,89 @@ func SetListenerEntrypoint(entrypoint string) { } } +// proxyTLSVolumesAndMounts returns volumes and volume mounts for proxy mTLS configuration. +// It creates volumes for client certificates and CA certificates if configured. +func proxyTLSVolumesAndMounts(proxy *v1alpha1.ProxyConfig) ([]corev1.Volume, []corev1.VolumeMount) { + if proxy == nil { + return nil, nil + } + + var volumes []corev1.Volume + var mounts []corev1.VolumeMount + + // Helper to add TLS volumes for a proxy server config + addTLSConfig := func(prefix string, tls *v1alpha1.ProxyTLSConfig) { + if tls == nil { + return + } + + // Client certificate secret + if tls.ClientCertSecretRef != "" { + volName := prefix + "-client-cert" + volumes = append(volumes, corev1.Volume{ + Name: volName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: tls.ClientCertSecretRef, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + Name: volName, + MountPath: "/etc/proxy-tls/" + prefix + "/client", + ReadOnly: true, + }) + } + + // CA certificate from secret + if tls.CACertSecretRef != "" { + volName := prefix + "-ca-cert" + volumes = append(volumes, corev1.Volume{ + Name: volName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: tls.CACertSecretRef, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + Name: volName, + MountPath: "/etc/proxy-tls/" + prefix + "/ca", + ReadOnly: true, + }) + } + + // CA certificate from configmap + if tls.CACertConfigMapRef != "" { + volName := prefix + "-ca-configmap" + volumes = append(volumes, corev1.Volume{ + Name: volName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: tls.CACertConfigMapRef, + }, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + Name: volName, + MountPath: "/etc/proxy-tls/" + prefix + "/ca-cm", + ReadOnly: true, + }) + } + } + + if proxy.HTTP != nil { + addTLSConfig("http-proxy", proxy.HTTP.TLS) + } + if proxy.HTTPS != nil { + addTLSConfig("https-proxy", proxy.HTTPS.TLS) + } + + return volumes, mounts +} + type SecretResolver interface { GetAppConfig(ctx context.Context, obj object.ActionsGitHubObject) (*appconfig.AppConfig, error) GetActionsService(ctx context.Context, obj object.ActionsGitHubObject) (multiclient.Client, error) @@ -266,6 +349,32 @@ func (b *ResourceBuilder) newScaleSetListenerPod(autoscalingListener *v1alpha1.A ports = append(ports, port) } + // Base volume mounts + volumeMounts := []corev1.VolumeMount{ + { + Name: "listener-config", + MountPath: "/etc/gha-listener", + ReadOnly: true, + }, + } + + // Base volumes + volumes := []corev1.Volume{ + { + Name: "listener-config", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: podConfig.Name, + }, + }, + }, + } + + // Add proxy mTLS volumes and mounts if configured + proxyTLSVolumes, proxyTLSMounts := proxyTLSVolumesAndMounts(autoscalingListener.Spec.Proxy) + volumes = append(volumes, proxyTLSVolumes...) + volumeMounts = append(volumeMounts, proxyTLSMounts...) + terminationGracePeriodSeconds := int64(60) podSpec := corev1.PodSpec{ ServiceAccountName: serviceAccount.Name, @@ -280,26 +389,11 @@ func (b *ResourceBuilder) newScaleSetListenerPod(autoscalingListener *v1alpha1.A Command: []string{ scaleSetListenerEntrypoint, }, - Ports: ports, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "listener-config", - MountPath: "/etc/gha-listener", - ReadOnly: true, - }, - }, - }, - }, - Volumes: []corev1.Volume{ - { - Name: "listener-config", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: podConfig.Name, - }, - }, + Ports: ports, + VolumeMounts: volumeMounts, }, }, + Volumes: volumes, ImagePullSecrets: autoscalingListener.Spec.ImagePullSecrets, RestartPolicy: corev1.RestartPolicyNever, TerminationGracePeriodSeconds: &terminationGracePeriodSeconds, @@ -697,6 +791,10 @@ func (b *ResourceBuilder) newEphemeralRunnerPod(runner *v1alpha1.EphemeralRunner newPod.Spec = runner.Spec.Spec newPod.Spec.Containers = make([]corev1.Container, 0, len(runner.Spec.Spec.Containers)) + // Add proxy mTLS volumes if configured + proxyTLSVolumes, proxyTLSMounts := proxyTLSVolumesAndMounts(runner.Spec.Proxy) + newPod.Spec.Volumes = append(newPod.Spec.Volumes, proxyTLSVolumes...) + for _, c := range runner.Spec.Spec.Containers { if c.Name == v1alpha1.EphemeralRunnerContainerName { c.Env = append( @@ -722,6 +820,8 @@ func (b *ResourceBuilder) newEphemeralRunnerPod(runner *v1alpha1.EphemeralRunner }, ) c.Env = append(c.Env, envs...) + // Add proxy mTLS volume mounts to runner container + c.VolumeMounts = append(c.VolumeMounts, proxyTLSMounts...) } newPod.Spec.Containers = append(newPod.Spec.Containers, c) diff --git a/controllers/actions.github.com/secretresolver/secret_resolver.go b/controllers/actions.github.com/secretresolver/secret_resolver.go index 5f3e95612d..0f21706c12 100644 --- a/controllers/actions.github.com/secretresolver/secret_resolver.go +++ b/controllers/actions.github.com/secretresolver/secret_resolver.go @@ -2,6 +2,7 @@ package secretresolver import ( "context" + "crypto/tls" "crypto/x509" "encoding/json" "fmt" @@ -10,6 +11,7 @@ import ( "net/url" "strings" + v1alpha1 "github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1" "github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1/appconfig" "github.com/actions/actions-runner-controller/controllers/actions.github.com/multiclient" "github.com/actions/actions-runner-controller/controllers/actions.github.com/object" @@ -121,6 +123,16 @@ func (sr *SecretResolver) GetActionsService(ctx context.Context, obj object.Acti } } + // Load mTLS client certificates for proxy authentication + var tlsClientCerts []tls.Certificate + if proxy := obj.GitHubProxy(); proxy != nil { + certs, err := sr.loadProxyTLSClientCerts(ctx, obj.GetNamespace(), proxy) + if err != nil { + return nil, fmt.Errorf("failed to load proxy TLS client certificates: %w", err) + } + tlsClientCerts = certs + } + var rootCAs *x509.CertPool if tc := obj.GitHubServerTLS(); tc != nil { pool, err := tc.ToCertPool(func(name, key string) ([]byte, error) { @@ -149,11 +161,12 @@ func (sr *SecretResolver) GetActionsService(ctx context.Context, obj object.Acti return sr.multiClient.GetClientFor( ctx, &multiclient.ClientForOptions{ - GithubConfigURL: obj.GitHubConfigUrl(), - AppConfig: *appConfig, - Namespace: obj.GetNamespace(), - RootCAs: rootCAs, - ProxyFunc: proxyFunc, + GithubConfigURL: obj.GitHubConfigUrl(), + AppConfig: *appConfig, + Namespace: obj.GetNamespace(), + RootCAs: rootCAs, + ProxyFunc: proxyFunc, + TLSClientCertificates: tlsClientCerts, }, ) } @@ -279,3 +292,57 @@ func (r *vaultResolver) proxyCredentials(ctx context.Context, key string) (*url. return url.UserPassword(i.Username, i.Password), nil } + +// loadProxyTLSClientCerts loads TLS client certificates from secrets for mTLS proxy authentication +func (sr *SecretResolver) loadProxyTLSClientCerts(ctx context.Context, namespace string, proxy *v1alpha1.ProxyConfig) ([]tls.Certificate, error) { + var certs []tls.Certificate + + // Load HTTP proxy client cert if configured + if proxy.HTTP != nil && proxy.HTTP.TLS != nil && proxy.HTTP.TLS.ClientCertSecretRef != "" { + cert, err := sr.loadTLSCertFromSecret(ctx, namespace, proxy.HTTP.TLS.ClientCertSecretRef) + if err != nil { + return nil, fmt.Errorf("failed to load HTTP proxy client cert: %w", err) + } + certs = append(certs, cert) + } + + // Load HTTPS proxy client cert if configured + if proxy.HTTPS != nil && proxy.HTTPS.TLS != nil && proxy.HTTPS.TLS.ClientCertSecretRef != "" { + cert, err := sr.loadTLSCertFromSecret(ctx, namespace, proxy.HTTPS.TLS.ClientCertSecretRef) + if err != nil { + return nil, fmt.Errorf("failed to load HTTPS proxy client cert: %w", err) + } + certs = append(certs, cert) + } + + return certs, nil +} + +// loadTLSCertFromSecret loads a TLS certificate from a Kubernetes TLS secret +func (sr *SecretResolver) loadTLSCertFromSecret(ctx context.Context, namespace, secretName string) (tls.Certificate, error) { + var secret corev1.Secret + err := sr.k8sClient.Get(ctx, types.NamespacedName{ + Namespace: namespace, + Name: secretName, + }, &secret) + if err != nil { + return tls.Certificate{}, fmt.Errorf("failed to get secret %s: %w", secretName, err) + } + + certPEM, ok := secret.Data["tls.crt"] + if !ok { + return tls.Certificate{}, fmt.Errorf("secret %s missing tls.crt key", secretName) + } + + keyPEM, ok := secret.Data["tls.key"] + if !ok { + return tls.Certificate{}, fmt.Errorf("secret %s missing tls.key key", secretName) + } + + cert, err := tls.X509KeyPair(certPEM, keyPEM) + if err != nil { + return tls.Certificate{}, fmt.Errorf("failed to parse TLS certificate: %w", err) + } + + return cert, nil +} diff --git a/go.mod b/go.mod index 4cf62aee83..426f029757 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 - github.com/actions/scaleset v0.4.0 + github.com/actions/scaleset v0.4.1-0.20260520143653-91e1f401c9c5 github.com/bradleyfalzon/ghinstallation/v2 v2.18.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/evanphx/json-patch v5.9.11+incompatible @@ -28,7 +28,7 @@ require ( github.com/teambition/rrule-go v1.8.2 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.1 - golang.org/x/net v0.52.0 + golang.org/x/net v0.54.0 golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.20.0 gomodules.xyz/jsonpatch/v2 v2.5.0 @@ -115,7 +115,7 @@ require ( github.com/go-openapi/swag/yamlutils v0.25.5 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/gonvenience/bunt v1.4.3 // indirect github.com/gonvenience/idem v0.0.3 // indirect @@ -152,7 +152,7 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-zglob v0.0.6 // indirect @@ -190,14 +190,14 @@ require ( github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.49.0 // indirect + golang.org/x/crypto v0.51.0 // indirect golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.41.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/term v0.43.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.43.0 // indirect + golang.org/x/tools v0.44.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 8a6ea55865..5d57982b0d 100644 --- a/go.sum +++ b/go.sum @@ -25,10 +25,8 @@ github.com/ProtonMail/go-crypto v1.4.0 h1:Zq/pbM3F5DFgJiMouxEdSVY44MVoQNEKp5d5Qx github.com/ProtonMail/go-crypto v1.4.0/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/actions-runner-controller/httpcache v0.2.0 h1:hCNvYuVPJ2xxYBymqBvH0hSiQpqz4PHF/LbU3XghGNI= github.com/actions-runner-controller/httpcache v0.2.0/go.mod h1:JLu9/2M/btPz1Zu/vTZ71XzukQHn2YeISPmJoM5exBI= -github.com/actions/scaleset v0.3.0 h1:y5/ClYLJXFuGCikzILOOPhaCShAcL6K0mnUtjDKFxVw= -github.com/actions/scaleset v0.3.0/go.mod h1:2L2I6rggFWV+zprDet6y7y7Vkm3HPudaup78eSc79Uo= -github.com/actions/scaleset v0.4.0 h1:691GC2AkHb3ZGjfNvatboYoRS7CLr3+4VcZk/6w9IbM= -github.com/actions/scaleset v0.4.0/go.mod h1:2L2I6rggFWV+zprDet6y7y7Vkm3HPudaup78eSc79Uo= +github.com/actions/scaleset v0.4.1-0.20260520143653-91e1f401c9c5 h1:MAuhes0m6aiOWN2BOl9aofXgYKMdWwFMaFhj+jAfPO0= +github.com/actions/scaleset v0.4.1-0.20260520143653-91e1f401c9c5/go.mod h1:+Ylz7IYPnOTJd8dZmMziJ7J9HEfZhdoH7iliEWSb/Ms= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go-v2 v1.41.3 h1:4kQ/fa22KjDt13QCy1+bYADvdgcxpfH18f0zP542kZA= @@ -132,8 +130,8 @@ github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -193,8 +191,8 @@ github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI6 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -319,8 +317,9 @@ github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -450,20 +449,20 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= +golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -484,21 +483,21 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=