Skip to content

MCO-2441: MCO-2442: MCO-2443: Support Openshift —> RHEL translation for tlsSecurityProfile options - #6297

Open
isabella-janssen wants to merge 2 commits into
openshift:mainfrom
isabella-janssen:pqc-enablement-poc
Open

MCO-2441: MCO-2442: MCO-2443: Support Openshift —> RHEL translation for tlsSecurityProfile options#6297
isabella-janssen wants to merge 2 commits into
openshift:mainfrom
isabella-janssen:pqc-enablement-poc

Conversation

@isabella-janssen

@isabella-janssen isabella-janssen commented Jul 12, 2026

Copy link
Copy Markdown
Member

- What I did
This adds the main functionality updates needed to support PQC efforts in the MCO. This adds a translation layer between the OCP API's TLSSecurityProfile option to policies understood by the machines in a cluster.

- How to verify it
To verify this, check that each OCP TLSSecurityProfile accurately maps to a correct policy on the machine for clusters based on RHEL9 and RHEL10. Note that TLS 1.0 and 1.1 are not supported on RHEL9 or RHEL10, so those TLS versions and any ciphers restricted to those versions will not be reflected in the machine's policy. On a cluster install, the machine should be adhering to the the standards set by the Intermediate profile. To change between profiles, use commands of the following form:

oc patch apiserver cluster --type merge -p '{"spec":{"tlsSecurityProfile":{"type":"Modern","modern":{}}}}'

Note that FIPS clusters cannot have TLSSecurityProfile options set, so any machines in FIPS clusters should be unaffected if a profile option is set and the machine should appropriately degrade.

- Description for the changelog
MCO-2441: MCO-2442: MCO-2443: Support Openshift —> RHEL translation for tlsSecurityProfile options

Summary by CodeRabbit

  • New Features
    • Added support for configuring node crypto policies from OpenShift TLS security profiles, including optional crypto-policy sub-modules for custom settings.
    • Added new templates to render /etc/crypto-policies/config and (when provided) an OPENSHIFT policy module.
    • Crypto-policy changes are now applied automatically during node configuration updates when crypto-policy files are included.
  • Bug Fixes
    • Improved template rendering/omission behavior for optional crypto-policy sub-modules.
  • Tests
    • Added coverage for crypto-policy generation, template rendering, and crypto-policy application behavior.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 12, 2026
@openshift-ci

openshift-ci Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 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

The change derives Fedora crypto policies from OpenShift TLS profiles, passes them through template rendering into MachineConfig files, and applies changed policies during node updates with a FIPS safeguard. Tests cover policy mapping, rendering, daemon behavior, and related call-site updates.

Changes

Crypto policy lifecycle

Layer / File(s) Summary
TLS profile policy mapping
pkg/controller/common/helpers.go, pkg/controller/common/helpers_test.go
Adds TLS profile-to-crypto-policy mapping, custom sub-policy generation, and table-driven coverage.
Rendered crypto-policy files
pkg/controller/template/render.go, pkg/controller/template/template_controller.go, templates/common/_base/files/*, pkg/controller/template/*_test.go
Carries policy values through rendering and emits the base config and optional OPENSHIFT.pmod file.
Node crypto-policy application
pkg/daemon/update.go, pkg/daemon/update_test.go
Detects crypto-policy changes, validates FIPS compatibility, and invokes update-crypto-policies during updates.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant APIServer
  participant TemplateController
  participant MachineConfig
  participant NodeDaemon
  participant CryptoPolicyTool
  APIServer->>TemplateController: provide TLS security profile
  TemplateController->>MachineConfig: render crypto-policy files
  MachineConfig->>NodeDaemon: deliver changed policy paths
  NodeDaemon->>CryptoPolicyTool: apply validated crypto policy
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Weak-Crypto ❌ Error helpers.go introduces legacy cipher mappings to SHA1 and 3DES (DES-CBC3-SHA, ECDHE-RSA-DES-CBC3-SHA), which trips the weak-crypto check. Remove or gate the legacy SHA1/3DES cipher mappings from the new crypto-policy translation, or document an explicit exception if they must remain.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
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.
Stable And Deterministic Test Names ✅ Passed No Ginkgo-style It/Describe/Context/When titles were added or changed; the new table-driven t.Run names are static strings.
Test Structure And Quality ✅ Passed Touched tests are plain testing.T unit tests; no Ginkgo It/BeforeEach/AfterEach/Eventually code or cluster waits were added.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the touched tests are standard unit tests and don't exercise MicroShift-unsupported APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e specs were added; the changed tests are standard Go unit tests and don’t assume multi-node behavior.
Topology-Aware Scheduling Compatibility ✅ Passed Changes only add crypto-policy rendering/apply logic; no new affinity, nodeSelector, spread, replica, or taint-based scheduling constraints were introduced.
Ote Binary Stdout Contract ✅ Passed PASS: The only process-level entrypoint, TestMain, just parses flags and runs tests; no main/init/suite stdout writes were added, and cmd.Stdout uses are subprocess wiring.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Touched files add only Go unit tests and templates; no new Ginkgo/e2e tests, public hosts, or IPv4-only networking assumptions were introduced.
Container-Privileges ✅ Passed No touched manifest sets privileged/host* or allowPrivilegeEscalation; the new YAMLs are MachineConfig file entries only and contain no securityContext.
No-Sensitive-Data-In-Logs ✅ Passed New logs only mention unknown ciphers or generic crypto-policy actions; no passwords, tokens, PII, or customer data are logged.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: translating tlsSecurityProfile options from OpenShift to RHEL crypto-policy settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 3

🧹 Nitpick comments (5)
pkg/daemon/update.go (2)

2656-2660: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded /etc/crypto-policies/config path limits test isolation.

Unlike fipsFile, which is a package-level var so tests can override it, the crypto-policies config path is a literal string used directly. Extracting it into a package var (mirroring fipsFile) would let tests point at a temp file instead of the real host path, avoiding host-state coupling in TestApplyCryptoPolicy.

🤖 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 `@pkg/daemon/update.go` around lines 2656 - 2660, The crypto-policies config
path is hardcoded, preventing test isolation. Extract the path into a
package-level variable near fipsFile, update the ReadFile call in the
crypto-policy application logic to use that variable, and preserve the existing
default path so TestApplyCryptoPolicy can override it with a temporary file.

2669-2673: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No timeout/cancellation around the update-crypto-policies external call.

runCmdSync("update-crypto-policies") is invoked with no visible context or timeout; if the binary hangs, this stalls the daemon's whole update() flow.

As per path instructions, "context.Context for cancellation and timeouts" for **/*.go.

🤖 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 `@pkg/daemon/update.go` around lines 2669 - 2673, Add context-based
cancellation with an appropriate timeout around the external command in the
crypto-policy update flow, replacing the unbounded runCmdSync call. Update the
relevant helper or call path near the policy application logic to accept and
propagate context.Context, while preserving the existing wrapped error and
successful return behavior.

Source: Path instructions

pkg/controller/template/kubelet_config_dir_test.go (1)

49-49: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Unkeyed RenderConfig{} literals are fragile as the struct grows.

Both call sites now pass 7 positional values (&RenderConfig{&controllerConfig.Spec, ..., "", "", nil}) to account for the new CryptoPolicy/CryptoPolicySubMod fields. Positional literals only verify field count, not field identity — a future field reorder or insertion could silently shift values into the wrong fields without a compile error, unlike keyed literals (as already used at the production call site in template_controller.go).

♻️ Suggested fix
-			cfgs, err := generateTemplateMachineConfigs(&RenderConfig{&controllerConfig.Spec, `{"dummy":"dummy"}`, "dummy", nil, "", "", nil}, templateDir)
+			cfgs, err := generateTemplateMachineConfigs(&RenderConfig{
+				ControllerConfigSpec: &controllerConfig.Spec,
+				PullSecret:           `{"dummy":"dummy"}`,
+				TLSMinVersion:        "dummy",
+				TLSCipherSuites:      nil,
+				CryptoPolicy:         "",
+				CryptoPolicySubMod:   "",
+			}, templateDir)

(Adjust remaining trailing field name to match RenderConfig's actual definition.)

Also applies to: 76-76

🤖 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 `@pkg/controller/template/kubelet_config_dir_test.go` at line 49, Replace the
unkeyed RenderConfig literals at both test call sites with keyed field literals,
explicitly assigning each value to the corresponding RenderConfig fields,
including the trailing CryptoPolicy and CryptoPolicySubMod fields according to
the struct definition. Preserve the existing values and behavior.
pkg/daemon/update_test.go (1)

984-1023: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Non-hermetic assertions in TestApplyCryptoPolicy.

The "triggers update" cases assume the failure comes from the missing update-crypto-policies binary, but the function first reads real /proc/sys/crypto/fips_enabled and /etc/crypto-policies/config from the host. On a FIPS-enabled CI runner, the error would instead originate from the FIPS guard (or a file-read failure) rather than the missing binary — the test still passes (since it only asserts expectError) but for a different reason than documented, and behavior is host-dependent. Tying this to injectable paths (see suggestion in update.go) and asserting on error content would make the test deterministic and actually validate the intended code path.

🤖 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 `@pkg/daemon/update_test.go` around lines 984 - 1023, The TestApplyCryptoPolicy
cases should avoid reading host-specific /proc and crypto-policy files and
should verify the intended missing-binary path deterministically. Update
applyCryptoPolicy and its callers to use injectable paths or dependencies,
configure those in TestApplyCryptoPolicy for a controlled non-FIPS environment,
and assert the returned error content identifies the unavailable
update-crypto-policies command rather than only checking that an error occurred.
pkg/controller/template/render_test.go (1)

85-85: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider keyed struct literals for RenderConfig in tests.

These call sites use positional literals for a 7-field struct where several fields share type string/[]string. go vet's unkeyed-composite-literal check doesn't fire here since the literal is same-package, so a future field reorder could silently swap values without a compile error. This PR already had to touch every call site to insert 2 new positional args.

♻️ Example fix for one call site
-			got, err := renderTemplate(RenderConfig{&config.Spec, `{"dummy":"dummy"}`, "dummy", nil, "", "", nil}, name, dummyTemplate)
+			got, err := renderTemplate(RenderConfig{
+				ControllerConfigSpec: &config.Spec,
+				PullSecret:           `{"dummy":"dummy"}`,
+				TLSMinVersion:        "dummy",
+			}, name, dummyTemplate)

Also applies to: 146-146, 240-240, 247-247, 258-258, 380-380, 513-513

🤖 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 `@pkg/controller/template/render_test.go` at line 85, Replace the positional
RenderConfig literals in all listed renderTemplate test call sites with keyed
field literals, using the actual RenderConfig field names. Preserve each call’s
existing values while making every argument explicit so future field additions
or reordering cannot silently change behavior.
🤖 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 `@pkg/controller/common/helpers.go`:
- Around line 1276-1297: Update GetCryptoPolicyFromTLSProfile for
TLSProfileModernType to use the documented TLS 1.3-only crypto-policy module
syntax that removes inherited older protocols, replacing the current
protocol@TLS = TLS1.3+ value. Leave the other profile mappings unchanged.

In `@pkg/daemon/update.go`:
- Around line 2649-2667: Update the FIPS policy validation inside processFips to
accept the exact policy “FIPS” and subpolicies beginning with “FIPS:”, while
continuing to reject all other values. Preserve the existing file-read and error
propagation behavior.
- Around line 1220-1223: Update the update() flow around applyCryptoPolicy so
failures after the system-wide crypto policy change also restore the previously
active policy, keeping it consistent with the rolled-back configuration file.
Either register rollback handling that reruns update-crypto-policies with the
prior policy or move applyCryptoPolicy after all fallible update steps, while
preserving existing error propagation.

---

Nitpick comments:
In `@pkg/controller/template/kubelet_config_dir_test.go`:
- Line 49: Replace the unkeyed RenderConfig literals at both test call sites
with keyed field literals, explicitly assigning each value to the corresponding
RenderConfig fields, including the trailing CryptoPolicy and CryptoPolicySubMod
fields according to the struct definition. Preserve the existing values and
behavior.

In `@pkg/controller/template/render_test.go`:
- Line 85: Replace the positional RenderConfig literals in all listed
renderTemplate test call sites with keyed field literals, using the actual
RenderConfig field names. Preserve each call’s existing values while making
every argument explicit so future field additions or reordering cannot silently
change behavior.

In `@pkg/daemon/update_test.go`:
- Around line 984-1023: The TestApplyCryptoPolicy cases should avoid reading
host-specific /proc and crypto-policy files and should verify the intended
missing-binary path deterministically. Update applyCryptoPolicy and its callers
to use injectable paths or dependencies, configure those in
TestApplyCryptoPolicy for a controlled non-FIPS environment, and assert the
returned error content identifies the unavailable update-crypto-policies command
rather than only checking that an error occurred.

In `@pkg/daemon/update.go`:
- Around line 2656-2660: The crypto-policies config path is hardcoded,
preventing test isolation. Extract the path into a package-level variable near
fipsFile, update the ReadFile call in the crypto-policy application logic to use
that variable, and preserve the existing default path so TestApplyCryptoPolicy
can override it with a temporary file.
- Around line 2669-2673: Add context-based cancellation with an appropriate
timeout around the external command in the crypto-policy update flow, replacing
the unbounded runCmdSync call. Update the relevant helper or call path near the
policy application logic to accept and propagate context.Context, while
preserving the existing wrapped error and successful return behavior.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d46eccc3-835c-4337-a414-4e9c223b5255

📥 Commits

Reviewing files that changed from the base of the PR and between 4d59cd4 and 268846f.

📒 Files selected for processing (10)
  • pkg/controller/common/helpers.go
  • pkg/controller/common/helpers_test.go
  • pkg/controller/template/kubelet_config_dir_test.go
  • pkg/controller/template/render.go
  • pkg/controller/template/render_test.go
  • pkg/controller/template/template_controller.go
  • pkg/daemon/update.go
  • pkg/daemon/update_test.go
  • templates/common/_base/files/etc-crypto-policies-config.yaml
  • templates/common/_base/files/etc-crypto-policies-modules-tls13only-pmod.yaml

Comment thread pkg/controller/common/helpers.go
Comment thread pkg/daemon/update.go Outdated
Comment thread pkg/daemon/update.go Outdated

@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 `@pkg/controller/common/helpers.go`:
- Around line 1301-1321: Update the cipher-suite mapping and its consuming
validation flow around the OpenSSL-to-node crypto-policy translation to reject
deprecated DES-CBC3/SHA1 suites, or emit the established warning and prevent
them from enabling policy entries. Apply this to both DES-CBC3-SHA and
ECDHE-RSA-DES-CBC3-SHA before they become cipher@TLS/mac@TLS values, while
preserving supported suite mappings.
🪄 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: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0b0b6827-58d0-417d-8ef5-d431b486eafe

📥 Commits

Reviewing files that changed from the base of the PR and between ddbf055 and 7ef81b8.

📒 Files selected for processing (4)
  • pkg/controller/common/helpers.go
  • pkg/controller/common/helpers_test.go
  • pkg/controller/template/render_test.go
  • templates/common/_base/files/etc-crypto-policies-modules-openshift-pmod.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/controller/template/render_test.go
  • pkg/controller/common/helpers_test.go

Comment thread pkg/controller/common/helpers.go Outdated
Comment thread pkg/daemon/update_test.go
// Stub out a test directory structure -- we need to create /etc so createOrigFile can use it
etcDir := filepath.Join(testDir, "etc")
err := os.MkdirAll(etcDir, 0755)
err := os.MkdirAll(etcDir, 0o755)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: The only true change in this file is the addition of TestApplyCryptoPolicy. The other changes are just the result of formatting this document.

@isabella-janssen

Copy link
Copy Markdown
Member Author

/test unit

Comment thread pkg/daemon/update.go
return nil
}

if err := processFips(func(nodeFIPS bool) error {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: FIPS check here was inspired by the checkFIPS function at

// checkFIPS verifies the state of FIPS on the system before an update.
// Our new thought around this is that really FIPS should be a "day 1"
// operation, and we don't want to make it editable after the fact.
// See also https://github.com/openshift/installer/pull/2594
// Anyone who wants to force this can change the MC flag, then
// `oc debug node` and run the disable command by hand, then reboot.
// If we detect that FIPS has been changed, we reject the update.
func checkFIPS(current, desired *mcfgv1.MachineConfig) error {
return processFips(func(nodeFIPS bool) error {
if desired.Spec.FIPS == nodeFIPS {
if desired.Spec.FIPS {
klog.Infof("FIPS is configured and enabled")
}
// Check if FIPS on the system is at the desired setting
current.Spec.FIPS = nodeFIPS
return nil
}
return fmt.Errorf("detected change to FIPS flag; refusing to modify FIPS on a running cluster")
})
}

FileEmbedded1: ign3types.FileEmbedded1{Contents: ign3types.Resource{Source: &testfiledata}, Mode: &mode}}
tempFileOverwriteFalse := ign3types.File{Node: ign3types.Node{Path: "/etc/testfileconfig2", Overwrite: boolToPtr(false)},
FileEmbedded1: ign3types.FileEmbedded1{Contents: ign3types.Resource{Source: &testfiledata}, Mode: &mode}}
tempFileNoDefault := ign3types.File{

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: It looks like there are a lot of changes in this file, but that is because the formatting was fixed. The only true change is the addition of the TestGetCryptoPolicyFromTLSProfile test.

Comment on lines +1283 to +1288
// opensslCipherInfo maps OpenSSL cipher suite names to their decomposed
// Fedora crypto-policy components. The source of truth for which OpenSSL
// cipher names exist is library-go's openSSLToIANACiphersMap in
// github.com/openshift/library-go/pkg/crypto/crypto.go — this table must
// stay in sync with it.
var opensslCipherInfo = map[string]cipherComponents{

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: There is a plan to automate keeping this list up to date in https://redhat.atlassian.net/browse/MCO-2444.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The automation for this and the other automation comment seems like it could be pretty interesting!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was thinking about this one. Could us use a go generator to inject them at build time instead of maintaing a job?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think that's a fair option, but I think then we'd need some helpers to automatically split the cipher into the policy components. Maybe I can schedule a meeting for us to chat about options here?

// tlsGroupToCryptoPolicy maps OpenShift TLSGroup enum values to Fedora
// crypto-policy group names. The canonical names are in the .pol files at
// https://gitlab.com/redhat-crypto/fedora-crypto-policies/-/tree/master/policies
var tlsGroupToCryptoPolicy = map[configv1.TLSGroup]string{

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note to reviewer: There is a plan to automate keeping this list up to date in https://redhat.atlassian.net/browse/MCO-2445.

Comment thread pkg/daemon/on_disk_validation.go Outdated
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 21, 2026
@isabella-janssen
isabella-janssen force-pushed the pqc-enablement-poc branch 4 times, most recently from 5b9ac89 to 5c8e2d2 Compare July 21, 2026 13:05
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 21, 2026
@isabella-janssen isabella-janssen changed the title poc for PQC work; default --> modern promotion MCO-2441: MCO-2442: MCO-2443: Support Openshift —> RHEL translation for tlsSecurityProfile options Jul 21, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 21, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@isabella-janssen: This pull request references MCO-2441 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

- What I did
This adds the main functionality updates needed to support PQC efforts in the MCO. This adds a translation layer between the OCP API's TLSSecurityProfile option to policies understood by the machines in a cluster.

- How to verify it
To verify this, check that each OCP TLSSecurityProfile accurately maps to a correct policy on the machine for clusters based on RHEL9 and RHEL10. Note that TLS 1.0 and 1.1 are not supported on RHEL9 or RHEL10, so those TLS versions and any ciphers restricted to those versions will not be reflected in the machine's policy. On a cluster install, the machine should be adhering to the the standards set by the Intermediate profile. To change between profiles, use commands of the following form:

oc patch apiserver cluster --type merge -p '{"spec":{"tlsSecurityProfile":{"type":"Modern","modern":{}}}}'

Note that FIPS clusters cannot have TLSSecurityProfile options set, so any machines in FIPS clusters should be unaffected if a profile option is set and the machine should appropriately degrade.

- Description for the changelog
MCO-2441: MCO-2442: MCO-2443: Support Openshift —> RHEL translation for tlsSecurityProfile options

Summary by CodeRabbit

  • New Features
  • Added support for configuring node crypto policies from OpenShift TLS security profiles, including optional crypto-policy sub-modules for custom settings.
  • Added new templates to render /etc/crypto-policies/config and (when provided) an OPENSHIFT policy module.
  • Crypto-policy changes are now applied automatically during node configuration updates when crypto-policy files are included.
  • Bug Fixes
  • Improved template rendering/omission behavior for optional crypto-policy sub-modules.
  • Tests
  • Added coverage for crypto-policy generation, template rendering, and crypto-policy application behavior.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@isabella-janssen
isabella-janssen marked this pull request as ready for review July 21, 2026 13:10
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 21, 2026
@isabella-janssen

Copy link
Copy Markdown
Member Author

/pipeline required

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-upgrade
/test e2e-gcp-op-ocl-part1
/test e2e-gcp-op-ocl-part2
/test e2e-gcp-op-part1
/test e2e-gcp-op-part2
/test e2e-gcp-op-single-node
/test e2e-hypershift

@isabella-janssen

Copy link
Copy Markdown
Member Author

/test unit

@isabella-janssen

Copy link
Copy Markdown
Member Author

/test e2e-gcp-op-ocl-part1

@angelcerveraroldan angelcerveraroldan 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.

Overall looks good to me! Just two questions.

Comment thread pkg/controller/common/helpers.go Outdated
Comment thread pkg/controller/common/helpers.go Outdated
… between OCP `TLSSecurityProfile` opinions and machine understandable policies
@isabella-janssen

Copy link
Copy Markdown
Member Author

/test unit

@pablintino pablintino left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It makes sense to me. Waiting to hear what the crypto team has in mind.
Have we planned the testing side? (I'm sure you have, but I'm not sure what's the plan)

Comment on lines +1283 to +1288
// opensslCipherInfo maps OpenSSL cipher suite names to their decomposed
// Fedora crypto-policy components. The source of truth for which OpenSSL
// cipher names exist is library-go's openSSLToIANACiphersMap in
// github.com/openshift/library-go/pkg/crypto/crypto.go — this table must
// stay in sync with it.
var opensslCipherInfo = map[string]cipherComponents{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was thinking about this one. Could us use a go generator to inject them at build time instead of maintaing a job?

configv1.VersionTLS10: {"TLS1.0", "TLS1.1", "DTLS1.0"},
configv1.VersionTLS11: {"TLS1.0", "TLS1.1", "DTLS1.0"},
configv1.VersionTLS12: {"TLS1.0", "TLS1.1", "DTLS1.0"},
configv1.VersionTLS13: {"TLS1.0", "TLS1.1", "TLS1.2", "DTLS1.0", "DTLS1.2"},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ack: Seems fine to have DTLS1.2 as discussed to allow DTLS1.3 to show up if added in Fedora.

@angelcerveraroldan

angelcerveraroldan commented Jul 28, 2026

Copy link
Copy Markdown

Have we planned the testing side?

@pablintino I am working on the testing at the moment - the idea is to run a subset of all the CoreOS tests with these policies enabled. So this should test that libraries that use backends such as openssl still pass all our tests with their modified configs.

This would mean no testing for Custom, but I think that is fine, since Custom has a big "danger" warning attached to it :D

@cheesesashimi cheesesashimi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall, this looks good! My feedback is non-blocking; just some questions and general thoughts.

return string(profileSpec.MinTLSVersion), crypto.OpenSSLToIANACipherSuites(profileSpec.Ciphers)
}

// cipherComponents holds the Fedora crypto-policy component names that an

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

suggestion (non-blocking): To keep the contents of this directory more organized, let's put this and the associated tests into a separate file called crypto.go or cryptopolicy.go / crypto_test.go or cryptopolicy_test.go, respectively.

Comment on lines +1283 to +1288
// opensslCipherInfo maps OpenSSL cipher suite names to their decomposed
// Fedora crypto-policy components. The source of truth for which OpenSSL
// cipher names exist is library-go's openSSLToIANACiphersMap in
// github.com/openshift/library-go/pkg/crypto/crypto.go — this table must
// stay in sync with it.
var opensslCipherInfo = map[string]cipherComponents{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The automation for this and the other automation comment seems like it could be pretty interesting!

macSet[info.mac] = struct{}{}
}

var lines []string

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thought (non-blocking): Whenever I construct a multi-line string like this, I like to use the strings.Builder object in the stdlib. My reasoning is because it allows me to use the fmt.Fprint(), fmt.Fprintf(), and fmt.Fprintln() functions along with format directives in a clear way.

Just to be clear: I'm not asking you to change this, I'm just pointing it out for the future 😄.

if err := processFips(func(nodeFIPS bool) error {
if nodeFIPS {
result.Insert(
"/etc/crypto-policies/config",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

question (non-blocking): Would it make sense to make /etc/crypto-policies/config / /etc/crypto-policies/policies/modules/OPENSHIFT.pmod constants?

@cheesesashimi

Copy link
Copy Markdown
Member

/lgtm
/approve
/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 28, 2026
@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 28, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-ovn
/test e2e-aws-ovn-upgrade
/test e2e-gcp-op-ocl-part1
/test e2e-gcp-op-ocl-part2
/test e2e-gcp-op-part1
/test e2e-gcp-op-part2
/test e2e-gcp-op-single-node
/test e2e-hypershift

@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cheesesashimi, isabella-janssen

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

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [cheesesashimi,isabella-janssen]

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

@openshift-ci

openshift-ci Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@isabella-janssen: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants