-
Notifications
You must be signed in to change notification settings - Fork 182
Gate JWT expiration validation behind env var #6166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds an environment-controlled feature gate to optionally disable JWT expiration validation, makes token Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant Auth as auth::verify_token
participant Env as env (FOREST_JWT_DISABLE_EXP_VALIDATION)
Caller->>Auth: verify_token(token)
Auth->>Env: is_env_truthy(FOREST_JWT_DISABLE_EXP_VALIDATION)
alt env truthy (disable exp validation)
note right of Auth #E6F7FF: allow missing `exp` and\nskip expiration checks
Auth-->>Caller: perform other claim checks -> success/failure
else env falsy (normal validation)
note right of Auth #FFF4E6: require `exp` and\ncheck expiration against now
Auth->>Auth: if `exp` present and not expired -> success
Auth-->>Caller: expired or missing `exp` -> failure
end
sequenceDiagram
participant Daemon
participant Env as env (FOREST_JWT_DISABLE_EXP_VALIDATION)
participant RPC as RPC service
Daemon->>Env: is_env_truthy(FOREST_JWT_DISABLE_EXP_VALIDATION)
alt env truthy
Daemon->>Daemon: log warning about disabled JWT exp validation
end
Daemon->>RPC: spawn RPC service
RPC-->>Daemon: started
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🪛 LanguageTooldocs/docs/users/reference/env_variables.md[style] ~53-~53: ‘Whether or not’ might be wordy. Consider a shorter alternative. (EN_WORDINESS_PREMIUM_WHETHER_OR_NOT) [grammar] ~80-~80: There might be a mistake here. (QB_NEW_EN) ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
Comment |
There was a problem hiding this comment.
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)
docs/docs/users/reference/env_variables.md (1)
53-53: Minor style suggestion: simplify wording.The phrase "Whether or not to disable" could be shortened to "Whether to disable" for improved clarity.
-| `FOREST_JWT_DISABLE_EXP_VALIDATION` | 1 or true | empty | 1 | Whether or not to disable JWT expiration validation | +| `FOREST_JWT_DISABLE_EXP_VALIDATION` | 1 or true | empty | 1 | Whether to disable JWT expiration validation |
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
CHANGELOG.md(1 hunks)docs/docs/users/reference/env_variables.md(1 hunks)src/auth/mod.rs(4 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/docs/users/reference/env_variables.md
[style] ~53-~53: ‘Whether or not’ might be wordy. Consider a shorter alternative.
Context: ... | Whether or not to disable JWT expiration validation ...
(EN_WORDINESS_PREMIUM_WHETHER_OR_NOT)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: tests-release
- GitHub Check: tests
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: Build Ubuntu
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: All lint checks
🔇 Additional comments (4)
src/auth/mod.rs (4)
6-6: LGTM!The import is necessary for the new environment variable check and is correctly placed.
29-30: LGTM!Making
expoptional with#[serde(default)]properly supports tokens without expiration while maintaining backward compatibility with existing tokens that have the field.
38-38: LGTM!Correctly wraps the expiration value in
Someto match the new optional type.
69-75: LGTM!The helper function cleanly creates tokens without expiration for testing purposes. The implementation correctly sets
exp: None.
There was a problem hiding this 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
♻️ Duplicate comments (1)
src/auth/mod.rs (1)
45-52: Warn when globally bypassing exp and simplify claim handling.Emit a warning to surface the security tradeoff and simplify by mutating required_spec_claims in place.
- let mut claims = validation.required_spec_claims.clone(); - claims.remove("exp"); - let buff: Vec<_> = claims.iter().collect(); - validation.set_required_spec_claims(&buff); - validation.validate_exp = false; + tracing::warn!( + "JWT expiration validation is disabled via FOREST_JWT_DISABLE_EXP_VALIDATION; \ + use only in development/testing or explicit cross-system token sharing." + ); + validation.required_spec_claims.remove("exp"); + validation.validate_exp = false;
🧹 Nitpick comments (2)
src/auth/mod.rs (2)
29-31: Avoid serializing "exp": null; omit the claim when None.Add skip_serializing_if so tokens without exp don’t emit a null value and better mirror peers (e.g., Lotus).
- #[serde(default)] - exp: Option<usize>, + #[serde(default, skip_serializing_if = "Option::is_none")] + exp: Option<usize>,
68-75: This currently encodes "exp": null; ensure the field is omitted instead.As written, exp: None will serialize to null. If the intent is to produce tokens without the exp claim, rely on skip_serializing_if on Claims.exp (see earlier comment). No further changes to this helper needed once that attribute is added.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/auth/mod.rs(4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: tests
- GitHub Check: tests-release
- GitHub Check: Build Ubuntu
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: All lint checks
- GitHub Check: Check
- GitHub Check: Deploy to Cloudflare Pages
🔇 Additional comments (2)
src/auth/mod.rs (2)
6-6: LGTM on using central env helper.Using is_env_truthy for gating is consistent and clear.
38-39: Wrapping exp in Some(...) is correct.
There was a problem hiding this 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
🧹 Nitpick comments (1)
src/auth/mod.rs (1)
128-130: Consider RAII guard for env var cleanup on panic.The test logic is correct and properly validates both tokens without expiration and expired tokens when validation is disabled. The
unsafeblocks are necessary becausestd::env::set_varandstd::env::remove_varare inherently unsafe in Rust (they can cause data races).However, if the test panics between setting and removing the env var, the cleanup at line 147-149 won't execute, potentially affecting subsequent tests. Consider implementing the RAII guard pattern suggested in the previous review to ensure cleanup even on panic:
struct EnvVarGuard { key: &'static str, } impl EnvVarGuard { fn new(key: &'static str, value: &str) -> Self { unsafe { std::env::set_var(key, value); } Self { key } } } impl Drop for EnvVarGuard { fn drop(&mut self) { unsafe { std::env::remove_var(self.key); } } }Then replace lines 128-130 and 147-149 with:
let _guard = EnvVarGuard::new("FOREST_JWT_DISABLE_EXP_VALIDATION", "1");Note: This addresses the previous review feedback which you marked as "Done" but wasn't fully implemented.
Also applies to: 147-149
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/auth/mod.rs(4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Check
- GitHub Check: All lint checks
- GitHub Check: tests-release
- GitHub Check: tests
- GitHub Check: Build Ubuntu
- GitHub Check: cargo-publish-dry-run
- GitHub Check: Build MacOS
- GitHub Check: Build forest binaries on Linux AMD64
- GitHub Check: Deploy to Cloudflare Pages
🔇 Additional comments (5)
src/auth/mod.rs (5)
29-30: LGTM! Optional expiration field correctly implemented.The change from
usizetoOption<usize>with#[serde(default)]correctly allows tokens without expiration while maintaining backward compatibility with tokens that have an expiration.
38-38: LGTM! Correctly wraps expiration in Some().The change properly wraps the expiration timestamp in
Some()to match the newOption<usize>type.
67-68: LGTM! Enables test serialization for env var safety.The
serial_testimport enables the#[serial]attribute, which helps prevent concurrent tests from interfering with each other's environment variable modifications.
69-76: LGTM! Test helper correctly creates tokens without expiration.The helper function properly constructs a token with
exp: None, which is essential for testing the new optional expiration field behavior.
79-79: LGTM! Prevents test interference.Adding
#[serial]to this test prevents potential interference from the new test that manipulates environment variables, even though this test doesn't use env vars directly.
Summary of changes
Changes introduced in this pull request:
FOREST_JWT_DISABLE_EXP_VALIDATIONenv varThis PR was motivated by a situation where Lotus and Forest nodes use the same private key, and
JWTexpiration validation is disabled for Forest—allowing the same Auth Bearer token (created withlotus auth create-token) to work for both clients.Reference issue to close (if applicable)
Closes
Other information and links
Change checklist
Summary by CodeRabbit
New Features
Documentation
Behavior
Tests