Skip to content

OCPBUGS-71237: Generate session-secret for all auth types - #1204

Open
jhadvig wants to merge 2 commits into
openshift:mainfrom
jhadvig:OCPBUGS-71237
Open

OCPBUGS-71237: Generate session-secret for all auth types#1204
jhadvig wants to merge 2 commits into
openshift:mainfrom
jhadvig:OCPBUGS-71237

Conversation

@jhadvig

@jhadvig jhadvig commented Aug 5, 2026

Copy link
Copy Markdown
Member

Analysis / Root cause:

Console sessions are lost on pod restart because encryption keys are generated randomly per process, making cookies non-portable across pods. The session-secret Secret infrastructure already exists for OIDC auth but was not enabled for OpenShift/IntegratedOAuth auth.

Jira: https://redhat.atlassian.net/browse/OCPBUGS-71237
Companion PR: openshift/console#16911

Solution description:

Extend the existing session-secret Secret management to all authentication types:

  • sync_v400.go: syncSessionSecret() now runs for all auth types, not just OIDC
  • config_builder.go: Sets session key file paths in the console config for OpenShift auth. Extracted sessionAuthKeyFilePath and sessionEncKeyFilePath constants
  • deployment.go: No changes needed — volume mount is already conditional on sessionSecret != nil

Upgrade safety: On upgrade, syncSessionSecret() creates the Secret before the ConfigMap and Deployment are synced.

Rollback safety: If downgraded, the orphaned Secret is harmless. The downgraded operator reverts to per-pod random keys.

Test cases:

  • All existing unit tests updated and passing
  • Config builder correctly sets session key paths for OpenShift auth
  • Config builder correctly omits session key paths for disabled auth

Additional info:

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved session security configuration across authentication modes.
    • Ensured session encryption and authentication keys are consistently configured when authentication is enabled.
    • Preserved empty session configuration when authentication is disabled.
    • Session secret synchronization now applies consistently across all authentication types.

Extend the session-secret Secret (previously OIDC-only) to all
authentication types including OpenShift/IntegratedOAuth. This provides
shared encryption keys across console pods so cookies can be decrypted
after pod restarts, enabling persistent sessions.

Changes:
- syncSessionSecret() now runs for all auth types, not just OIDC
- Config builder sets session key file paths for OpenShift auth
- Extract session key path constants to avoid duplication

The deployment volume mount is already conditional on sessionSecret
being non-nil, so no deployment changes are needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@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 Aug 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@jhadvig: This pull request references Jira Issue OCPBUGS-71237, which is invalid:

  • expected the bug to target the "5.0.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.

Details

In response to this:

Analysis / Root cause:

Console sessions are lost on pod restart because encryption keys are generated randomly per process, making cookies non-portable across pods. The session-secret Secret infrastructure already exists for OIDC auth but was not enabled for OpenShift/IntegratedOAuth auth.

Jira: https://redhat.atlassian.net/browse/OCPBUGS-71237
Companion PR: openshift/console#16911

Solution description:

Extend the existing session-secret Secret management to all authentication types:

  • sync_v400.go: syncSessionSecret() now runs for all auth types, not just OIDC. This creates the Secret with shared encryption keys (64-byte HMAC + 32-byte AES) on first reconciliation.
  • config_builder.go: Sets session key file paths in the console config for OpenShift auth (same paths already used for OIDC). Extracted sessionAuthKeyFilePath and sessionEncKeyFilePath constants.
  • deployment.go: No changes needed — volume mount is already conditional on sessionSecret != nil, which is now always true for non-disabled auth.

Upgrade safety: On upgrade, syncSessionSecret() creates the Secret before the ConfigMap and Deployment are synced. Kubelet won't start new pods until volumes are satisfiable.

Rollback safety: If downgraded, the orphaned Secret is harmless (~96 bytes). The downgraded operator won't set session key paths, so console reverts to per-pod random keys. Users are logged out (expected and unavoidable).

Test cases:

  • All existing unit tests updated and passing
  • Config builder correctly sets session key paths for OpenShift auth
  • Config builder correctly omits session key paths for disabled auth
  • Session secret is synced for all auth types

Additional info:

🤖 Generated with Claude Code

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.

@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 Aug 5, 2026
@openshift-ci

openshift-ci Bot commented Aug 5, 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

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: b0ea407d-d57b-4820-a37a-bbcff0af8d90

📥 Commits

Reviewing files that changed from the base of the PR and between 9e586f7 and ddf350f.

📒 Files selected for processing (1)
  • pkg/console/subresource/consoleserver/config_builder.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Follow Go coding standards and patterns documented in CONVENTIONS.md
Organize imports according to conventions documented in CONVENTIONS.md
Use gofmt to format Go code with standard formatting
Run go vet checks on all Go packages

Follow Go coding standards and patterns as documented in CONVENTIONS.md, including proper import organization

Organize Go code following the repository structure: main entry point in cmd/console/main.go, API constants in pkg/api/, operator command setup in pkg/cmd/operator/, and version command in pkg/cmd/version/

**/*.go: Use gofmt for formatting Go code
Follow standard Go naming conventions
Group imports in order: standard lib, 3rd party, kube/openshift, internal (marked with comments)
Use meaningful error messages with context in Go code
Set status conditions using status.Handle* functions with type prefixes (*Degraded, *Progressing, *Available, *Upgradeable)
Use typed errors and wrap errors to preserve stack context

Flag MD5, SHA1, DES, RC4, 3DES, Blowfish, and ECB mode cryptographic usage. Also flag custom crypto implementations and non-constant-time comparison of secrets or tokens.

**/*.go: Do not use deprecated Go APIs such as ioutil.ReadFile, ioutil.WriteFile, ioutil.ReadAll, or net.Dial in Dial callbacks; use os.ReadFile, os.WriteFile, io.ReadAll, and DialContext instead.
When returning errors in Go, wrap them with %w and include meaningful context instead of returning the raw error or using %v.
Use specific error checks such as apierrors.IsNotFound(err) instead of matching error strings with strings.Contains(err.Error(), ...).
Propagate the caller’s context.Context through operations and avoid replacing it with context.Background() inside request/controller code.
Use defer to release acquired resources so cleanup happens on all return paths.
Avoid god functions: keep Go functions to roughly under 100 lines and split code with too many responsibilities into smaller...

Files:

  • pkg/console/subresource/consoleserver/config_builder.go

⚙️ CodeRabbit configuration file

**/*.go: Review Go code following OpenShift operator patterns.
See CONVENTIONS.md for coding standards and patterns.

Refer to the following skills based on CODE PATTERNS, not just file paths:

Refer to /controller-review when code contains:

  • Controller struct types (e.g., type *Controller struct)
  • func New*Controller( factory functions
  • factory.New().WithFilteredEventsInformers( pattern
  • .ToController( method calls
  • Sync(ctx context.Context, controllerContext factory.SyncContext) methods
  • operatorConfig.Spec.ManagementState checks
  • status.NewStatusHandler or status.Handle* functions

Refer to /sync-handler-review when code contains:

  • Main operator sync functions (e.g., sync_v400.go content)
  • Sequential resource syncing with early returns
  • Incremental reconciliation loops
  • Multiple resourceapply.Apply*() calls in sequence
  • Dependency ordering of ConfigMaps → Secrets → Service Accounts → RBAC → Services → Deployments → Routes
  • Feature gate conditional logic

Refer to /go-quality-review for all Go code to check:

  • Deprecated imports: ioutil.ReadFile, ioutil.WriteFile, ioutil.ReadAll
  • Deprecated patterns: Dial without DialContext
  • Error handling: missing %w in fmt.Errorf
  • Code smells: deep nesting (4+ levels), functions >100 lines
  • Magic values: unexplained numbers/strings
  • Context propagation: context.Background() instead of passed ctx
  • Missing godoc on exported functions

Files:

  • pkg/console/subresource/consoleserver/config_builder.go
{pkg,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use gofmt for code formatting on pkg and cmd directories

{pkg,cmd}/**/*.go: Format code using gofmt -w ./pkg ./cmd
Run go vet checks on all Go packages in ./pkg and ./cmd

Files:

  • pkg/console/subresource/consoleserver/config_builder.go
pkg/console/subresource/**/*.go

📄 CodeRabbit inference engine (ARCHITECTURE.md)

Use pkg/console/subresource/ packages for resource builders, with separate packages for each resource type (authentication, configmap, deployment, oauthclient, route, secret, etc.)

Files:

  • pkg/console/subresource/consoleserver/config_builder.go
**/*.{py,js,ts,go,rs,java,rb,php,kt,swift,cs}

⚙️ CodeRabbit configuration file

**/*.{py,js,ts,go,rs,java,rb,php,kt,swift,cs}: Injection prevention (prodsec-skills):

  • SQL: parameterized queries only; no string concatenation
  • Command: no shell=True, os.system, or backtick exec with user input
  • LDAP/XPath: escape special characters in filters
  • Path traversal: canonicalize paths, reject ../
  • Deserialization: no pickle/yaml.load()/eval on untrusted data
  • Prototype pollution: no recursive merge of untrusted objects
  • Validate at trust boundaries with allow-lists, not deny-lists
  • Normalize Unicode and anchor regexes (^$); watch for ReDoS

Files:

  • pkg/console/subresource/consoleserver/config_builder.go
🪛 ast-grep (0.45.0)
pkg/console/subresource/consoleserver/config_builder.go

[warning] 25-25: A credential is hard-coded as a string literal. Secrets stored in source code, such as passwords, API keys, and tokens, can be leaked through version control or binaries and used by internal or external malicious actors. Rotate the exposed secret and load it at runtime from a secure secret vault, a Hardware Security Module (HSM), or an environment variable if permitted by your company policy (e.g. password := os.Getenv("APP_PASSWORD")).
Context: sessionAuthKeyFilePath = "/var/session-secret/sessionAuthenticationKey"
Note: [CWE-798] Use of Hard-coded Credentials.

(hardcoded-credentials-string-literal-go)

🔇 Additional comments (4)
pkg/console/subresource/consoleserver/config_builder.go (4)

203-204: LGTM!


224-225: LGTM!


24-27: 🗄️ Data Integrity & Integration

Verify the session Secret contract.

Confirm that the deployment mounts the Secret at /var/session-secret and that synchronization creates sessionAuthenticationKey and sessionEncryptionKey with these exact filenames. A mismatch makes the generated configuration unable to read the session keys.


459-473: 🎯 Functional Correctness

Add session configuration tests.

Cover disabled, OpenShift, OIDC, unset, and partial custom key paths. Define the expected behavior for partial custom paths and prevent unintended fallback mixing.


Walkthrough

The console configuration builder now emits session authentication and encryption key paths for enabled authentication modes. Disabled authentication returns an empty session configuration. Session Secret synchronization now applies to all authentication types. Tests update structured and YAML expectations.

Changes

Session configuration

Layer / File(s) Summary
Build session key configuration
pkg/console/subresource/consoleserver/config_builder.go
The builder defines shared session key paths, applies them to OpenShift and OIDC authentication, and returns an empty session when authentication is disabled.
Synchronize the session Secret
pkg/console/operator/sync_v400.go
Session-secret synchronization runs for every authentication configuration. Errors still terminate synchronization immediately.
Update configuration expectations
pkg/console/subresource/consoleserver/config_builder_test.go, pkg/console/subresource/consoleserver/config_merger_test.go, pkg/console/subresource/configmap/configmap_test.go
Structured and YAML expectations now include session authentication and encryption key file paths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: spadgett, therealjon

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Jira issue and the primary change: generating session secrets for all authentication types.
Description check ✅ Passed The description covers the root cause, solution, tests, upgrade and rollback safety, and companion PR; omitted template sections are non-critical.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 The feature commit changes only expected session fixture values; all test and subtest titles remain static strings, with no Ginkgo titles or dynamic identifiers.
Test Structure And Quality ✅ Passed The affected files use table-driven testing.T tests, not Ginkgo. They perform no cluster operations, waits, resource setup, or cleanup requiring these Ginkgo-specific checks.
Microshift Test Compatibility ✅ Passed The PR adds no Ginkgo e2e tests. Changed test files use Go's testing.T framework and contain no It, Describe, Context, or When constructs requiring MicroShift API review.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The feature diff adds no Ginkgo e2e tests. Changed tests use standard Go Test functions, and no It/Describe/Context/When or multi-node assumptions were added.
Topology-Aware Scheduling Compatibility ✅ Passed The feature diff changes only session-secret synchronization, console session paths, and tests; it adds no affinity, spread, selector, toleration, replica, strategy, or PDB scheduling constraints.
Ote Binary Stdout Contract ✅ Passed The feature patch adds no stdout writes or suite setup; the repository has no OTE/Ginkgo entrypoint. Existing e2e TestMain is an ordinary testing package and is outside this PR.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR adds no Ginkgo e2e tests or new networking calls; changes are Go unit-test expectations and configuration code, with no added IPv4 or external-connectivity assumptions.
No-Weak-Crypto ✅ Passed The PR adds key-path wiring and secret synchronization only; existing session keys use crypto/rand with AES-256 and HMAC-SHA256 sizes, with no weak algorithms or secret comparisons introduced.
Container-Privileges ✅ Passed The PR adds no privilege-related fields and changes no manifest-like files; the existing console deployment uses runAsNonRoot and allowPrivilegeEscalation: false.
No-Sensitive-Data-In-Logs ✅ Passed The PR adds no logging statements; it logs only session key file paths, while library Secret change logs redact data and events include only resource identity.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

Review ran into problems

🔥 Problems

Repository analysis: Couldn't refresh openshift/console-operator clone - clone failed: Clone operation failed: Stream initialization permanently failed: 14 UNAVAILABLE: Connection dropped


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

@openshift-ci

openshift-ci Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhadvig

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 Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 5, 2026

@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/console/operator/sync_v400.go`:
- Around line 124-126: Update the error return immediately after
syncSessionSecret in the operator synchronization flow to wrap the error with
meaningful session Secret synchronization context while preserving the original
cause via %w. Keep the existing statusHandler.FlushAndReturn handling unchanged.
🪄 Autofix

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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 7a53bbeb-7bc9-492b-82cf-aa10b9880c50

📥 Commits

Reviewing files that changed from the base of the PR and between 67370e1 and 9e586f7.

📒 Files selected for processing (5)
  • pkg/console/operator/sync_v400.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_merger_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Follow Go coding standards and patterns documented in CONVENTIONS.md
Organize imports according to conventions documented in CONVENTIONS.md
Use gofmt to format Go code with standard formatting
Run go vet checks on all Go packages

Follow Go coding standards and patterns as documented in CONVENTIONS.md, including proper import organization

Organize Go code following the repository structure: main entry point in cmd/console/main.go, API constants in pkg/api/, operator command setup in pkg/cmd/operator/, and version command in pkg/cmd/version/

**/*.go: Use gofmt for formatting Go code
Follow standard Go naming conventions
Group imports in order: standard lib, 3rd party, kube/openshift, internal (marked with comments)
Use meaningful error messages with context in Go code
Set status conditions using status.Handle* functions with type prefixes (*Degraded, *Progressing, *Available, *Upgradeable)
Use typed errors and wrap errors to preserve stack context

Flag MD5, SHA1, DES, RC4, 3DES, Blowfish, and ECB mode cryptographic usage. Also flag custom crypto implementations and non-constant-time comparison of secrets or tokens.

**/*.go: Do not use deprecated Go APIs such as ioutil.ReadFile, ioutil.WriteFile, ioutil.ReadAll, or net.Dial in Dial callbacks; use os.ReadFile, os.WriteFile, io.ReadAll, and DialContext instead.
When returning errors in Go, wrap them with %w and include meaningful context instead of returning the raw error or using %v.
Use specific error checks such as apierrors.IsNotFound(err) instead of matching error strings with strings.Contains(err.Error(), ...).
Propagate the caller’s context.Context through operations and avoid replacing it with context.Background() inside request/controller code.
Use defer to release acquired resources so cleanup happens on all return paths.
Avoid god functions: keep Go functions to roughly under 100 lines and split code with too many responsibilities into smaller...

Files:

  • pkg/console/operator/sync_v400.go
  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_builder.go

⚙️ CodeRabbit configuration file

**/*.go: Review Go code following OpenShift operator patterns.
See CONVENTIONS.md for coding standards and patterns.

Refer to the following skills based on CODE PATTERNS, not just file paths:

Refer to /controller-review when code contains:

  • Controller struct types (e.g., type *Controller struct)
  • func New*Controller( factory functions
  • factory.New().WithFilteredEventsInformers( pattern
  • .ToController( method calls
  • Sync(ctx context.Context, controllerContext factory.SyncContext) methods
  • operatorConfig.Spec.ManagementState checks
  • status.NewStatusHandler or status.Handle* functions

Refer to /sync-handler-review when code contains:

  • Main operator sync functions (e.g., sync_v400.go content)
  • Sequential resource syncing with early returns
  • Incremental reconciliation loops
  • Multiple resourceapply.Apply*() calls in sequence
  • Dependency ordering of ConfigMaps → Secrets → Service Accounts → RBAC → Services → Deployments → Routes
  • Feature gate conditional logic

Refer to /go-quality-review for all Go code to check:

  • Deprecated imports: ioutil.ReadFile, ioutil.WriteFile, ioutil.ReadAll
  • Deprecated patterns: Dial without DialContext
  • Error handling: missing %w in fmt.Errorf
  • Code smells: deep nesting (4+ levels), functions >100 lines
  • Magic values: unexplained numbers/strings
  • Context propagation: context.Background() instead of passed ctx
  • Missing godoc on exported functions

Files:

  • pkg/console/operator/sync_v400.go
  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_builder.go
{pkg,cmd}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use gofmt for code formatting on pkg and cmd directories

{pkg,cmd}/**/*.go: Format code using gofmt -w ./pkg ./cmd
Run go vet checks on all Go packages in ./pkg and ./cmd

Files:

  • pkg/console/operator/sync_v400.go
  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_builder.go
**/*sync*.go

📄 CodeRabbit inference engine (CONVENTIONS.md)

Implement sync loops (sync_v400) incrementally: start from zero, create/update missing requirements, and return to continue on next loop

Files:

  • pkg/console/operator/sync_v400.go
**/operator/**/*.go

📄 CodeRabbit inference engine (Custom checks)

When deployment manifests, operator code, or controllers are added/modified, ensure they do not introduce scheduling constraints assuming standard HA topology. Check ControlPlaneTopology for SingleReplica/DualReplica/HighlyAvailableArbiter/External modes before applying constraints. Use required anti-affinity with maxUnavailable >= 1 (not maxUnavailable: 0). Cap replica counts to schedulable nodes. Exclude arbiter nodes on TNA. Avoid master nodeSelectors on HyperShift. Use library-go DeploymentController hooks (WithTopologyAwareReplicasHook, WithTopologyAwareSchedulingHook, WithControlPlaneNodeSelectorHook).

Files:

  • pkg/console/operator/sync_v400.go
**/sync_v400.go

📄 CodeRabbit inference engine (.claude/skills/sync-handler-review.md)

Incremental sync pattern: each sync loop should stop on the first error and resume from the next step on the next reconciliation instead of collecting and joining all errors.

Files:

  • pkg/console/operator/sync_v400.go
**/*.{py,js,ts,go,rs,java,rb,php,kt,swift,cs}

⚙️ CodeRabbit configuration file

**/*.{py,js,ts,go,rs,java,rb,php,kt,swift,cs}: Injection prevention (prodsec-skills):

  • SQL: parameterized queries only; no string concatenation
  • Command: no shell=True, os.system, or backtick exec with user input
  • LDAP/XPath: escape special characters in filters
  • Path traversal: canonicalize paths, reject ../
  • Deserialization: no pickle/yaml.load()/eval on untrusted data
  • Prototype pollution: no recursive merge of untrusted objects
  • Validate at trust boundaries with allow-lists, not deny-lists
  • Normalize Unicode and anchor regexes (^$); watch for ReDoS

Files:

  • pkg/console/operator/sync_v400.go
  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_builder.go
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow testing patterns and commands documented in TESTING.md

Follow testing patterns and commands as documented in TESTING.md, including running unit tests with 'make test-unit' and checks with 'make check'

**/*_test.go: Use table-driven tests for comprehensive coverage
Use httptest for HTTP handler testing in Go
Include proper cleanup functions in tests
Test both success and failure paths

In Go tests, do not ignore returned errors; check err and fail the test with t.Fatalf or t.Errorf as appropriate.

Files:

  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go

⚙️ CodeRabbit configuration file

**/*_test.go: Review test code for quality and patterns.

Refer to /unit-test-review when test is in pkg//*_test.go:**

  • Table-driven test structure with test cases
  • Use of go-test/deep for struct comparisons
  • Test naming conventions (TestFunctionName)
  • Error handling with wantErr pattern
  • Edge case coverage (nil, empty, boundary values)
  • Proper assertions with helpful error messages
  • Test isolation (no shared mutable state)

Refer to /e2e-test-review when test contains:

  • framework.MustNewClientset(t, nil) or similar e2e framework usage
  • wait.Poll or wait.PollImmediate patterns
  • retry.RetryOnConflict for updates
  • Cleanup via defer functions
  • Console/operator CR manipulations
  • Test assertions on cluster state

Suggest to use /e2e-test-review when:

  • PR adds new feature requiring e2e coverage
  • Test file is empty or skeleton
  • Comments indicate "TODO: add test"

Review for common issues:

  • Missing cleanup (defer statements)
  • Using time.Sleep instead of wait.Poll
  • Missing context timeouts
  • Vague error messages in assertions
  • Tests without table-driven structure when testing multiple cases
  • Ignoring errors with _
  • Tests without assertions

Files:

  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
pkg/console/subresource/**/*.go

📄 CodeRabbit inference engine (ARCHITECTURE.md)

Use pkg/console/subresource/ packages for resource builders, with separate packages for each resource type (authentication, configmap, deployment, oauthclient, route, secret, etc.)

Files:

  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
  • pkg/console/subresource/consoleserver/config_builder.go
pkg/**/*_test.go

📄 CodeRabbit inference engine (.claude/skills/unit-test-review.md)

pkg/**/*_test.go: Most unit tests should use the table-driven test pattern, including a tests := []struct{...} table and t.Run(tt.name, ...) subtests for scenarios with multiple cases.
Test function names and subtest case names should be descriptive of the behavior or scenario being tested (for example, TestGetNodeComputeEnvironments or "Custom hostname and TLS secret set").
Use github.com/go-test/deep (deep.Equal) for struct comparisons instead of == or manual field-by-field checks.
Cover both success and failure paths in unit tests, including edge cases such as empty inputs, boundary values, missing fields, duplicates, and large inputs.
Structure tests using Arrange-Act-Assert so setup, execution, and verification are clearly separated.
When testing error-returning functions, assert error presence correctly and, when relevant, validate the error message substring instead of ignoring the error or discarding it with _.
Prefer dependency injection via interfaces for testability, and keep tests isolated so they do not depend on execution order or shared mutable state.
Extract repeated setup into helper functions when common test fixtures are reused across multiple tests.
Write specific, informative assertions that explain what failed instead of vague or silent failures.
Inline simple test data, but move complex fixtures to helper functions or testdata/ files.
Avoid tests that rely on execution order, share global mutable state, use hardcoded sleeps, omit assertions, or verify implementation details instead of behavior.

Files:

  • pkg/console/subresource/consoleserver/config_merger_test.go
  • pkg/console/subresource/configmap/configmap_test.go
  • pkg/console/subresource/consoleserver/config_builder_test.go
🪛 ast-grep (0.45.0)
pkg/console/subresource/consoleserver/config_builder.go

[warning] 25-25: A credential is hard-coded as a string literal. Secrets stored in source code, such as passwords, API keys, and tokens, can be leaked through version control or binaries and used by internal or external malicious actors. Rotate the exposed secret and load it at runtime from a secure secret vault, a Hardware Security Module (HSM), or an environment variable if permitted by your company policy (e.g. password := os.Getenv("APP_PASSWORD")).
Context: sessionAuthKeyFilePath = "/var/session-secret/sessionAuthenticationKey"
Note: [CWE-798] Use of Hard-coded Credentials.

(hardcoded-credentials-string-literal-go)

🔇 Additional comments (4)
pkg/console/subresource/consoleserver/config_builder.go (1)

24-27: LGTM!

Also applies to: 203-204, 224-225, 459-472

pkg/console/subresource/consoleserver/config_builder_test.go (1)

74-77: LGTM!

Also applies to: 110-113, 157-160, 211-214, 365-368, 404-407, 443-446, 506-509, 569-572, 612-615, 655-658, 697-700, 753-756, 821-824, 888-891, 948-951, 1005-1008, 1049-1052, 1094-1097, 1151-1153, 1236-1238, 1263-1265, 1292-1294, 1322-1324, 1376-1378, 1422-1424, 1459-1461, 1497-1499, 1584-1586, 1632-1634, 1704-1706, 1780-1782, 1836-1838, 1874-1876

pkg/console/subresource/configmap/configmap_test.go (1)

126-128: LGTM!

Also applies to: 194-196, 222-224, 280-282, 310-312, 365-367, 402-404, 453-455, 496-498, 547-549, 653-655, 704-706, 776-778, 827-829, 902-904, 972-974, 1045-1047, 1159-1161, 1231-1233, 1307-1309, 1546-1548, 1559-1561

pkg/console/subresource/consoleserver/config_merger_test.go (1)

64-66: LGTM!

Comment on lines +124 to +126
sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder())
if err != nil {
return statusHandler.FlushAndReturn(err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Wrap the session Secret synchronization error with context.

Line 126 returns the raw error. Add the failed operation name and preserve the cause with %w. This improves diagnosis because this operation now runs for every authentication type.

Proposed fix
-		return statusHandler.FlushAndReturn(err)
+		return statusHandler.FlushAndReturn(fmt.Errorf("sync session Secret: %w", err))

As per coding guidelines, “When returning errors in Go, wrap them with %w and include meaningful context instead of returning the raw error or using %v.”

📝 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
sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder())
if err != nil {
return statusHandler.FlushAndReturn(err)
sessionSecret, err = co.syncSessionSecret(ctx, updatedOperatorConfig, controllerContext.Recorder())
if err != nil {
return statusHandler.FlushAndReturn(fmt.Errorf("sync session Secret: %w", err))
🤖 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/console/operator/sync_v400.go` around lines 124 - 126, Update the error
return immediately after syncSessionSecret in the operator synchronization flow
to wrap the error with meaningful session Secret synchronization context while
preserving the original cause via %w. Keep the existing
statusHandler.FlushAndReturn handling unchanged.

Source: Coding guidelines

@jhadvig jhadvig changed the title WIP OCPBUGS-71237: Generate session-secret for all auth types OCPBUGS-71237: Generate session-secret for all auth types Aug 10, 2026
@jhadvig
jhadvig marked this pull request as ready for review August 10, 2026 11:36
@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 Aug 10, 2026
@openshift-ci
openshift-ci Bot requested review from TheRealJon and spadgett August 10, 2026 11:37
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jhadvig

jhadvig commented Aug 11, 2026

Copy link
Copy Markdown
Member Author

Test Results

All scenarios verified on a live cluster (GCP) with both console-operator and console PRs deployed together.

# Test User Trigger Result
1 Session persists after pod restart kubeadmin oc delete pods -l component=ui ✅ PASSED
2 Session persists after pod restart testuser (htpasswd IDP) oc delete pods -l component=ui ✅ PASSED
3 Session persists after plugin disable kubeadmin Operator-triggered rollout ✅ PASSED
4 Session persists after plugin re-enable kubeadmin Operator-triggered rollout ✅ PASSED
5 Session persists after plugin disable testuser (htpasswd IDP) Operator-triggered rollout ✅ PASSED
6 Session persists after plugin re-enable testuser (htpasswd IDP) Operator-triggered rollout ✅ PASSED
7 Cluster installs successfully Fresh install via cluster-bot ✅ PASSED

What this PR does

Extends the session-secret Secret (shared encryption keys) from OIDC-only to all auth types. This is the operator-side prerequisite for persistent sessions — the console PR handles the actual session recovery logic.

Companion console PR: openshift/console#16911

/verified by @jhadvig

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Aug 11, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@jhadvig: This PR has been marked as verified by @jhadvig.

Details

In response to this:

Test Results

All scenarios verified on a live cluster (GCP) with both console-operator and console PRs deployed together.

# Test User Trigger Result
1 Session persists after pod restart kubeadmin oc delete pods -l component=ui ✅ PASSED
2 Session persists after pod restart testuser (htpasswd IDP) oc delete pods -l component=ui ✅ PASSED
3 Session persists after plugin disable kubeadmin Operator-triggered rollout ✅ PASSED
4 Session persists after plugin re-enable kubeadmin Operator-triggered rollout ✅ PASSED
5 Session persists after plugin disable testuser (htpasswd IDP) Operator-triggered rollout ✅ PASSED
6 Session persists after plugin re-enable testuser (htpasswd IDP) Operator-triggered rollout ✅ PASSED
7 Cluster installs successfully Fresh install via cluster-bot ✅ PASSED

What this PR does

Extends the session-secret Secret (shared encryption keys) from OIDC-only to all auth types. This is the operator-side prerequisite for persistent sessions — the console PR handles the actual session recovery logic.

Companion console PR: openshift/console#16911

/verified by @jhadvig

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.

@jhadvig

jhadvig commented Aug 11, 2026

Copy link
Copy Markdown
Member Author

/retest

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

@jhadvig: The following tests 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-ovn ddf350f link true /test e2e-gcp-ovn
ci/prow/e2e-aws-operator ddf350f link true /test e2e-aws-operator
ci/prow/e2e-aws-console ddf350f link true /test e2e-aws-console
ci/prow/e2e-azure-ovn-upgrade ddf350f link true /test e2e-azure-ovn-upgrade

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.

@jhadvig

jhadvig commented Aug 11, 2026

Copy link
Copy Markdown
Member Author

CI e2e failures explanation

The 4 e2e job failures are expected and not caused by bugs in this PR.

Root cause: The e2e jobs build the operator from this PR but use the stock console image from the nightly. This PR sets session key file paths in the console config for OpenShift auth (previously OIDC-only). The stock console binary treats missing key files as a fatal error and crashes during bootstrap before the session-secret Secret is created and mounted.

The fix for this is in the companion console PR (#16911), which makes missing key files non-fatal for OpenShift auth (logs a warning and falls back to random keys). Once that console image lands in the nightly, these e2e jobs will pass.

Merge order: Console PR #16911 must merge first (it's fully backward compatible), then this operator PR can be retested and merged.

When deployed together (as verified in the test results above), both PRs work correctly — the cluster installs cleanly and sessions persist across pod restarts.

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. 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. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants