Skip to content

Conversation

ShazaAldawamneh
Copy link

Previously, when a custom service account issuer was set, the
service-account-jwks-uri argument was not configured in the KubeAPIServer,
causing the JWKS URI to default to the node IP. This led to TLS errors
because the node IP is not included in the certificate SAN.

This commit updates observedConfig to always set
service-account-jwks-uri to the API LB URL regardless of whether the
issuer is default or custom. Unit tests have been updated to validate
this behavior.

Fixes: TLS SAN issues for clients accessing JWKS URI with custom issuers.

@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Sep 11, 2025
@openshift-ci-robot
Copy link

@ShazaAldawamneh: This pull request references Jira Issue OCPBUGS-46086, which is invalid:

  • expected the bug to target the "4.21.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

Previously, when a custom service account issuer was set, the
service-account-jwks-uri argument was not configured in the KubeAPIServer,
causing the JWKS URI to default to the node IP. This led to TLS errors
because the node IP is not included in the certificate SAN.

This commit updates observedConfig to always set
service-account-jwks-uri to the API LB URL regardless of whether the
issuer is default or custom. Unit tests have been updated to validate
this behavior.

Fixes: TLS SAN issues for clients accessing JWKS URI with custom issuers.

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.

Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

Unconditional configuration of service-account-jwks-uri based on APIServerURL was introduced, decoupling it from the issuer check. Error handling for missing APIServerURL now triggers regardless of issuer. Corresponding tests were updated to expect the JWKS URI in more scenarios, with a new test case added.

Changes

Cohort / File(s) Summary of changes
Auth config observation logic
pkg/operator/configobservation/auth/auth_serviceaccountissuer.go
Removed issuer-gated condition; always sets service-account-jwks-uri when APIServerURL is present. Missing APIServerURL now returns an error regardless of issuer. JWKS URI remains apiServerExternalURL + "/openid/v1/jwks".
Auth config observation tests
pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go
Updated tests to expect service-account-jwks-uri in more cases; added expectInternalJWKI flag and a new test case for custom issuer without previous issuer. Adjusted assertions to validate JWKS URI equals testLBURI.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately and specifically summarizes the primary change — always setting service-account-jwks-uri to the API LB URL even when using a custom issuer — and directly matches the changes in the code and tests; the "[WIP]" prefix and Jira reference are informative but do not make the title misleading.
Description Check ✅ Passed The PR description clearly states the bug (missing JWKS URI with custom issuer causing TLS SAN errors), the implemented fix (always set service-account-jwks-uri to the API LB URL), and notes updated unit tests; this is directly related to the changeset and is sufficient for this lenient check.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

@ShazaAldawamneh ShazaAldawamneh changed the title OCPBUGS-46086: Always set service-account-jwks-uri to LB URL even with custom issuer [WIP]: OCPBUGS-46086: Always set service-account-jwks-uri to LB URL even with custom issuer Sep 11, 2025
@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 Sep 11, 2025
Copy link
Contributor

openshift-ci bot commented Sep 11, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

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

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 21e09f9 and 64ce562.

📒 Files selected for processing (3)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (4 hunks)
  • tls.crt (1 hunks)
  • tls.key (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tls.crt
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go
🧰 Additional context used
🪛 Gitleaks (8.27.2)
tls.key

[high] 1-27: Identified a Private Key, which may compromise cryptographic security and sensitive data encryption.

(private-key)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (6)

57-63: Reduce duplication with later custom-issuer case.

This test is effectively duplicated by the new “custom issuer, no previous issuer” case at Lines 114–121. Either drop one or vary inputs (e.g., add trustedIssuers) to cover a distinct path.


114-121: Good addition; add a negative test for empty APIServerURL.

To lock in the error-path contract, add a test where Infrastructure.Status.APIServerURL is empty and verify: an error is surfaced and JWKS URI is not set.

Here’s a self-contained test you can append:

+func TestObservedConfig_EmptyAPIServerURL(t *testing.T) {
+  testRecorder := events.NewInMemoryRecorder("SAIssuerTest", clock.RealClock{})
+  expectedErr := fmt.Errorf("APIServerURL is empty")
+  newConfig, errs := observedConfig(
+    unstructuredAPIConfigForIssuer(t, defaultServiceAccountIssuerValue, nil),
+    func(_ string) (*operatorv1.KubeAPIServer, error) {
+      return kasStatusForIssuer(defaultServiceAccountIssuerValue), nil
+    },
+    func(_ string) (*configv1.Infrastructure, error) {
+      return &configv1.Infrastructure{Status: configv1.InfrastructureStatus{APIServerURL: ""}}, expectedErr
+    },
+    testRecorder,
+  )
+  // Unmarshal and assert JWKS not present
+  unstructuredConfig := unstructured.Unstructured{Object: newConfig}
+  raw, err := unstructuredConfig.MarshalJSON()
+  require.NoError(t, err)
+  cfg := &kubecontrolplanev1.KubeAPIServerConfig{TypeMeta: metav1.TypeMeta{Kind: "KubeAPIServerConfig"}}
+  require.NoError(t, json.Unmarshal(raw, cfg))
+  if _, ok := cfg.APIServerArguments["service-account-jwks-uri"]; ok {
+    t.Fatalf("expected service-account-jwks-uri to be absent when APIServerURL is empty")
+  }
+  require.Contains(t, errs, expectedErr)
+}

174-175: Swap expected/actual in assert for clarity.

Keep testify’s expected, actual order.

-          require.Equal(t, uri, kubecontrolplanev1.Arguments{testLBURI})
+          require.Equal(t, kubecontrolplanev1.Arguments{testLBURI}, uri)

178-178: Avoid calling String() on slice type; print the value directly.

kubecontrolplanev1.Arguments is a slice; String() may not exist across versions.

-        t.Errorf("expected no service-account-jwks-uri to be set, it is %+v", uri.String())
+        t.Errorf("expected no service-account-jwks-uri to be set, it is %+v", uri)

215-218: Remove commented-out code in helper; keep intent crisp.

These deletes are confusing in tests. Drop them.

- //delete(args, "service-account-issuer")
- //delete(args, "api-audiences")
  args["service-account-jwks-uri"] = kubecontrolplanev1.Arguments{testLBURI}

39-40: Terminology nit: JWKS vs. JWKI.

Rename expectInternalJWKI to expectJWKSURI (or similar) for accuracy.

Also applies to: 170-177

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 64ce562 and f33ce1f.

📒 Files selected for processing (1)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (5 hunks)
🔇 Additional comments (5)
pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (5)

71-71: JWKS URI should always be set to LB URL — good.


75-80: LGTM: same issuer/no change still asserts JWKS URI present.


88-88: LGTM: trusted issuers preserved while JWKS URI asserted.


91-97: LGTM: issuer change triggers event and keeps JWKS URI.


99-105: Verify behavior when auth getter errors.

You still assert JWKS URI presence when auth returns an error. Confirm the observer keeps computing JWKS from Infrastructure.Status.APIServerURL even if the auth getter errors (and only fails if APIServerURL is empty).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (5)

57-63: Good expansion of table cases to always expect JWKS at the LB URL.

Covers key transitions (default→custom, custom unchanged, error pass‑through). Consider adding one more case where Infrastructure.Status.APIServerURL is empty to assert: (a) an error is surfaced and (b) service-account-jwks-uri is not set.

Sample table entry to add:

+        {
+            name:               "missing APIServerURL yields error and no jwks-uri",
+            existingIssuer:     defaultServiceAccountIssuerValue,
+            issuer:             defaultServiceAccountIssuerValue,
+            // infra getter returns empty APIServerURL
+            infraError:         fmt.Errorf("no APIServerURL"),
+            expectedIssuer:     defaultServiceAccountIssuerValue,
+            // keep this false if observed code skips jwks-uri on missing APIServerURL
+            expectInternalJWKI: false,
+            expectedChange:     true,
+        },

Also applies to: 71-71, 75-80, 88-88, 91-97, 99-105, 114-121


174-175: Swap expected/actual in require.Equal for clearer failures.

Testify expects require.Equal(t, expected, actual).

-                    require.Equal(t, uri, kubecontrolplanev1.Arguments{testLBURI})
+                    require.Equal(t, kubecontrolplanev1.Arguments{testLBURI}, uri)

178-178: Avoid calling String() on kubecontrolplanev1.Arguments.

Safer to format the slice directly; avoids coupling to a String() method.

-                t.Errorf("expected no service-account-jwks-uri to be set, it is %+v", uri.String())
+                t.Errorf("expected no service-account-jwks-uri to be set, it is %+v", uri)

215-217: Remove commented‑out deletes; keep expected args explicit.

Dead commented code adds noise in tests.

-    //delete(args, "service-account-issuer")
-    //delete(args, "api-audiences")
     args["service-account-jwks-uri"] = kubecontrolplanev1.Arguments{testLBURI}

61-61: Nit: rename expectInternalJWKI → expectJWKSURI (or expectJWKS).

Current name reads like “JWKI”. Renaming improves readability and avoids confusion with “JWKS”.

If you want, I can generate a quick sed/rg script to safely rename across the file.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between f33ce1f and 47ee8ff.

📒 Files selected for processing (2)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer.go (1 hunks)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer_test.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/operator/configobservation/auth/auth_serviceaccountissuer.go

Copy link
Contributor

openshift-ci bot commented Sep 15, 2025

@ShazaAldawamneh: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-gcp-operator-single-node 47ee8ff link false /test e2e-gcp-operator-single-node

Full PR test history. Your PR dashboard.

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
do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants