Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions api/v1alpha2/istio_merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ func (m *meshConfigBuilder) BuildExternalAuthorizerConfiguration(authorizers []*
return m
}

func (m *meshConfigBuilder) BuildTrustDomainConfig(domain *string) *meshConfigBuilder {
if domain == nil {
return m
}

err := m.c.SetPath("trustDomain", *domain)
if err != nil {
return nil
}
return m
}

func (m *meshConfigBuilder) BuildForwardClientCertDetails(xfccStrategy *XFCCStrategy) *meshConfigBuilder {
if xfccStrategy == nil {
return m
Expand Down Expand Up @@ -226,6 +238,7 @@ func (i *Istio) mergeConfig(op iopv1alpha1.IstioOperator) (iopv1alpha1.IstioOper
BuildDualStackConfig(dualStackEnabled).
BuildForwardClientCertDetails(i.Spec.Config.ForwardClientCertDetails).
BuildAmbientConfig(ambientEnabled).
BuildTrustDomainConfig(i.Spec.Config.TrustDomain).
Build()

op.Spec.MeshConfig = newMeshConfig
Expand Down
7 changes: 7 additions & 0 deletions api/v1alpha2/istio_structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ type Config struct {
// Defines the telemetry configuration of Istio.
// +kubebuilder:validation:Optional
Telemetry Telemetry `json:"telemetry,omitempty"`

// Defines trust domain configuration of Istio.
// +kubebuilder:validation:Optional
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Pattern=`^[a-z0-9]*([a-z0-9-_]*)?(\.[a-z0-9]*([a-z0-9-_]*[a-z0-9]*)?)*$`
TrustDomain *string `json:"trustDomain,omitempty"`
}

// Defines how to handle the x-forwarded-client-cert (XFCC) of the HTTP header.
Expand Down
59 changes: 59 additions & 0 deletions api/v1alpha2/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,65 @@ var _ = Describe("Merge", func() {
Expect(exists).To(BeTrue())
Expect(hbone).To(Equal("true"))
})
Context("TrustDomain", func() {
It("Should set IstioOperator TrustDomain, when Istio CR configures it", func() {
// given
m := mesh.DefaultMeshConfig()
meshConfigRaw := convert(m)
iop := iopv1alpha1.IstioOperator{
Spec: iopv1alpha1.IstioOperatorSpec{
MeshConfig: meshConfigRaw,
},
}

istioCR := istiov1alpha2.Istio{
Spec: istiov1alpha2.IstioSpec{
Config: istiov1alpha2.Config{
TrustDomain: ptr.To("trusted.com"),
},
},
}

// when
out, err := istioCR.MergeInto(iop)

// then
Expect(err).ShouldNot(HaveOccurred())
meshConfig, err := values.MapFromObject(out.Spec.MeshConfig)
Expect(err).ShouldNot(HaveOccurred())
trustDomain, exists := meshConfig.GetPath("trustDomain")
Expect(exists).To(BeTrue())
Expect(trustDomain).To(Equal("trusted.com"))
})

It("Should set IstioOperator TrustDomain, when Istio CR configures it", func() {
// given
m := mesh.DefaultMeshConfig()
meshConfigRaw := convert(m)
iop := iopv1alpha1.IstioOperator{
Spec: iopv1alpha1.IstioOperatorSpec{
MeshConfig: meshConfigRaw,
},
}

istioCR := istiov1alpha2.Istio{
Spec: istiov1alpha2.IstioSpec{
Config: istiov1alpha2.Config{},
},
}

// when
out, err := istioCR.MergeInto(iop)

// then
Expect(err).ShouldNot(HaveOccurred())
meshConfig, err := values.MapFromObject(out.Spec.MeshConfig)
Expect(err).ShouldNot(HaveOccurred())
trustDomain, exists := meshConfig.GetPath("trustDomain")
Expect(exists).To(BeTrue())
Expect(trustDomain).To(Equal("cluster.local"))
})
})

Context("Pilot", func() {
Context("When Istio CR has 500m configured for CPU limits", func() {
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions config/crd/bases/operator.kyma-project.io_istios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,12 @@ spec:
type: boolean
type: object
type: object
trustDomain:
description: Defines trust domain configuration of Istio.
maxLength: 255
minLength: 1
pattern: ^[a-z0-9]*([a-z0-9-_]*)?(\.[a-z0-9]*([a-z0-9-_]*[a-z0-9]*)?)*$
type: string
type: object
experimental:
description: Defines experimental configuration options.
Expand Down
3 changes: 3 additions & 0 deletions config/ui-extensions/istios/details
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ body:
- source: spec.config.numTrustedProxies
name: config.numTrustedProxies
placeholder: '1'
- source: spec.config.trustDomain
name: config.trustDomain
visibility: '$exists($value)'
- source: spec.compatibilityMode
name: compatibilityMode
placeholder: 'false'
Expand Down
6 changes: 6 additions & 0 deletions config/ui-extensions/istios/form
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
name: config.numTrustedProxies
value:
type: number
- path: config.trustDomain
name: config.trustDomain
simple: true
description: description.trustDomain
value:
type: string
- path: compatibilityMode
simple: true
name: compatibilityMode
Expand Down
2 changes: 2 additions & 0 deletions config/ui-extensions/istios/translations
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
en:
compatibilityMode: Compatibility Mode
config.numTrustedProxies: Number of trusted proxies
config.trustDomain: Trust Domain

config.authorizers: Authorizers
config.authorizers.name: Name
Expand Down Expand Up @@ -38,4 +39,5 @@ en:
description.requests.cpu: Total CPU requests of all Pods that are in a non-terminal state must not exceed this value
description.requests.memory: Total memory requests of all Pods that are in a non-terminal state must not exceed this value
description.externalTrafficPolicy: Specifies externalTrafficPolicy for the Istio Ingress Gateway Service
description.trustDomain: Defines the trust domain for the Istio service mesh. Change the value only if you have a specific requirement. Change of domain reconfiguring mTLS certificates and causes restart of all workloads in the mesh, this can lead to downtime.
description.compatibilityMode: Sets Istio compatibility version the last minor version.
19 changes: 10 additions & 9 deletions docs/contributor/04-50-istio-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ These metrics help monitor the health and status of Istio installations managed
The operator provides metrics that are defined by the controller-runtime by default, as well as custom metrics specific to Istio CR configurations.
The following custom metrics are available:

| Metric Name | Description |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
| **istio_ext_auth_providers_total** | Specifies the total number of external authorization providers defined in the Istio CR. |
| **istio_ext_auth_timeout_configured_number_total** | Specifies the total number of external authorization providers with timeout configured in the Istio CR. |
| Metric Name | Description |
|------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
| **istio_ext_auth_providers_total** | Specifies the total number of external authorization providers defined in the Istio CR. |
| **istio_ext_auth_timeout_configured_number_total** | Specifies the total number of external authorization providers with timeout configured in the Istio CR. |
| **istio_ext_auth_path_prefix_configured_number_total** | Specifies the total number of external authorization providers with path prefix configured in the Istio CR. |
| **istio_num_trusted_proxies_configured** | Indicates whether **numTrustedProxies** is configured in the Istio CR (`1` for configured, `0` for not configured). |
| **istio_forward_client_cert_details_configured** | Indicates whether **forwardClientCertDetails** is different from the default value of `SANITIZE` (`1` for configured, `0` for not configured). |
| **istio_prometheus_merge_enabled** | Indicates whether Prometheus merge is enabled in the Istio CR (`1` for enabled, `0` for disabled). |
| **istio_compatibility_mode_enabled** | Indicates whether compatibility mode is enabled in the Istio CR (`1` for enabled, `0` for disabled). |
| istio_egress_gateway_used | Indicates whether the egress gateway is used in the Istio CR (`1` for used, `0` for not used). |
| **istio_num_trusted_proxies_configured** | Indicates whether **numTrustedProxies** is configured in the Istio CR (`1` for configured, `0` for not configured). |
| **istio_forward_client_cert_details_configured** | Indicates whether **forwardClientCertDetails** is different from the default value of `SANITIZE` (`1` for configured, `0` for not configured). |
| **istio_trust_domain_configured** | Indicates whether **trustedDomain** is configured (`1` for configured, `0` for not configured). |
| **istio_prometheus_merge_enabled** | Indicates whether Prometheus merge is enabled in the Istio CR (`1` for enabled, `0` for disabled). |
| **istio_compatibility_mode_enabled** | Indicates whether compatibility mode is enabled in the Istio CR (`1` for enabled, `0` for disabled). |
| istio_egress_gateway_used | Indicates whether the egress gateway is used in the Istio CR (`1` for used, `0` for not used). |
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Support for Trust Domain Configuration

## Status

Accepted

## Context

In Istio's security model, a trust domain is a fundamental concept that represents the security boundary of a service mesh. It corresponds to the trust root of a system and is used in workload identity certificates (SPIFFE certificates). The trust domain is encoded in the Subject Alternative Name (SAN) field of the X.509 certificates issued to workloads within the mesh.

By default, Istio uses `cluster.local` as the trust domain. However, there are scenarios where users need to customize the trust domain. For example, in multi-cluster deployments, where multiple clusters need to trust each other, a shared trust domain can facilitate seamless service-to-service authentication across cluster boundaries without requiring a complex federation setup.

The trust domain affects:
- The SPIFFE identity format: `spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>`
- Certificate validation and authentication between services
- Authorization policies that reference identities

Currently, the `cluster.local` trust domain is hardcoded in the Istio operator configuration, and users have no way to customize it through the Istio custom resource.

## Decision

We will add support for configuring the trust domain through the Istio custom resource. The implementation will include the following aspects:

1. **Add the trustDomain field**: The field will be added to the **Config** struct in the Istio CR specification with the following properties:
- Type: `string` (optional)
- Pattern validation: must conform to the SPIFFE specification for trust domain names
- Length constraints: 1-255 characters
- Default value: `cluster.local` (when not specified)

2. **Merge the configuration** into the IstioOperator's **trustDomain** field during reconciliation, allowing the user-specified value to override the default.

3. **Validation**: The field will be validated by Kubernetes API server through CRD validation rules to ensure it meets the SPIFFE specification requirements for trust domain names.

4. **Backward compatibility**: If the field is not specified, the existing default behavior (`cluster.local`) will be maintained, ensuring no breaking changes for existing deployments.

5. **Downtime**: During the trust domain change, workloads may experience temporary authentication failures until new certificates are issued and propagated.
4 changes: 3 additions & 1 deletion docs/release-notes/1.24.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@
See [#1710](https://github.com/kyma-project/istio/pull/1710).
- We've added support for **forwardClientCertDetails**.
See [#1715](https://github.com/kyma-project/istio/pull/1715) and [Istio Custom Resource](https://kyma-project.io/external-content/istio/docs/user/04-00-istio-custom-resource.html).
- We've added support for Istio trust domain configuration.
See [#1705](https://github.com/kyma-project/istio/issues/1705)
- Add support for the **KYMA_FIPS_MODE_ENABLED** environment variable, which allows configuring separate Istio FIPS images.
See [#1721](https://github.com/kyma-project/istio/pull/1721).
See [#1721](https://github.com/kyma-project/istio/pull/1721).
1 change: 1 addition & 0 deletions docs/user/04-00-istio-custom-resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Appears in:
| **authorizers** <br /> [Authorizer](#authorizer) array | Defines a list of external authorization providers. | Optional |
| **gatewayExternalTrafficPolicy** <br /> string | Defines the external traffic policy for the Istio Ingress Gateway Service. Valid configurations are `"Local"` or `"Cluster"`. The external traffic policy set to `"Local"` preserves the client IP in the request, but also introduces the risk of unbalanced traffic distribution.<br />WARNING: Switching **externalTrafficPolicy** may result in a temporal increase in request delay. Make sure that this is acceptable. | Enum: [Local Cluster] <br />Optional <br /> |
| **telemetry** <br /> [Telemetry](#telemetry) | Defines the telemetry configuration of Istio. | Optional <br /> |
| **trustDomain** <br /> string | Defines trust domain configuration of Istio. | MaxLength: 255 <br />MinLength: 1 <br />Optional <br />Pattern: `^[a-z0-9]*([a-z0-9-_]*)?(\.[a-z0-9]*([a-z0-9-_]*[a-z0-9]*)?)*$` <br /> |

### EgressGateway

Expand Down
14 changes: 13 additions & 1 deletion internal/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package istiocrmetrics

import (
"github.com/kyma-project/istio/operator/api/v1alpha2"
"github.com/prometheus/client_golang/prometheus"
ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"

"github.com/kyma-project/istio/operator/api/v1alpha2"
)

// IstioCRMetrics holds all the metrics related to the Istio CR.
Expand All @@ -20,6 +21,7 @@ type configMetrics struct {
prometheusMergeEnabled prometheus.Gauge
compatibilityModeEnabled prometheus.Gauge
forwardClientCertDetailsConfigured prometheus.Gauge
trustDomainConfigured prometheus.Gauge
}

type componentMetrics struct {
Expand Down Expand Up @@ -65,6 +67,10 @@ func NewMetrics() *IstioCRMetrics {
Name: "istio_forward_client_cert_details_configured",
Help: "Indicates whether forwardClientCertDetails is configured in the Istio CR (1 for configured, 0 for not configured).",
}),
trustDomainConfigured: prometheus.NewGauge(prometheus.GaugeOpts{
Name: "istio_trust_domain_configured",
Help: "Indicates whether a custom trust domain is configured in the Istio CR (1 for configured, 0 for not configured).",
}),
},
componentMetrics: &componentMetrics{
egressGatewayEnabled: prometheus.NewGauge(prometheus.GaugeOpts{
Expand Down Expand Up @@ -124,6 +130,12 @@ func (m *IstioCRMetrics) UpdateIstioCRMetrics(cr *v1alpha2.Istio) {
m.configMetrics.forwardClientCertDetailsConfigured.Set(0)
}

if cr.Spec.Config.TrustDomain != nil && *cr.Spec.Config.TrustDomain != "" && *cr.Spec.Config.TrustDomain != "cluster.local" {
m.configMetrics.trustDomainConfigured.Set(1)
} else {
m.configMetrics.trustDomainConfigured.Set(0)
}

if cr.Spec.CompatibilityMode {
m.configMetrics.compatibilityModeEnabled.Set(1)
} else {
Expand Down
21 changes: 21 additions & 0 deletions internal/restarter/predicates/ingressgateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func (i RestartPredicate) NewIngressGatewayEvaluator(_ context.Context) (Ingress
NewXForwardClientCert: i.istioCR.Spec.Config.ForwardClientCertDetails,
OldXForwardClientCert: lastAppliedConfig.Config.ForwardClientCertDetails,
},
TrustDomainsRestartEvaluator{
NewTrustDomain: i.istioCR.Spec.Config.TrustDomain,
OldTrustDomain: lastAppliedConfig.Config.TrustDomain,
},
},
}, nil
}
Expand Down Expand Up @@ -71,6 +75,23 @@ func (i NumTrustedProxiesRestartEvaluator) RequiresIngressGatewayRestart() bool
return false
}

type TrustDomainsRestartEvaluator struct {
NewTrustDomain *string
OldTrustDomain *string
}

func (i TrustDomainsRestartEvaluator) RequiresIngressGatewayRestart() bool {
isNewNotNil := i.NewTrustDomain != nil
isOldNotNil := i.OldTrustDomain != nil
if isNewNotNil && isOldNotNil && *i.NewTrustDomain != *i.OldTrustDomain {
return true
}
if isNewNotNil != isOldNotNil {
return true
}
return false
}

func (i XForwardClientCertRestartEvaluator) RequiresIngressGatewayRestart() bool {
isNewNotNil := i.NewXForwardClientCert != nil
isOldNotNil := i.OldXForwardClientCert != nil
Expand Down
Loading
Loading