Skip to content

✨ Add cipher suite support to gRPC server TLS config - #219

Merged
openshift-merge-bot[bot] merged 4 commits into
open-cluster-management-io:mainfrom
zhujian7:feat/grpc-cipher-suites
Apr 2, 2026
Merged

✨ Add cipher suite support to gRPC server TLS config#219
openshift-merge-bot[bot] merged 4 commits into
open-cluster-management-io:mainfrom
zhujian7:feat/grpc-cipher-suites

Conversation

@zhujian7

@zhujian7 zhujian7 commented Mar 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Add a CipherSuites []string field to GRPCServerOptions for configuring TLS cipher suites using IANA names (e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) in YAML/JSON config
  • Validate() parses IANA names into uint16 IDs via the shared pkg/tls.ParseCipherSuites(), returning an error for unrecognized names and logging a warning for insecure suites
  • The parsed IDs are applied to tls.Config.CipherSuites only when non-empty and TLSMinVersion < TLS 1.3 (TLS 1.3 cipher suites are not configurable in Go)
  • ApplyTLSFlags() allows --tls-min-version and --tls-cipher-suites CLI flags to override config file values
  • Refactored TLS version and cipher suite parsing to reuse exported pkg/tls.ParseTLSVersion and pkg/tls.ParseCipherSuites, eliminating duplicated code between pkg/server/grpc and pkg/tls

Related issue(s)

Fixes open-cluster-management-io/ocm#1443

Summary by CodeRabbit

  • New Features

    • Configure cipher suites for the gRPC server and override TLS minimum version and cipher suites via command-line flags.
    • Cipher-suite settings apply for TLS ≤ 1.2; TLS 1.3 behavior is unchanged.
  • Tests

    • Added tests covering parsing, validation, flag overrides, and error cases for TLS versions and cipher suites.
  • Chores

    • Exposed TLS parsing helpers for reuse across configuration paths.

@openshift-ci
openshift-ci Bot requested review from deads2k and qiujian16 March 30, 2026 07:11
@coderabbitai

coderabbitai Bot commented Mar 30, 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

Adds exported TLS parsing helpers, new CipherSuites []string and internal cipherSuiteIDs []uint16 to gRPC options, validates/parses cipher names and TLS version, adds ApplyTLSFlags(minVersion, cipherSuites string) error, and applies cipher IDs to server TLS config only for TLS ≤ 1.2.

Changes

Cohort / File(s) Summary
Options: configuration & CLI
pkg/server/grpc/options.go
Added public CipherSuites []string and internal cipherSuiteIDs []uint16 to GRPCServerOptions; extended Validate() to parse/validate cipher suite names into IDs; added ApplyTLSFlags(minVersion, cipherSuites string) error to override TLS flags and re-validate.
Server TLS behavior
pkg/server/grpc/server.go
When building tls.Config, set CipherSuites from options.cipherSuiteIDs only if non-empty and TLSMinVersion < TLS 1.3; otherwise leave cipher suites unset (preserve TLS 1.3 behavior).
TLS parsing utilities & callers
pkg/tls/config.go, pkg/tls/configmap.go, pkg/tls/tls_test.go
Renamed and exported parsing helpers: parseTLSVersionParseTLSVersion, parseCipherSuitesParseCipherSuites; updated callers (ConfigFromFlags, configmap parsing, tests) to use exported functions with unchanged parsing behavior.
Options tests
pkg/server/grpc/options_test.go
Adjusted test comparisons to ignore unexported fields; added TestApplyTLSFlags and TestApplyTLSFlags_OverridesConfigFile covering parsing, accepted formats, cipher-suite parsing, no-op behavior, overrides, and error cases for unknown TLS versions or cipher names.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

approved, lgtm

Suggested reviewers

  • qiujian16
  • deads2k
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the primary change: adding cipher suite support to gRPC server TLS configuration.
Description check ✅ Passed The PR description comprehensively covers the changes including new CipherSuites field, validation logic, TLS flag application, and refactoring. It follows the template structure with Summary and Related issue(s) sections.
Linked Issues check ✅ Passed The PR addresses the core requirements from issue #1443: exports ParseTLSVersion and ParseCipherSuites functions, implements cipher suite parsing and validation with IANA names, applies parsed IDs to tls.Config conditionally based on TLS version, and supports CLI flag overrides.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: gRPC server cipher suite support, shared TLS parsing refactoring, and necessary test updates. No unrelated modifications are present.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@zhujian7

Copy link
Copy Markdown
Member Author

/hold

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

🧹 Nitpick comments (1)
pkg/server/grpc/options_test.go (1)

177-182: Add explicit CipherSuites validation cases.

Ignoring unexported fields here is fine, but this file still never exercises the new parser. A small table around Validate() for valid names, insecure names, and bad names would keep this security-sensitive change from regressing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options_test.go` around lines 177 - 182, Tests for
GRPCServerOptions are not exercising the new CipherSuites parsing/validation, so
add table-driven cases that call GRPCServerOptions.Validate() and assert
expected outcomes for valid names (accepted), insecure names (rejected or warned
per policy), and malformed names (validation error). Update the test in
options_test.go to include a new subtest table that constructs GRPCServerOptions
with various CipherSuites values, calls opts.Validate(), and checks for no error
for valid lists and specific error presence for insecure/bad names; reference
the GRPCServerOptions struct and its Validate() method and assert on the
returned error or state to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/server/grpc/options.go`:
- Around line 118-136: The cipher-suite parsing currently accepts TLS 1.3-only
suites from tls.CipherSuites() into o.cipherSuiteIDs, which will be ignored by
tls.Config at runtime; update the loop in the function handling o.CipherSuites
(the block that calls tls.CipherSuites(), tls.InsecureCipherSuites(), and
findCipherSuiteID) to inspect the found tls.CipherSuite's SupportedVersions and
either reject or warn when a suite's SupportedVersions contains only TLS 1.3
(i.e., does not include TLS 1.0–1.2), returning an error for invalid configs (or
logging a clear warning for insecure/ignored entries) instead of silently
accepting them so that o.cipherSuiteIDs only contains suites compatible with
non‑TLS1.3 versions.

In `@pkg/server/grpc/server.go`:
- Around line 113-116: The code reads b.options.cipherSuiteIDs without ensuring
options are validated/populated, so callers that construct GRPCServerOptions
programmatically may leave cipherSuiteIDs empty; call
(*GRPCServerOptions).Validate() (or otherwise populate/parse cipher suites)
early in NewGRPCServer or at the start of Run() before this branch and/or ensure
cipherSuiteIDs is computed from the public CipherSuites field when nil; update
the logic around tlsConfig.CipherSuites to use the validated/populated
b.options.cipherSuiteIDs (or parse from b.options.CipherSuites) and only assign
when populated and TLSMinVersion < tls.VersionTLS13 to keep behavior consistent
across construction paths.

---

Nitpick comments:
In `@pkg/server/grpc/options_test.go`:
- Around line 177-182: Tests for GRPCServerOptions are not exercising the new
CipherSuites parsing/validation, so add table-driven cases that call
GRPCServerOptions.Validate() and assert expected outcomes for valid names
(accepted), insecure names (rejected or warned per policy), and malformed names
(validation error). Update the test in options_test.go to include a new subtest
table that constructs GRPCServerOptions with various CipherSuites values, calls
opts.Validate(), and checks for no error for valid lists and specific error
presence for insecure/bad names; reference the GRPCServerOptions struct and its
Validate() method and assert on the returned error or state to prevent
regressions.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3d5c2455-1cdf-4916-aac3-878e0563e0e7

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbb733 and 11a34f8.

📒 Files selected for processing (3)
  • pkg/server/grpc/options.go
  • pkg/server/grpc/options_test.go
  • pkg/server/grpc/server.go

Comment thread pkg/server/grpc/options.go Outdated
Comment thread pkg/server/grpc/server.go

@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 (1)
pkg/server/grpc/options.go (1)

150-157: ⚠️ Potential issue | 🟠 Major

TLS 1.3-only suites still need to be rejected during validation.

Lines 151-157 accept any name returned by tls.CipherSuites(), but that API includes TLS 1.3-only entries via CipherSuite.SupportedVersions, while tls.Config.CipherSuites only governs TLS 1.0–1.2. With Go's current filtering, a config made only of TLS 1.3-only names validates here but, when TLSMinVersion is below TLS 1.3, produces an empty configured TLS 1.2 suite set at runtime. Please gate on SupportedVersions before storing the ID. (pkg.go.dev)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options.go` around lines 150 - 157, The loop over
o.CipherSuites accepts any suite IDs returned by findCipherSuiteID (from the
secure/insecure lists) but must reject TLS 1.3‑only suites because
tls.Config.CipherSuites only applies to TLS 1.0–1.2; update the logic in the
loop that calls findCipherSuiteID to also inspect the corresponding
tls.CipherSuite.SupportedVersions and only append the id if the suite supports
TLS versions <= tls.VersionTLS12 (reject suites whose SupportedVersions are TLS
1.3‑only), keeping the same warning for insecure matches (variables:
o.CipherSuites, findCipherSuiteID, secure, insecure,
tls.CipherSuite.SupportedVersions, tls.Config.CipherSuites).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/server/grpc/options.go`:
- Around line 143-145: The validateCipherSuites method returns early when
o.CipherSuites is empty but does not clear the derived cache o.cipherSuiteIDs,
so subsequent revalidations may reuse stale IDs; modify
GRPCServerOptions.validateCipherSuites to reset o.cipherSuiteIDs (set to nil or
empty) before returning when len(o.CipherSuites) == 0 so the server.go logic
will not apply old cipher suites on revalidation.

---

Duplicate comments:
In `@pkg/server/grpc/options.go`:
- Around line 150-157: The loop over o.CipherSuites accepts any suite IDs
returned by findCipherSuiteID (from the secure/insecure lists) but must reject
TLS 1.3‑only suites because tls.Config.CipherSuites only applies to TLS 1.0–1.2;
update the logic in the loop that calls findCipherSuiteID to also inspect the
corresponding tls.CipherSuite.SupportedVersions and only append the id if the
suite supports TLS versions <= tls.VersionTLS12 (reject suites whose
SupportedVersions are TLS 1.3‑only), keeping the same warning for insecure
matches (variables: o.CipherSuites, findCipherSuiteID, secure, insecure,
tls.CipherSuite.SupportedVersions, tls.Config.CipherSuites).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 77a45f58-24db-4f81-b92b-f3f6d7df38ad

📥 Commits

Reviewing files that changed from the base of the PR and between 11a34f8 and 659a241.

📒 Files selected for processing (2)
  • pkg/server/grpc/options.go
  • pkg/server/grpc/options_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/server/grpc/options_test.go

Comment thread pkg/server/grpc/options.go Outdated
Comment on lines +143 to +145
func (o *GRPCServerOptions) validateCipherSuites() error {
if len(o.CipherSuites) == 0 {
return nil

@coderabbitai coderabbitai Bot Mar 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clear the cached cipher IDs when CipherSuites becomes empty.

Line 144 returns before resetting the derived o.cipherSuiteIDs cache. If this options object is revalidated after CipherSuites is cleared, pkg/server/grpc/server.go will keep applying the old suites.

💡 Proposed fix
 func (o *GRPCServerOptions) validateCipherSuites() error {
 	if len(o.CipherSuites) == 0 {
+		o.cipherSuiteIDs = nil
 		return nil
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (o *GRPCServerOptions) validateCipherSuites() error {
if len(o.CipherSuites) == 0 {
return nil
func (o *GRPCServerOptions) validateCipherSuites() error {
if len(o.CipherSuites) == 0 {
o.cipherSuiteIDs = nil
return nil
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options.go` around lines 143 - 145, The validateCipherSuites
method returns early when o.CipherSuites is empty but does not clear the derived
cache o.cipherSuiteIDs, so subsequent revalidations may reuse stale IDs; modify
GRPCServerOptions.validateCipherSuites to reset o.cipherSuiteIDs (set to nil or
empty) before returning when len(o.CipherSuites) == 0 so the server.go logic
will not apply old cipher suites on revalidation.

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.

CipherSuites is set once at startup (from config file or CLI flags) and never cleared afterward. There is no real scenario where it transitions from non-empty to empty on the same options object, so clearing cipherSuiteIDs here is unnecessary.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@zhujian7, that makes sense — since GRPCServerOptions is configured once at startup and the CipherSuites field is never mutated to an empty value after that point, there's no real revalidation path where stale IDs would be applied. I'll defer to your judgment here.


✏️ Learnings added
Learnt from: zhujian7
Repo: open-cluster-management-io/sdk-go PR: 219
File: pkg/server/grpc/options.go:0-0
Timestamp: 2026-04-01T14:51:02.810Z
Learning: In `pkg/server/grpc/options.go` (open-cluster-management-io/sdk-go), `GRPCServerOptions` (including its `CipherSuites` field) is treated as immutable after startup — it is populated once from a config file or CLI flags and never cleared or mutated afterward. Therefore, clearing the derived `cipherSuiteIDs` cache when `CipherSuites` is empty inside `validateCipherSuites`/`parseCipherSuiteIDs` is unnecessary, as the scenario where `CipherSuites` transitions from non-empty to empty on the same options object does not occur in practice.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: zhujian7
Repo: open-cluster-management-io/sdk-go PR: 218
File: pkg/tls/config.go:35-46
Timestamp: 2026-03-31T03:13:28.938Z
Learning: In `pkg/tls/config.go` (open-cluster-management-io/sdk-go), the `init()` function intentionally includes TLS 1.3-only cipher names (e.g., `TLS_AES_128_GCM_SHA256`, `TLS_CHACHA20_POLY1305_SHA256`, `TLS_AES_256_GCM_SHA384`) in `secureCiphersByName` and `cipherNamesByID`. This is by design: Go's `tls.Config.CipherSuites` silently ignores TLS 1.3-only entries, so users can safely mix TLS 1.3-only and TLS 1.2 cipher names in their config. Filtering them out would cause valid mixed configurations to fail with an "unsupported cipher suite" error.

Add a CipherSuites []string field to GRPCServerOptions for configuring
TLS cipher suites using IANA names (e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256).

Validate() parses the IANA names into uint16 IDs using tls.CipherSuites()
and tls.InsecureCipherSuites(), returning an error for unrecognized names
and logging a warning for insecure suites.

The parsed IDs are applied to tls.Config.CipherSuites when non-empty and
TLSMinVersion is below TLS 1.3 (TLS 1.3 cipher suites are not
configurable in Go).

Signed-off-by: zhujian <jiazhu@redhat.com>
Add ApplyTLSFlags(minVersion, cipherSuites) to GRPCServerOptions so
that --tls-min-version and --tls-cipher-suites flag values from
commonoptions can override TLS settings loaded from the config file.

Refactor validateCipherSuites() out of Validate() so both paths share
the same cipher suite parsing logic. Add parseTLSVersion() for
converting version strings (VersionTLS12, TLSv1.2, etc.) to uint16.

Add tests covering: valid overrides, invalid values, and flag
precedence over config file settings.

Signed-off-by: zhujian <jiazhu@redhat.com>
@zhujian7
zhujian7 force-pushed the feat/grpc-cipher-suites branch from 659a241 to efa1e9c Compare March 31, 2026 06:32
Export ParseTLSVersion and ParseCipherSuites from pkg/tls and use them
in grpc options, eliminating ~30 lines of duplicated parsing code. Also
fix test cases that used TLS 1.3 cipher names not present in
tls.CipherSuites().

Signed-off-by: Jia Zhu <jiazhu@redhat.com>
Signed-off-by: zhujian <jiazhu@redhat.com>

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

♻️ Duplicate comments (1)
pkg/server/grpc/options.go (1)

147-155: ⚠️ Potential issue | 🟠 Major

Reset cached cipher IDs when CipherSuites is empty.

At Line 147, returning early leaves o.cipherSuiteIDs untouched. If options are revalidated after clearing CipherSuites, stale IDs can still be applied later.

💡 Proposed fix
 func (o *GRPCServerOptions) validateCipherSuites() error {
 	if len(o.CipherSuites) == 0 {
+		o.cipherSuiteIDs = nil
 		return nil
 	}
 	cipherString := strings.Join(o.CipherSuites, ",")
 	ids, unsupported := pkgtls.ParseCipherSuites(cipherString)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options.go` around lines 147 - 155, When validating cipher
suites in the options block, clear any previously cached IDs when CipherSuites
is empty to avoid reusing stale values; specifically, in the branch that
currently returns when len(o.CipherSuites) == 0, set o.cipherSuiteIDs = nil
before returning (update the logic around the o.CipherSuites check in the
function that sets o.cipherSuiteIDs).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@pkg/server/grpc/options.go`:
- Around line 147-155: When validating cipher suites in the options block, clear
any previously cached IDs when CipherSuites is empty to avoid reusing stale
values; specifically, in the branch that currently returns when
len(o.CipherSuites) == 0, set o.cipherSuiteIDs = nil before returning (update
the logic around the o.CipherSuites check in the function that sets
o.cipherSuiteIDs).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 76117d58-b4bb-4890-a384-d7bb6cecae26

📥 Commits

Reviewing files that changed from the base of the PR and between 659a241 and efa1e9c.

📒 Files selected for processing (6)
  • pkg/server/grpc/options.go
  • pkg/server/grpc/options_test.go
  • pkg/server/grpc/server.go
  • pkg/tls/config.go
  • pkg/tls/configmap.go
  • pkg/tls/tls_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/server/grpc/server.go

@zhujian7
zhujian7 force-pushed the feat/grpc-cipher-suites branch from efa1e9c to bb0e27b Compare March 31, 2026 06:37

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

♻️ Duplicate comments (1)
pkg/server/grpc/options.go (1)

147-149: ⚠️ Potential issue | 🟡 Minor

Reset derived cipher IDs when CipherSuites is empty.

Line 147 exits without clearing o.cipherSuiteIDs, so a reused options object can keep applying stale cipher IDs after suites are removed.

💡 Proposed fix
func (o *GRPCServerOptions) validateCipherSuites() error {
	if len(o.CipherSuites) == 0 {
+		o.cipherSuiteIDs = nil
		return nil
	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options.go` around lines 147 - 149, The early return when
o.CipherSuites is empty leaves stale derived IDs in o.cipherSuiteIDs; update the
branch in the function handling cipher suites (where o.CipherSuites is checked)
to clear or reset o.cipherSuiteIDs (e.g., set to nil or empty slice) before
returning so a reused options object does not retain old cipher IDs; ensure this
change touches the same method that computes/uses o.cipherSuiteIDs so subsequent
calls reflect the cleared state.
🧹 Nitpick comments (1)
pkg/server/grpc/options_test.go (1)

327-334: Assert cipher suite values (and order), not only counts.

These checks pass even if parsing returns wrong suite content with the same length.

✅ Suggested test tightening
-			if len(tt.expectedCiphers) > 0 {
-				if len(opts.CipherSuites) != len(tt.expectedCiphers) {
-					t.Errorf("expected %d cipher suites, got %d", len(tt.expectedCiphers), len(opts.CipherSuites))
-				}
+			if len(tt.expectedCiphers) > 0 {
+				if diff := cmp.Diff(tt.expectedCiphers, opts.CipherSuites); diff != "" {
+					t.Errorf("cipher suites mismatch (-want +got):\n%s", diff)
+				}
 				if len(opts.cipherSuiteIDs) != len(tt.expectedCiphers) {
 					t.Errorf("expected %d parsed cipher IDs, got %d", len(tt.expectedCiphers), len(opts.cipherSuiteIDs))
 				}
 			}
-	if len(opts.CipherSuites) != 2 {
-		t.Errorf("expected 2 cipher suites, got %d", len(opts.CipherSuites))
-	}
+	expectedCiphers := []string{
+		"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+		"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+	}
+	if diff := cmp.Diff(expectedCiphers, opts.CipherSuites); diff != "" {
+		t.Errorf("cipher suites mismatch (-want +got):\n%s", diff)
+	}

Also applies to: 355-360

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/server/grpc/options_test.go` around lines 327 - 334, The test currently
only checks lengths for opts.CipherSuites and opts.cipherSuiteIDs against
tt.expectedCiphers; change it to assert the actual values and their order by
comparing the slices element-by-element (or using reflect.DeepEqual or a slice
comparison helper) and fail with a clear message showing expected vs actual for
both opts.CipherSuites and opts.cipherSuiteIDs; apply the same stronger
assertions to the other similar block that checks cipher suites in this test so
you verify content and ordering, not just counts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@pkg/server/grpc/options.go`:
- Around line 147-149: The early return when o.CipherSuites is empty leaves
stale derived IDs in o.cipherSuiteIDs; update the branch in the function
handling cipher suites (where o.CipherSuites is checked) to clear or reset
o.cipherSuiteIDs (e.g., set to nil or empty slice) before returning so a reused
options object does not retain old cipher IDs; ensure this change touches the
same method that computes/uses o.cipherSuiteIDs so subsequent calls reflect the
cleared state.

---

Nitpick comments:
In `@pkg/server/grpc/options_test.go`:
- Around line 327-334: The test currently only checks lengths for
opts.CipherSuites and opts.cipherSuiteIDs against tt.expectedCiphers; change it
to assert the actual values and their order by comparing the slices
element-by-element (or using reflect.DeepEqual or a slice comparison helper) and
fail with a clear message showing expected vs actual for both opts.CipherSuites
and opts.cipherSuiteIDs; apply the same stronger assertions to the other similar
block that checks cipher suites in this test so you verify content and ordering,
not just counts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2bfbb900-0880-4e22-ad10-a2fe88e81de8

📥 Commits

Reviewing files that changed from the base of the PR and between efa1e9c and bb0e27b.

📒 Files selected for processing (5)
  • pkg/server/grpc/options.go
  • pkg/server/grpc/options_test.go
  • pkg/tls/config.go
  • pkg/tls/configmap.go
  • pkg/tls/tls_test.go
✅ Files skipped from review due to trivial changes (2)
  • pkg/tls/configmap.go
  • pkg/tls/tls_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/tls/config.go

@zhujian7

zhujian7 commented Apr 1, 2026

Copy link
Copy Markdown
Member Author

/cc @skeeey @qiujian16

@openshift-ci
openshift-ci Bot requested a review from skeeey April 1, 2026 13:16
@@ -18,6 +21,7 @@ type GRPCServerOptions struct {
ClientCAFile string `json:"client_ca_file" yaml:"client_ca_file"`
TLSMinVersion uint16 `json:"tls_min_version" yaml:"tls_min_version"`

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.

So currently we use the server-config file to configure the tls_min_version, but the type is uint16, so the user needs to configure it like:

tls_min_version: 772  # this looks not quite human-readable?

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.

@skeeey Should we change the TLSMinVersion and TLSMaxVersion from uint16(772) to string(VersionTLS13)?

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.

yeah, using string is more readable

@zhujian7 zhujian7 Apr 2, 2026

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.

Has anyone already been using this? Will it break?

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.

@ncr38 PTAL, can we change this? do you use it?

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.

How about we merge the current pr first, and if we decide to change the tls_min_version to string, we do it as a follow-up PR.

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.

yes, that would be best

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.

@skeeey No, we don't use tls_min_version.

Change CipherSuites from []string to string, eliminating the
split-then-join round-trip between ApplyTLSFlags and validateCipherSuites.
The string is passed directly to pkgtls.ParseCipherSuites without
intermediate conversions.

Signed-off-by: Jia Zhu <jiazhu@redhat.com>
Signed-off-by: zhujian <jiazhu@redhat.com>
@zhujian7
zhujian7 force-pushed the feat/grpc-cipher-suites branch from 4049725 to e850e70 Compare April 1, 2026 14:50
@zhujian7

zhujian7 commented Apr 2, 2026

Copy link
Copy Markdown
Member Author

/unhold

@skeeey

skeeey commented Apr 2, 2026

Copy link
Copy Markdown
Member

LGTM

and I think we also need support this in https://github.com/open-cluster-management-io/sdk-go/blob/main/pkg/cloudevents/generic/options/cert/config.go, this is tls config for cloudevnet clients, these clients will be used by ocm components with grpc mod, right?

@zhujian7

zhujian7 commented Apr 2, 2026

Copy link
Copy Markdown
Member Author

I think we also need support this in pkg/cloudevents/generic/options/cert/config.go

@skeeey I don't think it's necessary for the client side right now. Cipher suite configuration is primarily a server-side concern — the server decides which suites to accept, and the client negotiates from what Go's TLS stack offers by default (which is already secure).

For clients, Go's defaults are fine:

  • tls.Config.CipherSuites defaults to a safe, preferred list
  • TLS 1.3 suites aren't configurable anyway
  • Clients don't need to restrict cipher suites unless there's a specific compliance requirement forcing them to match the server's exact list

We can add it later if a concrete use case comes up.

@zhujian7

zhujian7 commented Apr 2, 2026

Copy link
Copy Markdown
Member Author

/assign @qiujian16

@qiujian16

Copy link
Copy Markdown
Member

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Apr 2, 2026
@openshift-ci

openshift-ci Bot commented Apr 2, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: qiujian16, zhujian7

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:

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 added the approved label Apr 2, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 996da9f into open-cluster-management-io:main Apr 2, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sdk-go] Add pkg/tlsconfig package for TLS configuration parsing

4 participants