Skip to content

feat: integrate with cluster TLS security profile - #140

Merged
mprahl merged 2 commits into
opendatahub-io:mainfrom
ugiordan:RHOAIENG-61072-tls-profile
Jun 29, 2026
Merged

mprahl merged 2 commits into
opendatahub-io:mainfrom
ugiordan:RHOAIENG-61072-tls-profile

Conversation

@ugiordan

@ugiordan ugiordan commented Jun 10, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Integrate with the cluster-wide TLS security profile from apiservers.config.openshift.io/cluster
  • Uses controller-runtime-common/pkg/tls to fetch the profile at startup and apply it to metrics server TLSOpts
  • Registers SecurityProfileWatcher to restart on profile or adherence policy changes
  • Adds RBAC for config.openshift.io/apiservers (get/list/watch)
  • Sets NextProtos explicitly for ALPN compliance
  • Gracefully falls back to defaults in non-OpenShift environments

Motivation

RHOAIENG-61072

OCP 5.0 (GA October 2026) requires all components to honor the centralized TLS profile. This is a release blocker (OCPSTRAT-2611). Components that do not comply receive Critical bugs.

Reference: OCP TLS Implementation Reference

Upstream example: openshift/cluster-machine-approver #286

Changes

  • cmd/main.go: 5-step TLS profile integration (fetch profile, build tls.Config, apply TLSOpts, register watcher, cancellable context)
  • internal/controller/mlflow_controller.go: RBAC marker for apiservers
  • go.mod/go.sum: added controller-runtime-common, controller-runtime upgraded v0.22.4 to v0.23.3

Test plan

  • go build ./... passes
  • Existing unit tests pass (no regressions)
  • Deploy on OpenShift cluster with Intermediate profile, verify TLS endpoints
  • Change profile to Modern, verify pod restarts and negotiates TLS 1.3
  • Verify NextProtos with openssl s_client -alpn

Summary by CodeRabbit

  • New Features

    • OpenShift TLS security profile support with automatic controller restart when the TLS profile or adherence changes.
    • Manager lifecycle updated to stop/start cleanly in response to TLS profile updates.
    • Metrics endpoint TLS adjusted to prefer HTTP/1.1.
  • Chores

    • Bumped Go toolchain to 1.25 and refreshed dependencies.
    • Updated container builder image to Go 1.25 toolset.
    • Added RBAC to read OpenShift API server TLS profile.
    • Makefile adjusted to avoid automatic toolchain download when resolving build paths.

@openshift-ci
openshift-ci Bot requested review from kramaranya and mprahl June 10, 2026 09:08
@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign mprahl for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR consumes OpenShift API server TLSProfile (and optional adherence) to build tls.Options for the operator metrics server (always forcing NextProtos=http/1.1), moves ctrl.GetConfigOrDie() earlier for reuse, replaces the local HTTP/2-disable helper, registers a SecurityProfileWatcher that cancels the manager context on profile/adherence changes so mgr.Start(ctx) exits, adds RBAC for apiservers.config.openshift.io, bumps go.mod dependencies and Go toolchain, updates Makefile GOBIN evaluation, and updates the Docker builder image to Go toolset 1.25.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Security observations

  • Supply chain: multiple go.mod bumps and builder image change increase supply-chain attack surface; audit for known CVEs and unmaintained modules (CWE-1104).
  • RBAC scope: new get/list/watch on apiservers.config.openshift.io expands privileges; verify least-privilege boundaries (CWE-862).
  • TLS handling: operator consumes cluster TLSProfile/adherence — confirm proper CA usage, certificate validation, and disable weak ciphers/protocols (CWE-295).
  • Restart-on-change: watcher cancels manager context to restart process; ensure controllers and webhooks drain and handle in-flight work to avoid state corruption or resource leaks (CWE-404).
  • Lint suppression: added //nolint:staticcheck on Server-Side Apply Patch; verify suppressed warnings are not masking correctness or security issues (CWE-754).
🚥 Pre-merge checks | ✅ 10
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Contribution Quality And Spam Detection ✅ Passed Multi-file TLS feature PR with proper error handling, Jira ticket, test plan. No spam signals found; fails to meet 2+ signal threshold for low-quality classification.
No Hardcoded Secrets ✅ Passed No hardcoded secrets found. All code changes contain legitimate configuration, TLS logic, dependencies, and RBAC rules without credentials.
No Weak Cryptography ✅ Passed No weak cryptographic primitives, custom crypto implementations, or non-constant-time secret comparisons. Uses safe Go stdlib crypto/tls and upstream OpenShift controller-runtime-common.
No Injection Vectors ✅ Passed No injection vectors (CWE-89, CWE-78, CWE-94, CWE-502, CWE-79) detected in PR modifications. Flag inputs are passed directly to APIs, not concatenated in commands or queries.
No Privileged Containers ✅ Passed No privileged containers found. All Pod/container specs enforce runAsNonRoot, allowPrivilegeEscalation: false, drop ALL capabilities, and read-only root filesystems.
No Sensitive Data In Logs ✅ Passed No passwords, tokens, API keys, PII, or sensitive credentials exposed in logs. Only status messages, public cipher names, and command-line flag file paths logged.
Title check ✅ Passed The title 'feat: integrate with cluster TLS security profile' accurately and concisely summarizes the primary changeset: TLS security profile integration from OpenShift cluster configuration into the mlflow-operator.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands.

@ugiordan
ugiordan force-pushed the RHOAIENG-61072-tls-profile branch from 9520138 to 390db04 Compare June 10, 2026 09:14

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/main.go`:
- Around line 126-139: The bootstrap reads use context.Background() which can
block indefinitely; hoist rootCtx := ctrl.SetupSignalHandler() before these
fetches and replace Background with derived contexts that have timeouts (e.g.,
ctx, cancel := context.WithTimeout(rootCtx, <reasonableDuration>); defer
cancel()) when calling tlspkg.FetchAPIServerTLSProfile and
tlspkg.FetchAPIServerTLSAdherencePolicy (which populate tlsProfileFetched,
tlsAdherenceFetched and feed tlsConfigFn / unsupported handling); ensure you
pass the timeout-backed ctx and cancel appropriately so the process fails fast
instead of hanging on bootstrapClient reads.
- Around line 126-141: The current code treats any error from
tlspkg.FetchAPIServerTLSProfile and tlspkg.FetchAPIServerTLSAdherencePolicy as
benign and continues with defaults; change this to "fail closed": only treat
explicit API/resource-absent errors as recoverable (e.g.,
apierrors.IsNotFound(err) or meta.IsNoMatchError(err)); for all other errors log
them with setupLog.Error (include the error) and abort startup (return non-nil
error from main or call os.Exit(1)). Update the blocks around
FetchAPIServerTLSProfile / tlsProfileFetched and
FetchAPIServerTLSAdherencePolicy / tlsAdherenceFetched so
tlsProfileFetched/tlsAdherenceFetched are set only on success and
non-recoverable errors cause process termination while recoverable
IsNotFound/IsNoMatch cases fall back to defaults.

In `@go.mod`:
- Around line 11-13: The go.mod currently pins modules using pseudo-versions
which weakens provenance; replace the pseudo-versions for
github.com/opendatahub-io/operator-chaos, github.com/openshift/api, and
github.com/openshift/controller-runtime-common with their appropriate tagged
releases (or an approved, audited tag/announced release) instead of the
v0.0.0-YYYYMMDD... pseudo-versions: update the require entries for these module
paths to the correct semantic version tags (or verified release commit hashes)
and run `go get`/`go mod tidy` to refresh go.sum so the module graph uses the
tagged releases.
- Line 3: Update the Go toolchain version in the module directive to a patched
1.25.x release to avoid known security issues: change the go directive in go.mod
from "go 1.25.0" to a patched version such as "go 1.25.11" so CI (which reads
go.mod) will use the fixed toolchain; after updating, run go mod tidy and your
CI build to verify no further version conflicts, and review any pseudo-versioned
dependencies (operator-chaos / OpenShift/k8s) for resolved secure releases
before merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ab6ba34c-6a43-4dc3-a36a-58754f6a959a

📥 Commits

Reviewing files that changed from the base of the PR and between ec59b7c and 9520138.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (3)
  • cmd/main.go
  • go.mod
  • internal/controller/mlflow_controller.go

Comment thread cmd/main.go Outdated
Comment thread cmd/main.go Outdated
Comment thread go.mod Outdated
Comment thread go.mod Outdated
@ugiordan
ugiordan force-pushed the RHOAIENG-61072-tls-profile branch 5 times, most recently from 3bdb8c0 to 85eca00 Compare June 10, 2026 09:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
go.mod (2)

3-3: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Go 1.25.0 remains obsolete; CVE-2026-39825 & CVE-2026-39819 still unpatched.

This was flagged in a prior review but the toolchain directive still pins go 1.25.0 instead of a patched release (e.g., go 1.25.11). CI will continue to use the vulnerable toolchain version.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@go.mod` at line 3, The go.mod toolchain is pinned to the vulnerable string
"go 1.25.0"; update that directive to a patched release (for example change "go
1.25.0" -> "go 1.25.11"), then run go mod tidy to refresh module files and
ensure CI/toolchain configuration (any workflow or Dockerfile that pins the Go
version) is updated to the same patched version so builds no longer use the
vulnerable Go 1.25.0 toolchain.

11-12: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

CWE-829: OpenShift pseudo-versions remain unpinned to tagged releases.

This was flagged in a prior review. openshift/api and openshift/controller-runtime-common still use pseudo-versions instead of semantic version tags, weakening supply-chain auditability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@go.mod` around lines 11 - 12, The go.mod currently pins
github.com/openshift/api and github.com/openshift/controller-runtime-common to
pseudo-versions; update those entries to specific semantic version tags for
supply-chain traceability by editing go.mod (look for the module lines for
github.com/openshift/api and github.com/openshift/controller-runtime-common) and
replace the pseudo-versions with the corresponding released tags (or run `go get
github.com/openshift/api@<tag>` and `go get
github.com/openshift/controller-runtime-common@<tag>` to resolve and update to
the canonical tagged versions), then run `go mod tidy` to ensure the lockfile
and dependencies are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@go.mod`:
- Line 54: The go.mod contains indirect pseudo-versions (github.com/google/pprof
v0.0.0-20260115054156-294ebfa9ad83, github.com/openshift/library-go
v0.0.0-20260213153706-03f1709971c5, and sigs.k8s.io/structured-merge-diff/v6
v6.3.2-0.20260122202528-d9cc6641c482) which weakens supply-chain provenance;
update the sigs.k8s.io/structured-merge-diff/v6 entry to the corresponding
stable v6.x.y tag (e.g., run go get sigs.k8s.io/structured-merge-diff/v6@v6.x.y
and then go mod tidy), and for github.com/google/pprof and
github.com/openshift/library-go either replace each pseudo-version with a
published tagged release if available or add a short rationale comment in the
repository (and a tracking TODO) explaining why the untagged commit is required
and confirming no suitable tag exists, then run go mod tidy to refresh go.sum.

---

Duplicate comments:
In `@go.mod`:
- Line 3: The go.mod toolchain is pinned to the vulnerable string "go 1.25.0";
update that directive to a patched release (for example change "go 1.25.0" ->
"go 1.25.11"), then run go mod tidy to refresh module files and ensure
CI/toolchain configuration (any workflow or Dockerfile that pins the Go version)
is updated to the same patched version so builds no longer use the vulnerable Go
1.25.0 toolchain.
- Around line 11-12: The go.mod currently pins github.com/openshift/api and
github.com/openshift/controller-runtime-common to pseudo-versions; update those
entries to specific semantic version tags for supply-chain traceability by
editing go.mod (look for the module lines for github.com/openshift/api and
github.com/openshift/controller-runtime-common) and replace the pseudo-versions
with the corresponding released tags (or run `go get
github.com/openshift/api@<tag>` and `go get
github.com/openshift/controller-runtime-common@<tag>` to resolve and update to
the canonical tagged versions), then run `go mod tidy` to ensure the lockfile
and dependencies are consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 006d144b-ce98-49e9-93bf-7cea97f93cf3

📥 Commits

Reviewing files that changed from the base of the PR and between 3533ed2 and 5093931.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (5)
  • Dockerfile
  • cmd/main.go
  • config/rbac/role.yaml
  • go.mod
  • internal/controller/mlflow_controller.go
✅ Files skipped from review due to trivial changes (1)
  • Dockerfile
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/controller/mlflow_controller.go
  • config/rbac/role.yaml
  • cmd/main.go

Comment thread go.mod
@ugiordan
ugiordan force-pushed the RHOAIENG-61072-tls-profile branch 3 times, most recently from 31080b9 to 991e555 Compare June 10, 2026 09:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 6-12: The Makefile currently silences all errors from the
`GOTOOLCHAIN=local go env ... 2>/dev/null` calls which can produce a bad or
empty GOBIN (e.g., "/bin") and mask missing/broken Go installations; remove the
`2>/dev/null` redirections so `go env` errors are visible, capture stderr to a
temp logfile if noise is a concern, and add validation after computing GOBIN
(from the `GOTOOLCHAIN=local go env GOBIN`/`GOPATH` branches) to fail fast if
GOBIN is empty or points to unsafe locations like "/" or "/bin" (emit a clear
error message referencing GOBIN and GOTOOLCHAIN and exit non‑zero).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 47e45f3b-36ba-46ec-b54c-c83f6c5e03de

📥 Commits

Reviewing files that changed from the base of the PR and between 5093931 and 991e555.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum, !**/*.sum
📒 Files selected for processing (6)
  • Dockerfile
  • Makefile
  • cmd/main.go
  • config/rbac/role.yaml
  • go.mod
  • internal/controller/mlflow_controller.go
✅ Files skipped from review due to trivial changes (1)
  • Dockerfile
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/main.go
  • go.mod

Comment thread Makefile
Honor the cluster-wide TLS security profile from
apiservers.config.openshift.io/cluster instead of hardcoding TLS
settings. Uses controller-runtime-common/pkg/tls to fetch the profile
at startup, apply it to the metrics server TLSOpts, and watch for
profile changes via SecurityProfileWatcher.

On profile or adherence policy change, the manager context is cancelled
so the pod restarts with the new configuration.

Gracefully falls back to defaults if the APIServer resource is not
available (non-OpenShift environments).

RHOAIENG-61072

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ugo Giordano <ugiordan@redhat.com>
@ugiordan
ugiordan force-pushed the RHOAIENG-61072-tls-profile branch from cfca0e8 to 7cb44fa Compare June 26, 2026 15:44
Keep the nested api module on the same Kubernetes/controller-runtime stack as the root module, and let the metrics e2e accept either HTTP/1.1 or HTTP/2 now that the TLS profile work can negotiate h2.
@mprahl

mprahl commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

/retest

@mprahl
mprahl merged commit 865026c into opendatahub-io:main Jun 29, 2026
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants