diff --git a/charts/acs-central/templates/central-cr.yaml b/charts/acs-central/templates/central-cr.yaml index 6b91dac4..ac56bd89 100644 --- a/charts/acs-central/templates/central-cr.yaml +++ b/charts/acs-central/templates/central-cr.yaml @@ -21,6 +21,16 @@ spec: port: 443 route: enabled: {{ .Values.central.exposure.route.enabled }} + {{- if .Values.central.exposure.route.host }} + host: {{ .Values.central.exposure.route.host }} + {{- end }} + {{- if .Values.central.exposure.route.reencrypt.enabled }} + reencrypt: + enabled: true + {{- if .Values.central.exposure.route.reencrypt.host }} + host: {{ .Values.central.exposure.route.reencrypt.host }} + {{- end }} + {{- end }} {{- if .Values.central.persistence.enabled }} persistence: diff --git a/charts/acs-central/templates/console-link.yaml b/charts/acs-central/templates/console-link.yaml index 3030fa41..01acf02a 100644 --- a/charts/acs-central/templates/console-link.yaml +++ b/charts/acs-central/templates/console-link.yaml @@ -8,7 +8,19 @@ metadata: annotations: argocd.argoproj.io/sync-wave: "46" spec: + {{- if .Values.central.exposure.route.reencrypt.enabled }} + {{- if .Values.central.exposure.route.reencrypt.host }} + href: https://{{ .Values.central.exposure.route.reencrypt.host }} + {{- else }} + href: https://central.{{ .Values.global.localClusterDomain }} + {{- end }} + {{- else }} + {{- if .Values.central.exposure.route.host }} + href: https://{{ .Values.central.exposure.route.host }} + {{- else }} href: https://central-{{ .Release.Namespace }}.{{ .Values.global.localClusterDomain }} + {{- end }} + {{- end }} location: ApplicationMenu text: Advanced Cluster Security applicationMenu: diff --git a/charts/acs-central/templates/jobs/create-auth-provider.yaml b/charts/acs-central/templates/jobs/create-auth-provider.yaml index ae5dc4fb..71626a01 100644 --- a/charts/acs-central/templates/jobs/create-auth-provider.yaml +++ b/charts/acs-central/templates/jobs/create-auth-provider.yaml @@ -86,7 +86,7 @@ spec: exit 0 fi - ACS_CENTRAL_HOSTNAME="$(oc get route central -n stackrox -o jsonpath='{.spec.host}')" + ACS_CENTRAL_HOSTNAME="$(oc get route central-reencrypt -n stackrox -o jsonpath='{.spec.host}' 2>/dev/null || oc get route central -n stackrox -o jsonpath='{.spec.host}')" echo "ACS Central hostname: $ACS_CENTRAL_HOSTNAME" cat > /tmp/oidc-config.json << 'OIDCEOF' diff --git a/charts/acs-central/values.yaml b/charts/acs-central/values.yaml index 9c01ba9d..1d8c965a 100644 --- a/charts/acs-central/values.yaml +++ b/charts/acs-central/values.yaml @@ -73,10 +73,13 @@ central: exposure: route: enabled: true - # Use cluster wildcard certificate + host: "" # Autogenerate if not specified tls: enabled: true termination: passthrough + reencrypt: + enabled: true + host: "" # Autogenerate if not specified loadBalancer: enabled: false @@ -170,8 +173,8 @@ integration: # Container image for the auth provider configuration job # Uses OpenShift CLI tools (curl, oc, jq, etc.) jobImage: - registry: image-registry.openshift-image-registry.svc:5000 - repository: openshift/cli + registry: registry.redhat.io + repository: openshift4/ose-cli-rhel9 tag: latest pullPolicy: IfNotPresent # Service account used by jobs (init bundle, auth provider, htpasswd) diff --git a/docs/acs-deployment.md b/docs/acs-deployment.md index 1d694d0a..7e67ee48 100644 --- a/docs/acs-deployment.md +++ b/docs/acs-deployment.md @@ -48,6 +48,34 @@ The ACS deployment in the Layered Zero Trust pattern is implemented using: - Admission Controller (policy enforcement) - Collector (DaemonSet for runtime monitoring) +## Route and TLS Configuration + +ACS Central exposes two OpenShift routes with different TLS termination modes: + +| Route | TLS Mode | Purpose | +|---|---|---| +| `central` | Passthrough | Sensor/SecuredCluster gRPC communication (mTLS) | +| `central-reencrypt` | Reencrypt | Browser UI access using cluster wildcard certificate | + +The **passthrough route is required** for sensor communication. Sensors use +mutual TLS with certificates from the cluster init bundle, and the RHACS +operator [explicitly states](https://github.com/stackrox/stackrox/blob/master/operator/api/v1alpha1/central_types.go) +that the reencrypt route *"should not be used for sensor communication"* +because the router terminates the sensor's TLS session, breaking mTLS +authentication. + +The **reencrypt route** is enabled by default (`central.exposure.route.reencrypt.enabled: true`) +so that browser users see the cluster's wildcard certificate instead of +Central's self-signed certificate. This works on all platforms: + +- **Cloud (AWS, Azure, GCP)**: wildcard cert is signed by a public CA — no browser warning +- **BareMetal / vSphere**: wildcard cert uses the cluster ingress CA — trusted + if `ztvp-certificates` has injected it via `proxyCA` + +The RHACS operator auto-generates the reencrypt route hostname +(`central-reencrypt-stackrox.apps.`). The ConsoleLink and OIDC auth +provider `uiEndpoint` automatically point to the reencrypt route when enabled. + ## Deployment Workflow ### Phase 1: Operator Installation (Managed by Pattern Framework) diff --git a/values-hub.yaml b/values-hub.yaml index dae08bf8..03ff30e6 100644 --- a/values-hub.yaml +++ b/values-hub.yaml @@ -594,6 +594,8 @@ clusterGroup: # value: gp3-csi # Example for AWS - name: central.exposure.route.enabled value: "true" + - name: central.exposure.route.reencrypt.host + value: "central.{{ $.Values.global.localClusterDomain }}" - name: integration.keycloak.enabled value: "true" - name: integration.keycloak.realm