Enforce secure renderer password defaults for production-like envs#2829
Enforce secure renderer password defaults for production-like envs#2829
Conversation
Closes #2795 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughNode renderer and Rails now enforce renderer password in production-like environments: password is optional in Changes
Sequence Diagram(s)sequenceDiagram
participant Launcher as "Launcher"
participant Node as "NodeRenderer.buildConfig()"
participant Env as "process.env"
participant Proc as "process (exit)"
Launcher->>Node: start renderer
Node->>Env: read NODE_ENV, RAILS_ENV, RENDERER_PASSWORD, REPLAY_SERVER_ASYNC_OPERATION_LOGS
Node->>Node: recompute runtime defaults, merge config (filter undefined)
Node->>Node: log sanitized config (mask module-load defaults)
Node->>Node: validatePasswordForProduction()
alt password present OR env is development/test
Node->>Launcher: return Config (startup continues)
else missing password in non-dev/test
Node->>Launcher: log multi-line error with env matrix and instructions
Node->>Proc: process.exit(1)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR enforces a secure-by-default renderer password policy for Key changes:
Minor items: the inline comment on the Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[ReactOnRailsPro.configure / buildConfig called] --> B{renderer_password\nalready set directly?}
B -- Yes --> Z[Continue startup normally]
B -- No --> C[Extract password from renderer_url]
C --> D{Password found\nin URL?}
D -- Yes --> Z
D -- No --> E{node_renderer? /\nNodeRenderer in use?}
E -- No ExecJS --> Z
E -- Yes --> F{Rails.env /\nNODE_ENV}
F -- development or test --> Z
F -- staging / production\nor NODE_ENV unset --> G[🚨 Raise / Throw error\nREREERER_PASSWORD must be set]
G --> H[App refuses to start]
|
PR Review: Enforce secure renderer password defaults for production-like envsOverall, this is a well-structured security improvement. The fail-fast approach (raising at configuration/startup time rather than at request time) is the right pattern, the dev/test bypass is appropriate, and the error messages are actionable. Test coverage is solid. A few things worth flagging: Medium: Validation can be bypassed via explicit
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c5d1acd93
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
size-limit report 📦
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/react-on-rails-pro-node-renderer/src/shared/configBuilder.ts`:
- Around line 251-269: validatePasswordForProduction currently only checks
NODE_ENV; update it to consider both NODE_ENV and RAILS_ENV so password
enforcement matches Rails usage: compute nodeEnv = NODE_ENV and railsEnv =
process.env.RAILS_ENV, treat the environment as "production-like" if either env
is not 'development' or 'test' (e.g., 'staging'/'production'), and require a
password in that case inside validatePasswordForProduction(Config).
Additionally, detect and fail-closed on a mixed env mismatch (one env
production-like and the other development/test) by throwing an explicit error
explaining the mismatch so the caller can align RAILS_ENV and NODE_ENV or
provide RENDERER_PASSWORD; reference validatePasswordForProduction, NODE_ENV,
and RAILS_ENV when making these changes.
🪄 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: 556bcce9-9556-4be6-9dcd-c8b73b811d0e
📒 Files selected for processing (6)
docs/oss/building-features/node-renderer/js-configuration.mddocs/pro/node-renderer.mdpackages/react-on-rails-pro-node-renderer/src/shared/configBuilder.tspackages/react-on-rails-pro-node-renderer/tests/configBuilder.test.tsreact_on_rails_pro/lib/react_on_rails_pro/configuration.rbreact_on_rails_pro/spec/react_on_rails_pro/configuration_spec.rb
Aligns validatePasswordForProduction with master.ts, which already checks both NODE_ENV and RAILS_ENV for production detection. Previously only NODE_ENV was checked, so RAILS_ENV=production with NODE_ENV=development would skip password enforcement while the master ran in production mode. The new logic also fails closed when neither env var is set, matching the existing default of NODE_ENV defaulting to 'production'. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Review: Enforce secure renderer password defaultsOverall this is a well-motivated security hardening PR with solid test coverage. The fail-closed approach (require password in all non-dev/test environments, including when neither env var is set) is the right default. A few issues worth addressing before merge: Missing CHANGELOG entry
Breaking change: no deprecation pathUsers upgrading
Inline comments posted on:
What's good
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d742d39edf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Replying to #2829 (comment) I reviewed the remaining points and am leaving them as-is for this PR:
The only remaining optional nit I may still address is the stale inline TypeScript comment on the |
|
Replying to #2829 (comment) On the The stale |
|
Replying to #2829 (comment) Addressed the remaining optional Updated the inline TypeScript comment in |
|
Good security improvement overall — enforcing a password for NodeRenderer in non-dev/test environments is the right call, and the test coverage is solid. Breaking change This will break any existing production/staging deployment using NodeRenderer without RENDERER_PASSWORD. The default renderer is ExecJS, so existing NodeRenderer users are the only affected group, but this is worth calling out explicitly in the changelog. A soft landing (warn in the current release, error in the next major) would reduce upgrade friction. Documentation gap: coverage is broader than the table implies The environment matrix shows only staging and production as required. But the code logic is anything-not-development-or-test — so custom environments like qa, preview, uat, sandbox, demo, etc. also require the password. The table should reflect this with an 'other' row or a note about all non-development/test environments. Error handling inconsistency in Node.js validatePasswordForProduction throws an Error, but all other validations in buildConfig call process.exit(1). Throwing is better for testability, but it means a misconfigured renderer crashes with an unhandled rejection rather than a clean logged exit. Consider wrapping the throw in a try/catch in buildConfig that logs and exits cleanly, consistent with the rest of the file. Minor: missing Node.js edge-case test The test suite covers NODE_ENV=development + RAILS_ENV=production (correctly throws) but not NODE_ENV=test + RAILS_ENV=production. Since test is an explicitly allowed value in the logic, that combination deserves a test confirming it still throws when RAILS_ENV is production. |
Review: Enforce secure renderer password defaultsOverall this is a solid security improvement with a well-designed fail-closed approach and comprehensive test coverage. A few issues worth addressing. Logic correctnessThe `validatePasswordForProduction` logic is correct — it requires all set environment variables to be safe (dev/test), not just one of them. This correctly rejects misconfigurations like `RAILS_ENV=production` + `NODE_ENV=development`. The Ruby side correctly uses `Rails.env` as authoritative without needing to cross-check `NODE_ENV`. Tests are thorough and the fail-closed behavior when neither env var is set is explicitly covered. Issues1. Dead code in `defaultConfig` — `replayServerAsyncOperationLogs` `defaultConfig.replayServerAsyncOperationLogs` is computed once at module load time but is always overridden by the same expression inside `runtimeDefaultConfig` in `buildConfig()`. The `{ ...defaultConfig, replayServerAsyncOperationLogs: ... }` spread means the `defaultConfig` value is never used. Harmless but confusing. 2. `logSanitizedConfig` logs stale `defaultConfig.password` `logSanitizedConfig` includes `'Default settings': defaultConfig`. Since `defaultConfig.password` is evaluated at module load time, a late-loaded `RENDERER_PASSWORD` (set after import but before `buildConfig()` is called) will appear as `undefined` in the defaults log even though the actual runtime default is correct. Minor observability inaccuracy. 3. Missing mixed-env test case There is a test for `NODE_ENV=development` + `RAILS_ENV=production` (throws), but no test for the symmetric case: `NODE_ENV=staging` + `RAILS_ENV=development` (should also throw). Both directions of a mixed-env mismatch should be exercised to protect against future logic regressions. 4. Ruby `setup_renderer_password` early-return skips validation for pre-set passwords When `renderer_password` is already present, `setup_renderer_password` returns at line 232 before `validate_renderer_password_for_production` is ever reached. In the singleton `configure` pattern this is fine — but a second `configure` call that changes `server_renderer` to `NodeRenderer` while a password from the first call is still live would skip validation entirely. Low risk given the singleton usage pattern, but the constraint is implicit rather than structurally enforced. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/react-on-rails-pro-node-renderer/tests/configBuilder.test.ts (1)
79-206: Comprehensive test coverage for password validation logic.The test suite covers all critical scenarios:
- Production/staging environments require password
- Password via env or config bypasses validation
- Development/test environments don't require password
- Mixed env cases (RAILS_ENV vs NODE_ENV conflicts) fail closed
- Neither env set fails closed
- Late-loaded password works
Consider adding a symmetric test case for
RAILS_ENV=developmentwithNODE_ENV=productionto fully exercise the mixed-env logic (should require password). This would verify the reverse of the existing test at line 138-148.🧪 Optional: Add symmetric mixed-env test case
+ it('throws when NODE_ENV is production even if RAILS_ENV is development', () => { + process.env.NODE_ENV = 'production'; + process.env.RAILS_ENV = 'development'; + delete process.env.RENDERER_PASSWORD; + const processExit = mockProcessExit(); + + const { buildConfig } = loadConfigBuilderWithMockedLogger(); + + expect(() => buildConfig()).toThrow('process.exit: 1'); + expect(processExit).toHaveBeenCalledWith(1); + });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/react-on-rails-pro-node-renderer/tests/configBuilder.test.ts` around lines 79 - 206, Add a symmetric unit test to assert that when RAILS_ENV='development' and NODE_ENV='production' without RENDERER_PASSWORD the password validation still requires a password (i.e., buildConfig() should throw and process.exit should be called with 1); locate the tests using loadConfigBuilderWithMockedLogger() and buildConfig() in the existing "password validation in production-like environments" describe block and mirror the structure of the existing mixed-env test at the RAILS_ENV=production/NODE_ENV=development case to set process.env.RAILS_ENV='development', process.env.NODE_ENV='production', delete process.env.RENDERER_PASSWORD, call mockProcessExit(), then expect buildConfig() to throw and processExit toHaveBeenCalledWith(1).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/react-on-rails-pro-node-renderer/tests/configBuilder.test.ts`:
- Around line 79-206: Add a symmetric unit test to assert that when
RAILS_ENV='development' and NODE_ENV='production' without RENDERER_PASSWORD the
password validation still requires a password (i.e., buildConfig() should throw
and process.exit should be called with 1); locate the tests using
loadConfigBuilderWithMockedLogger() and buildConfig() in the existing "password
validation in production-like environments" describe block and mirror the
structure of the existing mixed-env test at the
RAILS_ENV=production/NODE_ENV=development case to set
process.env.RAILS_ENV='development', process.env.NODE_ENV='production', delete
process.env.RENDERER_PASSWORD, call mockProcessExit(), then expect buildConfig()
to throw and processExit toHaveBeenCalledWith(1).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 69e4ea1d-aefa-4f1c-9af6-67917d9b614f
📒 Files selected for processing (4)
docs/pro/node-renderer.mdpackages/react-on-rails-pro-node-renderer/src/shared/configBuilder.tspackages/react-on-rails-pro-node-renderer/tests/configBuilder.test.tsreact_on_rails_pro/lib/react_on_rails_pro/configuration.rb
✅ Files skipped from review due to trivial changes (1)
- docs/pro/node-renderer.md
|
Thanks for the thorough review. Addressed in a968c82: Security — Ruby/Node fail-closed asymmetry: Fixed. Code quality — duplicate condition: Fixed. Extracted the Minor — Minor — |
Review: Enforce Secure Renderer Password DefaultsSolid security hardening. The fail-closed invariant (require both Issues1.
2. In 3. Password enforcement requires both 4. The recommended snippet in config.renderer_password = ENV.fetch("RENDERER_PASSWORD")...will raise 5. Breaking change migration risk: Ruby doesn't auto-read Already documented in the PR, but worth surfacing in the review: users who set Minor / Non-blocking
OverallThe core logic is correct. The PR improves security posture meaningfully and the error messages are actionable. The main things to fix before merge are the noisy |
… test - Only emit the explicitUndefinedPassword warning in production-like environments where it is actionable; suppress it in dev/test where the missing password is harmless and the warning is noise. - Add test confirming buildConfig() does not throw when only RAILS_ENV is development and NODE_ENV is unset. - Add test confirming the warning is suppressed in development. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
Review: Enforce secure renderer password defaults for production-like envs Overall this is a solid security improvement with good test coverage. A few issues worth addressing before merge. CRITICAL: Ruby/Node environment check asymmetry The Ruby side only checks WARNING MESSAGE DEAD END In MINOR:
NIT: This is inconsistent with |
The warning fired in production-like environments suggesting users pass an empty string to clear the password, then immediately noted that empty strings fail validation in production. Simplified to clearly state that a password is always required and cannot be cleared. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Code ReviewThe PR correctly implements fail-closed security defaults for NodeRenderer. The core logic is sound: checking both NODE_ENV and RAILS_ENV, handling the explicit-undefined-password semantics, and mirroring behavior between Node and Ruby sides. Tests are comprehensive and cover the key cross-env combinations. A few observations worth considering: Diagnostic gap in envValuesUsed() The RENDERER_PASSWORD entry uses a short-circuit expression: If RENDERER_PASSWORD is set to an empty string in the environment, Asymmetry between replayServerAsyncOperationLogs and password enforcement
Missing test: empty-string RENDERER_PASSWORD env var Tests cover Minor: runtimeEnvsAllowDevelopmentDefaults() called twice in buildConfig Called once for the Overall this is a well-crafted security feature. The fail-closed defaults, Node/Ruby behavioral mirroring, and detailed error messages are all solid. The diagnostic inconsistency in |
| RENDERER_WORKERS_COUNT: !userConfig.workersCount && env.RENDERER_WORKERS_COUNT, | ||
| RENDERER_PASSWORD: !userConfig.password && env.RENDERER_PASSWORD && '<MASKED>', | ||
| // Explicit password overrides, including empty strings, intentionally suppress the env-derived value here. | ||
| RENDERER_PASSWORD: userConfig.password === undefined && env.RENDERER_PASSWORD && '<MASKED>', |
There was a problem hiding this comment.
If RENDERER_PASSWORD='' (empty string) is set in the environment, env.RENDERER_PASSWORD && '<MASKED>' evaluates to '' (falsy), so this diagnostic entry logs as false rather than indicating an empty value was attempted. sanitizedSettings handles this correctly with an explicit === '' check. Consider applying the same pattern here:
RENDERER_PASSWORD: userConfig.password === undefined && (
env.RENDERER_PASSWORD === '' ? '<EMPTY STRING>' : env.RENDERER_PASSWORD ? '<MASKED>' : false
),| return truthy(env.REPLAY_SERVER_ASYNC_OPERATION_LOGS); | ||
| } | ||
|
|
||
| return env.NODE_ENV?.toLowerCase() === 'development'; |
There was a problem hiding this comment.
This intentionally only checks NODE_ENV (not RAILS_ENV) so that replay logs follow the Node-side development experience regardless of RAILS_ENV. This differs from runtimeEnvsAllowDevelopmentDefaults() which requires all present envs to be dev/test for the fail-open password path. Worth a brief comment here noting the asymmetry is intentional, so future maintainers don't align it with the password enforcement logic.
…2829) Adds password enforcement for the Node renderer and Rails Pro configuration so that production-like environments (staging, production, qa, etc.) require RENDERER_PASSWORD to be set, while development and test environments remain passwordless for convenience. Key changes: - Node renderer: validatePasswordForProduction checks both NODE_ENV and RAILS_ENV, fails closed when neither is set, uses log.error + process.exit(1) for consistency - Rails Pro: validate_renderer_password_for_production checks ENV["RAILS_ENV"] directly (not Rails.env) to avoid silent skip when RAILS_ENV is unset - buildConfig refreshes runtime env-derived defaults on each call so late env initialization (e.g. dotenv) is picked up - password:undefined in buildConfig preserves env/default rather than clearing - Docs updated with environment matrix and breaking change noted in CHANGELOG Breaking change: Missing RENDERER_PASSWORD now causes a boot error in production-like environments. Existing production deployments that already set RENDERER_PASSWORD are unaffected.
…e-repo * origin/main: Improve create-react-on-rails-app fresh app onboarding (#2849) Add Docker deployment guide for Kamal, Kubernetes, and Control Plane (#2837) Reframe RSC migration docs around React on Rails patterns (#2661) Enforce secure renderer password defaults for production-like envs (#2829)
## Summary Addresses all three follow-up items from PR #2829: - **Ruby-side NODE_ENV checking**: `validate_renderer_password_for_production` now checks both `RAILS_ENV` and `NODE_ENV`, mirroring the Node-side `runtimeEnvsAllowDevelopmentDefaults()`. Surfaces misconfigurations (e.g. `NODE_ENV=production` + `RAILS_ENV=development`) at Rails boot time instead of at Node request time. - **Clarifying comment**: Added comment to `defaultReplayServerAsyncOperationLogs()` explaining the intentional asymmetry — it only checks `NODE_ENV` because async log replay is a JS debugging concern, not a security boundary. - **Unconditional validator call**: Moved `validate_renderer_password_for_production` from inside `setup_renderer_password` to `setup_config_values`, making enforcement unconditional and resilient to future refactors of the password resolution logic. Closes #2887 ## Test plan - [x] All 51 Ruby configuration specs pass (including 4 new cross-env tests) - [x] All 31 Node renderer configBuilder tests pass - [x] RuboCop clean - [x] ESLint + Prettier clean - [ ] CI passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Tightens production-like startup validation for the Node renderer password, which can cause previously misconfigured deployments to fail fast at Rails boot. Changes are localized to configuration/validation paths with expanded spec coverage. > > **Overview** > Ensures `RENDERER_PASSWORD` enforcement is **fail-closed and consistent across Ruby and Node** by validating against both `RAILS_ENV` and `NODE_ENV`, including rejecting mixed-env setups (e.g. `NODE_ENV=production` + `RAILS_ENV=development`). > > Moves `validate_renderer_password_for_production` to run unconditionally during Rails `setup_config_values`, updates the error message docs/matrix accordingly, and expands Ruby specs to cover the new cross-env scenarios. > > Adds a clarifying comment in the Node `configBuilder` that `defaultReplayServerAsyncOperationLogs()` intentionally keys only off `NODE_ENV` (debugging behavior, not a security boundary). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5a01f45. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Strengthened production validation for the Node renderer to prevent misconfiguration in mixed or production envs. * **Documentation** * Clarified default server operation logging behavior and updated environment-related messaging. * **Tests** * Expanded test coverage for environment-variable combinations to ensure consistent behavior across deployment and development scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
## Summary Addresses all three follow-up items from PR #2829: - **Ruby-side NODE_ENV checking**: `validate_renderer_password_for_production` now checks both `RAILS_ENV` and `NODE_ENV`, mirroring the Node-side `runtimeEnvsAllowDevelopmentDefaults()`. Surfaces misconfigurations (e.g. `NODE_ENV=production` + `RAILS_ENV=development`) at Rails boot time instead of at Node request time. - **Clarifying comment**: Added comment to `defaultReplayServerAsyncOperationLogs()` explaining the intentional asymmetry — it only checks `NODE_ENV` because async log replay is a JS debugging concern, not a security boundary. - **Unconditional validator call**: Moved `validate_renderer_password_for_production` from inside `setup_renderer_password` to `setup_config_values`, making enforcement unconditional and resilient to future refactors of the password resolution logic. Closes #2887 ## Test plan - [x] All 51 Ruby configuration specs pass (including 4 new cross-env tests) - [x] All 31 Node renderer configBuilder tests pass - [x] RuboCop clean - [x] ESLint + Prettier clean - [ ] CI passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Tightens production-like startup validation for the Node renderer password, which can cause previously misconfigured deployments to fail fast at Rails boot. Changes are localized to configuration/validation paths with expanded spec coverage. > > **Overview** > Ensures `RENDERER_PASSWORD` enforcement is **fail-closed and consistent across Ruby and Node** by validating against both `RAILS_ENV` and `NODE_ENV`, including rejecting mixed-env setups (e.g. `NODE_ENV=production` + `RAILS_ENV=development`). > > Moves `validate_renderer_password_for_production` to run unconditionally during Rails `setup_config_values`, updates the error message docs/matrix accordingly, and expands Ruby specs to cover the new cross-env scenarios. > > Adds a clarifying comment in the Node `configBuilder` that `defaultReplayServerAsyncOperationLogs()` intentionally keys only off `NODE_ENV` (debugging behavior, not a security boundary). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5a01f45. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Strengthened production validation for the Node renderer to prevent misconfiguration in mixed or production envs. * **Documentation** * Clarified default server operation logging behavior and updated environment-related messaging. * **Tests** * Expanded test coverage for environment-variable combinations to ensure consistent behavior across deployment and development scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
## Summary Addresses all three follow-up items from PR #2829: - **Ruby-side NODE_ENV checking**: `validate_renderer_password_for_production` now checks both `RAILS_ENV` and `NODE_ENV`, mirroring the Node-side `runtimeEnvsAllowDevelopmentDefaults()`. Surfaces misconfigurations (e.g. `NODE_ENV=production` + `RAILS_ENV=development`) at Rails boot time instead of at Node request time. - **Clarifying comment**: Added comment to `defaultReplayServerAsyncOperationLogs()` explaining the intentional asymmetry — it only checks `NODE_ENV` because async log replay is a JS debugging concern, not a security boundary. - **Unconditional validator call**: Moved `validate_renderer_password_for_production` from inside `setup_renderer_password` to `setup_config_values`, making enforcement unconditional and resilient to future refactors of the password resolution logic. Closes #2887 ## Test plan - [x] All 51 Ruby configuration specs pass (including 4 new cross-env tests) - [x] All 31 Node renderer configBuilder tests pass - [x] RuboCop clean - [x] ESLint + Prettier clean - [ ] CI passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Tightens production-like startup validation for the Node renderer password, which can cause previously misconfigured deployments to fail fast at Rails boot. Changes are localized to configuration/validation paths with expanded spec coverage. > > **Overview** > Ensures `RENDERER_PASSWORD` enforcement is **fail-closed and consistent across Ruby and Node** by validating against both `RAILS_ENV` and `NODE_ENV`, including rejecting mixed-env setups (e.g. `NODE_ENV=production` + `RAILS_ENV=development`). > > Moves `validate_renderer_password_for_production` to run unconditionally during Rails `setup_config_values`, updates the error message docs/matrix accordingly, and expands Ruby specs to cover the new cross-env scenarios. > > Adds a clarifying comment in the Node `configBuilder` that `defaultReplayServerAsyncOperationLogs()` intentionally keys only off `NODE_ENV` (debugging behavior, not a security boundary). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5a01f45. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Strengthened production validation for the Node renderer to prevent misconfiguration in mixed or production envs. * **Documentation** * Clarified default server operation logging behavior and updated environment-related messaging. * **Tests** * Expanded test coverage for environment-variable combinations to ensure consistent behavior across deployment and development scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Summary
RENDERER_PASSWORDwhen using NodeRenderer in production-like environments (anything other thandevelopmentortest). Both the Ruby configuration and the Node.jsbuildConfignow raise/throw on startup if no password is set.docs/pro/node-renderer.mdanddocs/oss/building-features/node-renderer/js-configuration.md.Closes #2795
Test plan
cd react_on_rails_pro && bundle exec rspec spec/react_on_rails_pro/configuration_spec.rb) — 8 new specs covering production/staging enforcement, dev/test bypass, ExecJS exemption, and URL-embedded passwordjest tests/configBuilder.test.ts) — 6 new specs covering production/staging enforcement, dev/test bypass, env var and config-object password🤖 Generated with Claude Code
Note
High Risk
Introduces fail-fast startup validation for NodeRenderer password in production-like environments, which is a breaking change that can prevent staging/production deployments from booting if misconfigured.
Overview
Enforces secure defaults for React on Rails Pro NodeRenderer authentication. The Node renderer now refuses to start in any non-
development/testenvironment (including whenNODE_ENV/RAILS_ENVare unset) unless a truthyRENDERER_PASSWORDis provided, with clearer diagnostics and masking of password values in logs.Rails-side Pro configuration adds matching validation: when using
NodeRenderer, it raises during configuration ifrenderer_passwordis missing/blank in production-like environments, and clarifies that the initializer must explicitly assignconfig.renderer_password = ENV.fetch("RENDERER_PASSWORD").Docs and release notes are updated to describe the new environment matrix and setup steps; tests are expanded on both Node and Ruby to cover the new enforcement and logging behavior, and link-check config excludes an intermittently timing-out PDF URL.
Written by Cursor Bugbot for commit f65da03. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
Documentation
Chores
Tests