From 53091fbd62e0742eeb54ad5129a0f7c0b5ac4773 Mon Sep 17 00:00:00 2001 From: akhil nittala Date: Thu, 8 Oct 2026 13:23:04 +0530 Subject: [PATCH 1/4] feat(tls): configure TLS curve preferences for gitops-plugin Signed-off-by: akhil nittala --- argocd-operator/pkg/tlsprofile/profile.go | 2 + cmd/main.go | 4 ++ config/manager/kustomization.yaml | 3 +- controllers/consoleplugin.go | 32 ++++++++++ controllers/consoleplugin_test.go | 75 +++++++++++++++++++++++ go.mod | 1 + go.sum | 2 + 7 files changed, 118 insertions(+), 1 deletion(-) diff --git a/argocd-operator/pkg/tlsprofile/profile.go b/argocd-operator/pkg/tlsprofile/profile.go index 6b83c09b2fe..71d50b676a7 100644 --- a/argocd-operator/pkg/tlsprofile/profile.go +++ b/argocd-operator/pkg/tlsprofile/profile.go @@ -8,4 +8,6 @@ type TLSConfigProfile struct { MinVersion configv1.TLSProtocolVersion // Ciphers specifies the list of supported TLS cipher suites in cluster. Ciphers []string + // CurvePreferences specifies the list of supported TLS curve preferences in cluster. + CurvePreferences []string } diff --git a/cmd/main.go b/cmd/main.go index a4a8a72bdce..6e10c3a15f5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -51,6 +51,7 @@ import ( operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/samber/lo" corev1 "k8s.io/api/core/v1" crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" @@ -382,6 +383,9 @@ func main() { DisableClusterTLSProfile: disableClusterTLSProfile, MinVersion: profile.MinTLSVersion, Ciphers: profile.Ciphers, + CurvePreferences: lo.Map(profile.Groups, func(group configv1.TLSGroup, _ int) string { + return string(group) + }), }, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Argo CD") diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index c7ac940f7d1..2df5e5f30be 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -12,4 +12,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: quay.io/redhat-developer/gitops-operator + newName: quay.io/nittalaakhil/openshift-gitops-operator + newTag: v5.0.0 diff --git a/controllers/consoleplugin.go b/controllers/consoleplugin.go index aab97f443a0..bac312c146b 100644 --- a/controllers/consoleplugin.go +++ b/controllers/consoleplugin.go @@ -13,6 +13,7 @@ import ( argocommon "github.com/argoproj-labs/gitops-operator/argocd-operator/common" argocdutil "github.com/argoproj-labs/gitops-operator/argocd-operator/controllers/argoutil" + configv1 "github.com/openshift/api/config/v1" consolev1 "github.com/openshift/api/console/v1" pipelinesv1alpha1 "github.com/redhat-developer/gitops-operator/api/v1alpha1" "github.com/redhat-developer/gitops-operator/controllers/util" @@ -250,6 +251,34 @@ func securityContextForPlugin() *corev1.SecurityContext { } } +// allowedHttpdGroups lists TLS groups supported by OpenSSL via SSLOpenSSLConfCmd Groups. +// OpenShift TLSGroup string values are directly usable as OpenSSL group names (OpenSSL >= 3.5). +var allowedHttpdGroups = map[configv1.TLSGroup]struct{}{ + configv1.TLSGroupX25519: {}, + configv1.TLSGroupSecP256r1: {}, + configv1.TLSGroupSecP384r1: {}, + configv1.TLSGroupSecP521r1: {}, + configv1.TLSGroupX25519MLKEM768: {}, + configv1.TLSGroupSecP256r1MLKEM768: {}, + configv1.TLSGroupSecP384r1MLKEM1024: {}, +} + +// tlsGroupsForHttpd converts OpenShift TLS groups to a colon-separated OpenSSL +// Groups string for Apache's SSLOpenSSLConfCmd directive. Unknown groups are +// filtered out so forward-compatible profile values do not break httpd. +func tlsGroupsForHttpd(groups []configv1.TLSGroup) string { + if len(groups) == 0 { + return "" + } + names := make([]string, 0, len(groups)) + for _, g := range groups { + if _, ok := allowedHttpdGroups[g]; ok { + names = append(names, string(g)) + } + } + return strings.Join(names, ":") +} + // buildHttpdConfig generates httpd.conf with dynamic TLS settings func (r *ReconcileGitopsService) buildHttpdConfig() string { minVersionTLS := string(r.CentralTLSProfile.MinTLSVersion) @@ -275,6 +304,9 @@ ServerRoot "/etc/httpd" if minVersionTLS != "VersionTLS13" && strings.Join(r.CentralTLSProfile.Ciphers, ":") != "" { httpdConfigBase += fmt.Sprintf("\n\tSSLCipherSuite %s", strings.Join(r.CentralTLSProfile.Ciphers, ":")) } + if groups := tlsGroupsForHttpd(r.CentralTLSProfile.Groups); groups != "" { + httpdConfigBase += fmt.Sprintf("\n\tSSLOpenSSLConfCmd Groups %s", groups) + } // Close VirtualHost httpdConfigBase += "\n" return httpdConfigBase diff --git a/controllers/consoleplugin_test.go b/controllers/consoleplugin_test.go index f03a553316f..611414a2252 100644 --- a/controllers/consoleplugin_test.go +++ b/controllers/consoleplugin_test.go @@ -1869,8 +1869,10 @@ func TestBuildHttpdConfig(t *testing.T) { CentralTLSProfile configv1.TLSProfileSpec wantProtocol bool wantCipherSuite bool + wantGroups bool protocol string cipherSuite string + groups string }{ { name: "no TLS version no ciphers", @@ -1880,6 +1882,7 @@ func TestBuildHttpdConfig(t *testing.T) { }, wantProtocol: false, wantCipherSuite: false, + wantGroups: false, }, { name: "TLS 1.2 with cipher suites", @@ -1889,6 +1892,7 @@ func TestBuildHttpdConfig(t *testing.T) { }, wantProtocol: true, wantCipherSuite: true, + wantGroups: false, protocol: "-all +TLSv1.2 +TLSv1.3", cipherSuite: "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256", }, @@ -1900,6 +1904,7 @@ func TestBuildHttpdConfig(t *testing.T) { }, wantProtocol: true, wantCipherSuite: false, + wantGroups: false, protocol: "-all +TLSv1.3", }, { @@ -1910,6 +1915,7 @@ func TestBuildHttpdConfig(t *testing.T) { }, wantProtocol: true, wantCipherSuite: false, + wantGroups: false, protocol: "-all +TLSv1.2 +TLSv1.3", }, { @@ -1920,8 +1926,70 @@ func TestBuildHttpdConfig(t *testing.T) { }, wantProtocol: false, wantCipherSuite: true, + wantGroups: false, cipherSuite: "ECDHE-RSA-AES256-GCM-SHA384", }, + { + name: "TLS groups configure SSLOpenSSLConfCmd Groups", + CentralTLSProfile: configv1.TLSProfileSpec{ + MinTLSVersion: "VersionTLS12", + Groups: []configv1.TLSGroup{ + configv1.TLSGroupX25519MLKEM768, + configv1.TLSGroupX25519, + configv1.TLSGroupSecP256r1, + configv1.TLSGroupSecP384r1, + }, + }, + wantProtocol: true, + wantCipherSuite: false, + wantGroups: true, + protocol: "-all +TLSv1.2 +TLSv1.3", + groups: "X25519MLKEM768:X25519:secp256r1:secp384r1", + }, + { + name: "TLS 1.3 with groups", + CentralTLSProfile: configv1.TLSProfileSpec{ + MinTLSVersion: "VersionTLS13", + Groups: []configv1.TLSGroup{ + configv1.TLSGroupX25519, + configv1.TLSGroupSecP256r1, + }, + }, + wantProtocol: true, + wantCipherSuite: false, + wantGroups: true, + protocol: "-all +TLSv1.3", + groups: "X25519:secp256r1", + }, + { + name: "unknown groups are filtered out", + CentralTLSProfile: configv1.TLSProfileSpec{ + MinTLSVersion: "VersionTLS12", + Groups: []configv1.TLSGroup{ + configv1.TLSGroupX25519, + configv1.TLSGroup("UnknownGroup"), + configv1.TLSGroupSecP384r1, + }, + }, + wantProtocol: true, + wantCipherSuite: false, + wantGroups: true, + protocol: "-all +TLSv1.2 +TLSv1.3", + groups: "X25519:secp384r1", + }, + { + name: "only unknown groups omits SSLOpenSSLConfCmd", + CentralTLSProfile: configv1.TLSProfileSpec{ + MinTLSVersion: "VersionTLS12", + Groups: []configv1.TLSGroup{ + configv1.TLSGroup("UnknownGroup"), + }, + }, + wantProtocol: true, + wantCipherSuite: false, + wantGroups: false, + protocol: "-all +TLSv1.2 +TLSv1.3", + }, } for _, tt := range tests { @@ -1953,6 +2021,13 @@ func TestBuildHttpdConfig(t *testing.T) { } else { assert.Assert(t, !strings.Contains(cfg, "SSLCipherSuite")) } + + // SSLOpenSSLConfCmd Groups + if tt.wantGroups { + assert.Assert(t, cmp.Contains(cfg, "SSLOpenSSLConfCmd Groups "+tt.groups)) + } else { + assert.Assert(t, !strings.Contains(cfg, "SSLOpenSSLConfCmd Groups")) + } }) } } diff --git a/go.mod b/go.mod index 750a70848c0..d84f6b71125 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e github.com/operator-framework/api v0.17.5 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 + github.com/samber/lo v1.53.0 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.28.0 golang.org/x/crypto v0.56.0 diff --git a/go.sum b/go.sum index 45188b83bce..08aec189afd 100644 --- a/go.sum +++ b/go.sum @@ -421,6 +421,8 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= +github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU= From 3cbbe79fae1e63d9d35b4821c93fcf7fa6375984 Mon Sep 17 00:00:00 2001 From: akhil nittala Date: Thu, 8 Oct 2026 13:25:32 +0530 Subject: [PATCH 2/4] feat(tls): configure TLS curve preferences for gitops-plugin Signed-off-by: akhil nittala --- config/manager/kustomization.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 2df5e5f30be..c7ac940f7d1 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -12,5 +12,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: quay.io/nittalaakhil/openshift-gitops-operator - newTag: v5.0.0 + newName: quay.io/redhat-developer/gitops-operator From c51318b3cd2d88af65b8c581a66452bc63aa649a Mon Sep 17 00:00:00 2001 From: akhil nittala Date: Fri, 9 Oct 2026 21:58:45 +0530 Subject: [PATCH 3/4] feat(tls): Configure TLS Curve Preferences Signed-off-by: akhil nittala --- cmd/main.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6e10c3a15f5..a9763514c2e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -51,7 +51,6 @@ import ( operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - "github.com/samber/lo" corev1 "k8s.io/api/core/v1" crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" @@ -372,6 +371,11 @@ func main() { argocdprovisioner.Register(openshift.ReconcilerHook, openshift.BuilderHook) + curvePreferences := make([]string, len(profile.Groups)) + for i, group := range profile.Groups { + curvePreferences[i] = string(group) + } + if err = (&argocdprovisioner.ReconcileArgoCD{ Client: client, Scheme: mgr.GetScheme(), @@ -383,9 +387,7 @@ func main() { DisableClusterTLSProfile: disableClusterTLSProfile, MinVersion: profile.MinTLSVersion, Ciphers: profile.Ciphers, - CurvePreferences: lo.Map(profile.Groups, func(group configv1.TLSGroup, _ int) string { - return string(group) - }), + CurvePreferences: curvePreferences, }, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Argo CD") From e288d20b4803bfb909ccd6e0d52982b7976774b1 Mon Sep 17 00:00:00 2001 From: akhil nittala Date: Fri, 9 Oct 2026 21:59:32 +0530 Subject: [PATCH 4/4] feat(tls): Configure TLS Curve Preferences Signed-off-by: akhil nittala --- go.mod | 1 - go.sum | 2 -- 2 files changed, 3 deletions(-) diff --git a/go.mod b/go.mod index d84f6b71125..750a70848c0 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,6 @@ require ( github.com/openshift/controller-runtime-common v0.0.0-20260428152732-64ee174f5e2e github.com/operator-framework/api v0.17.5 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 - github.com/samber/lo v1.53.0 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.28.0 golang.org/x/crypto v0.56.0 diff --git a/go.sum b/go.sum index 08aec189afd..45188b83bce 100644 --- a/go.sum +++ b/go.sum @@ -421,8 +421,6 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= -github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU=