Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 34 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds embedded hooks, configurable health and metrics endpoints, router collision checks, and supporting docs, dependencies, and tests. ChangesEmbedded Tier-2 hooks and configuration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib.rs (1)
252-324: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winKeep configurable probe and verify paths exempt from maintenance.
maintenance_exemptis still seeded from the static defaults (/health/**,/metrics,/auth/verify). After this change, relocatinghealth.*,metrics.path, or the decider’s verify path means maintenance mode will return503for those endpoints, which breaks probe traffic and custom forward-auth even though the default paths were intentionally exempt before. Please derive the exemption list from the resolved configured paths when building the router state, and add a maintenance-mode regression test for the relocated paths.Also applies to: 380-399
🤖 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 `@src/lib.rs` around lines 252 - 324, The maintenance exemption list is still based on the static defaults, so custom health, metrics, and verify endpoints built in the router can be blocked during maintenance. Update the router-state setup around the health/metrics routes and the decider verify path so maintenance_exempt is derived from the resolved configured paths (health.path, health.live_path, health.ready_path, health.startup_path, metrics.path, and the configured verify path) instead of hardcoded defaults. Add a regression test covering relocated probe and verify paths to confirm they stay reachable in maintenance mode.
🤖 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 `@README.md`:
- Around line 201-243: The embedding example currently implies only http, bytes,
and serde_json are needed, but the hook implementation also uses async-trait via
#[async_trait::async_trait]. Update the README section around the embedding
hooks and the AuthDecider example to explicitly mention async-trait as a
required dependency for embedders, or otherwise note that the macro crate must
be added alongside the existing foundational types. Keep the guidance aligned
with the hook traits and ProxyServer::from_config example so readers can locate
the dependency requirement quickly.
In `@src/embed.rs`:
- Around line 253-259: The bearer_token helper only accepts "Bearer " and
"bearer ", so it still rejects other casing like "BEARER token". Update
bearer_token to match the authorization scheme case-insensitively before
trimming the token, while keeping the existing empty-token check and returning
the token from the same helper.
- Around line 153-161: The UserInfo 401 response handling in this branch
currently returns only the JSON body, so update the `backend.userinfo` match in
`src/embed.rs` to add a `WWW-Authenticate` header on every unauthorized
response. Use a plain `Bearer` challenge when `bearer_token(&headers)` yields no
credential, and use `Bearer error="invalid_token"` when
`backend.userinfo(&token)` returns `None`, while keeping the existing
`deny_response` path and JSON error payloads.
- Around line 191-193: The extra-route body buffering in handle() is currently
swallowing failures with unwrap_or_default(), which can pass an empty payload to
the handler. Update the body read path around axum::body::to_bytes in
src/embed.rs to return an error response immediately when buffering fails or
exceeds MAX_EXTRA_ROUTE_BODY, and only continue to the route handler when the
body is successfully read.
---
Outside diff comments:
In `@src/lib.rs`:
- Around line 252-324: The maintenance exemption list is still based on the
static defaults, so custom health, metrics, and verify endpoints built in the
router can be blocked during maintenance. Update the router-state setup around
the health/metrics routes and the decider verify path so maintenance_exempt is
derived from the resolved configured paths (health.path, health.live_path,
health.ready_path, health.startup_path, metrics.path, and the configured verify
path) instead of hardcoded defaults. Add a regression test covering relocated
probe and verify paths to confirm they stay reachable in maintenance mode.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 47f72a28-572b-4e0e-954e-00cfcb5148f5
📒 Files selected for processing (10)
Cargo.tomlREADME.mdsrc/config.rssrc/embed.rssrc/embed/tests.rssrc/hooks.rssrc/lib.rssrc/shield/store.rstests/embedded.rstests/hooks.rs
|
| Filename | Overview |
|---|---|
| src/lib.rs | Adds hook wiring, route reservation checks, configurable edge route mounting, verify route selection, and maintenance exemptions. |
| src/embed.rs | Adds the axum bridge for embedded auth, OIDC, and extra-route handlers. |
| src/config.rs | Adds health and metrics config with defaults and validation for built-in edge paths. |
| src/transcode/mod.rs | Adds route path enumeration for collision checks. |
| src/oidc/mod.rs | Adds OIDC path enumeration for collision checks. |
| src/hooks.rs | Adds public framework-agnostic hook interfaces for embedders. |
Reviews (9): Last reviewed commit: "fix: key route-collision detection on (m..." | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib.rs (1)
441-458: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winApply the verify-path collision guard to config-driven forward-auth too.
This precheck only runs in the injected-decider branch. A deployment that uses plain JWT forward-auth still merges
forward_auth.routes()without it, soauth.forward_auth.pathcolliding withhealth.*ormetrics.pathwill still hit Axum’s duplicate-route panic instead of returning the clean error this PR adds.🛠️ Proposed fix
let forward_auth = auth.as_ref().and_then(|built| { auth::forward::ForwardAuth::build(self.config.auth.as_ref()?, built.clone()) }); + + if (self.auth_decider.is_some() || forward_auth.is_some()) + && self.builtin_get_paths().iter().any(|p| p == &verify_path) + { + anyhow::bail!( + "verify path {verify_path:?} collides with a health/metrics endpoint path" + ); + } // Auth runs inside Shield (added first = inner): rate limiting sheds // load before any signature verification work. if let Some(auth) = auth { router = router.layer(axum::middleware::from_fn_with_state(auth, auth::middleware)); @@ // Forward-auth `/verify` endpoint. An injected AuthDecider owns it when // present (in-process PDP); otherwise the config-driven JWT ForwardAuth // backs it. Mounted after the auth layer so it is not itself JWT-gated. if let Some(decider) = &self.auth_decider { - // Guard against the verify path colliding with a built-in GET route - // (axum panics on duplicate path registration); fail with a clear - // error instead. `verify_path` was resolved once above. - if self.builtin_get_paths().iter().any(|p| p == &verify_path) { - anyhow::bail!( - "verify path {verify_path:?} collides with a health/metrics endpoint path" - ); - } let decider = decider.clone(); router = router.route( &verify_path, axum::routing::any(move |req: axum::extract::Request| { let decider = decider.clone();🤖 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 `@src/lib.rs` around lines 441 - 458, The verify-path collision check is only applied in the injected-decider branch, so plain JWT forward-auth can still merge `forward_auth.routes()` with a conflicting `auth.forward_auth.path`. Update the routing setup in `src/lib.rs` so the same `builtin_get_paths()` vs `verify_path` precheck runs before both the decider route registration and the `forward_auth.routes()` merge, returning the same clear `anyhow::bail!` error instead of letting Axum panic.
🤖 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 `@src/embed.rs`:
- Around line 153-170: Short-circuit missing Bearer credentials in the
`/userinfo` flow before calling `backend.userinfo`. In the `bearer_token`
handling inside `src/embed.rs`, avoid passing `token.as_deref().unwrap_or("")`
to `userinfo`; instead return the same unauthorized challenge path when
`bearer_token(&headers)` yields `None`, and only invoke `backend.userinfo(...)`
when a real token is present. Keep the existing `invalid_token` vs plain
`Bearer` challenge behavior in the match around `userinfo`.
---
Outside diff comments:
In `@src/lib.rs`:
- Around line 441-458: The verify-path collision check is only applied in the
injected-decider branch, so plain JWT forward-auth can still merge
`forward_auth.routes()` with a conflicting `auth.forward_auth.path`. Update the
routing setup in `src/lib.rs` so the same `builtin_get_paths()` vs `verify_path`
precheck runs before both the decider route registration and the
`forward_auth.routes()` merge, returning the same clear `anyhow::bail!` error
instead of letting Axum panic.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 90cbdb7f-1485-4c2a-8b8b-1b3e063eed24
📒 Files selected for processing (6)
README.mdsrc/config.rssrc/embed.rssrc/embed/tests.rssrc/lib.rstests/hooks.rs
Add axum-free Tier-2 embedding hooks so a service gets the full stateless REST/OIDC/forward-auth edge by adding the crate, with no axum in its own Cargo.toml: - AuthDecider: in-process forward-auth/PDP gate, runs inline on proxied routes and backs /verify (path set via with_verify_path) - OidcBackend: stateless discovery/JWKS/userinfo, paths consumer-supplied - with_extra_routes: framework-agnostic route adapter (request/response parts) - Make health and metrics endpoint paths configurable and disablable - Fix RedisStore intra-doc link in no-redis builds; docs.rs builds with the redis feature so the type is documented Hook contracts use only http/bytes/serde_json, so AuthDecider adds zero new dependencies. Standalone binary behavior is unchanged. BREAKING CHANGE: ProxyConfig gains `health` and `metrics` fields; code that builds ProxyConfig with a struct literal must add them. YAML configs are unaffected (serde defaults fill them in). Closes #66
…scheme - Reject oversized/unreadable extra-route bodies with 413 instead of passing an empty payload to the handler (a body-parsing handler would misread it) - Add RFC 6750 WWW-Authenticate Bearer challenge to userinfo 401 responses (plain Bearer when no credentials, error="invalid_token" when rejected) - Match the Authorization Bearer scheme case-insensitively
…sion-free - Reject duplicate built-in endpoint paths at config load (e.g. health.path equal to the default live_path) instead of panicking on duplicate route registration - Derive the maintenance exemption list from the resolved configured health, metrics, and verify paths so relocating them does not 503 probe/forward-auth traffic that was exempt at the default paths - Fail with a clear error when the verify path collides with a built-in GET endpoint path
The hook traits are #[async_trait], so embedders need async-trait alongside http/bytes/serde_json. None is an HTTP framework.
…llision - /userinfo now returns the 401 Bearer challenge without invoking the OIDC backend when no credentials are present (never call it with an empty token) - Apply the verify-path / built-in-GET collision guard before both the injected decider route and the config-driven JWT forward-auth merge, so plain forward-auth also returns a clean error instead of an axum duplicate-route panic
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@src/config.rs`:
- Around line 646-662: validate_edge_paths() only checks for duplicate built-in
endpoint paths, but Router::route expects valid route shapes. Update
validate_edge_paths in src/config.rs to also reject invalid health and metrics
paths before they reach Router::route, using the existing path fields on
self.health and self.metrics so bad config fails fast at validation time instead
of during startup routing.
In `@src/hooks.rs`:
- Around line 116-119: The `Hooks::userinfo` documentation still says `bearer`
may be an empty string, but `src/embed.rs` now bypasses the hook when
credentials are missing. Update the `userinfo` contract comment in `Hooks` to
state that it is only called with a present bearer token after the `Bearer `
prefix is stripped, and remove the empty-string/missing-credentials wording so
the doc matches the actual `userinfo` call path.
In `@src/lib.rs`:
- Around line 298-306: The middleware layering in the route setup is reversed:
auth_decider_gate is currently applied after auth::authz::middleware, so it
executes before authz instead of after it. Update the layering in src/lib.rs
where transcode_routes is built so the AuthDecider middleware is inserted before
the authz layer, preserving the intended authz -> AuthDecider -> handler order;
use the existing auth_decider_gate and auth::authz::middleware symbols to adjust
the wrapping sequence.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: a48eb3b2-a81d-4752-965d-3e02cea645a6
📒 Files selected for processing (10)
Cargo.tomlREADME.mdsrc/config.rssrc/embed.rssrc/embed/tests.rssrc/hooks.rssrc/lib.rssrc/shield/store.rstests/embedded.rstests/hooks.rs
…cider - builtin_get_paths now includes the enabled OpenAPI spec/docs paths, so a verify path colliding with /openapi.json or /docs is rejected with a clear error instead of an axum duplicate-route panic - validate_edge_paths rejects paths without a leading '/' (axum would reject the route shape at construction otherwise) - order the proxied-route gates authz -> AuthDecider -> handler (the decider layer is added inner, authz outer), so ext_authz runs first and the decider sees headers it injected; the previous order was inverted - correct the OidcBackend::userinfo doc: it only ever receives a present, non-empty bearer token (missing credentials are rejected before the call)
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/lib.rs (2)
443-467: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winValidate
verify_pathbefore route registration.with_verify_path()and theauth.forward_auth.pathfallback can both supply a path without a leading/; when auth/forward-auth is enabled, that reachesrouter.route(...)and can panic instead of returningErr.🤖 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 `@src/lib.rs` around lines 443 - 467, Validate verify_path before calling router.route in the routing setup inside src/lib.rs, because with_verify_path() and the auth.forward_auth.path fallback can yield a path without a leading slash and cause a panic. Add normalization/validation right after the verify_path is chosen and before the collision check and route registration, so invalid paths are rejected with an error instead of reaching the AuthDecider/forward-auth verify endpoint mount.
203-222: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftInclude all pre-mounted routes in the verify collision check.
builtin_get_paths()only covers health, metrics, and OpenAPI, butoidc_routes,embed::extra_routes_router(...), andtranscode_routesare merged beforeverifyis registered. A custom/userinfo, extra route, or transcoded GET path can still collide and panic at router construction; guard the full reserved path set instead.🤖 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 `@src/lib.rs` around lines 203 - 222, The verify collision guard is incomplete because builtin_get_paths only returns health, metrics, and OpenAPI paths, while oidc_routes, embed::extra_routes_router(...), and transcode_routes are mounted before verify and can still conflict. Update the reserved-path collection used by the verify registration check to include every pre-mounted GET route from those route builders, and ensure the guard in builtin_get_paths (or its caller) reflects the full set of paths that can be registered before verify.src/config.rs (1)
647-666: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winValidate OpenAPI paths with the other built-in edge paths.
openapi.pathandopenapi.docs_pathare also mounted, so a collision with health/metrics (or between the two OpenAPI routes) can still panic when the router is assembled.Proposed fix
if self.metrics.enabled { check("metrics.path", &self.metrics.path)?; } + if let Some(openapi) = self.openapi.as_ref().filter(|o| o.enabled) { + check("openapi.path", &openapi.path)?; + check("openapi.docs_path", &openapi.docs_path)?; + } Ok(()) }🤖 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 `@src/config.rs` around lines 647 - 666, The built-in path validation in validate_edge_paths currently checks only health and metrics, so openapi.path and openapi.docs_path can still collide with those routes or with each other and later panic during router setup. Extend the existing HashSet-based duplicate/path-prefix checks in validate_edge_paths to include both OpenAPI routes when openapi is enabled, using the same check helper and distinct labels so all built-in edge paths are validated consistently.
🤖 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.
Outside diff comments:
In `@src/config.rs`:
- Around line 647-666: The built-in path validation in validate_edge_paths
currently checks only health and metrics, so openapi.path and openapi.docs_path
can still collide with those routes or with each other and later panic during
router setup. Extend the existing HashSet-based duplicate/path-prefix checks in
validate_edge_paths to include both OpenAPI routes when openapi is enabled,
using the same check helper and distinct labels so all built-in edge paths are
validated consistently.
In `@src/lib.rs`:
- Around line 443-467: Validate verify_path before calling router.route in the
routing setup inside src/lib.rs, because with_verify_path() and the
auth.forward_auth.path fallback can yield a path without a leading slash and
cause a panic. Add normalization/validation right after the verify_path is
chosen and before the collision check and route registration, so invalid paths
are rejected with an error instead of reaching the AuthDecider/forward-auth
verify endpoint mount.
- Around line 203-222: The verify collision guard is incomplete because
builtin_get_paths only returns health, metrics, and OpenAPI paths, while
oidc_routes, embed::extra_routes_router(...), and transcode_routes are mounted
before verify and can still conflict. Update the reserved-path collection used
by the verify registration check to include every pre-mounted GET route from
those route builders, and ensure the guard in builtin_get_paths (or its caller)
reflects the full set of paths that can be registered before verify.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fc5a97b5-f553-42e2-95b8-1e968c27c04f
📒 Files selected for processing (4)
src/config.rssrc/hooks.rssrc/lib.rstests/hooks.rs
|
T-Rex pricing update — T-Rex was free through June 2026. Effective July 1, 2026, T-Rex adds 2 credits on top of the standard 1-credit review (3 total). T-Rex settings |
- reserved_get_paths now collects every route mounted before verify: health, metrics, OpenAPI, the OIDC surface (injected backend or config-driven static discovery), embedder extra routes, and the transcoded REST routes (transcode::route_paths). A verify path colliding with any of them is now a clear error instead of an axum duplicate-route panic - reject a verify path without a leading '/' before route registration - validate_edge_paths also checks OpenAPI spec/docs paths for shape and duplicates
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib.rs (1)
203-241: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winApply the reserved-path check to every mounted edge route. The helper already collects health, metrics, OpenAPI, OIDC, extra-route, and transcode paths, but it is only used for
/verify. Any collision among mounted routes can still reach Axum and abort startup with a duplicate-route panic.🤖 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 `@src/lib.rs` around lines 203 - 241, The reserved-path guard in reserved_get_paths currently covers all mounted edge route categories, but the check is only being applied for /verify, so other mounted routes can still collide and trigger an Axum duplicate-route panic at startup. Update the route registration flow in lib.rs to run this reserved-path validation for every mounted edge route (not just verify), reusing reserved_get_paths along the mounting path so any conflicting path is rejected with the existing clear error before registration.
🤖 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.
Outside diff comments:
In `@src/lib.rs`:
- Around line 203-241: The reserved-path guard in reserved_get_paths currently
covers all mounted edge route categories, but the check is only being applied
for /verify, so other mounted routes can still collide and trigger an Axum
duplicate-route panic at startup. Update the route registration flow in lib.rs
to run this reserved-path validation for every mounted edge route (not just
verify), reusing reserved_get_paths along the mounting path so any conflicting
path is rejected with the existing clear error before registration.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 55df3552-868b-4e16-b326-b6a9498d1787
📒 Files selected for processing (6)
src/config.rssrc/hooks.rssrc/lib.rssrc/oidc/mod.rssrc/transcode/mod.rstests/hooks.rs
Run the reserved-path duplicate scan across the whole mounted edge (built-in routes, OIDC surface, extra routes, transcoded paths, and the verify endpoint) up front, before any router is constructed. Any collision now returns a clear error instead of reaching axum and panicking at .route/.merge during startup.
There was a problem hiding this comment.
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 `@src/lib.rs`:
- Around line 261-277: The mounted verify path and the path used for
validation/exemptions are diverging in the JWT forward-auth flow, so collisions
and maintenance exemptions can apply to the wrong route. Update the logic around
self.resolved_verify_path(), ForwardAuth::build, and forward_auth.routes() so
the same path that is actually mounted is also the one added to mounted and used
for maintenance exemptions; keep the decider-driven route using the override,
but for config-driven forward auth validate/exempt auth.forward_auth.path unless
the override is explicitly threaded through.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 6474cf96-98b6-42f6-b0af-1c166c091965
📒 Files selected for processing (2)
src/lib.rstests/hooks.rs
The with_verify_path override applies only to an injected AuthDecider's verify route; config-driven JWT forward-auth always mounts at auth.forward_auth.path. Introduce mounted_verify_path() that returns the branch-correct path (decider → override/config/default; config forward-auth → forward_auth.path, only when mode is jwt), and use it for both the duplicate-route guard and the maintenance-exempt list. Previously a with_verify_path override hid a config forward_auth.path collision and exempted the wrong path under maintenance.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib.rs (1)
294-306: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winValidate every mounted path before router construction.
reserved_get_paths()includes OIDC and extra-route paths, and those are later handed toRouter::route(), which panics on paths that don’t start with/. The current guard only checksverify_path, so a malformed backend or extra-route path can still turn startup into a panic instead of a build error.Proposed fix
if let Some(vp) = &verify_path { if !vp.starts_with('/') { anyhow::bail!("verify path {vp:?} must start with '/'"); } mounted.push(vp.clone()); } + for path in &mounted { + if !path.starts_with('/') { + anyhow::bail!("route path {path:?} must start with '/'"); + } + } let mut seen = std::collections::HashSet::with_capacity(mounted.len());🤖 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 `@src/lib.rs` around lines 294 - 306, The startup path validation only checks verify_path, but mounted also includes values from reserved_get_paths() that later go into Router::route(). Add a pre-router validation pass over every entry in mounted to ensure each path starts with '/' and return an anyhow::bail! build error if any do not. Keep the existing duplicate-path check, and make the fix in the mounting logic around reserved_get_paths(), mounted, and Router::route() so malformed backend or extra-route paths can’t cause a panic.
🤖 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 `@tests/hooks.rs`:
- Around line 420-433: The YAML snippet in `ProxyConfig::from_yaml_str` is
embedding `pem_path.display()` directly into a double-quoted scalar, which can
break on Windows because backslashes are treated as escapes. Update the test to
pass an escaped/serialized path string when interpolating the
`public_key_pem_file` value so the generated YAML remains valid across
platforms.
---
Outside diff comments:
In `@src/lib.rs`:
- Around line 294-306: The startup path validation only checks verify_path, but
mounted also includes values from reserved_get_paths() that later go into
Router::route(). Add a pre-router validation pass over every entry in mounted to
ensure each path starts with '/' and return an anyhow::bail! build error if any
do not. Keep the existing duplicate-path check, and make the fix in the mounting
logic around reserved_get_paths(), mounted, and Router::route() so malformed
backend or extra-route paths can’t cause a panic.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 6368cf48-ba68-4c4b-9d0f-b0b1b0ea912d
📒 Files selected for processing (2)
src/lib.rstests/hooks.rs
reserved_get_paths() includes consumer-supplied OIDC-backend and extra-route paths that are handed to Router::route(), which panics on a path without a leading '/'. Validate the leading '/' for every mounted path (not only the verify path) before building the router, so a malformed backend/extra-route path is a clean build error. Also embed the temp PEM path in test YAML with forward slashes so the config parses on Windows runners.
Same-path routes with different methods (e.g. an embedder registering GET /c and POST /c through the extra-route adapter, which merges them by method) are a legal shape. The collision guard now keys on (method, path): only a repeated (method, path) is a conflict. The verify endpoint answers all methods, so it is tracked as '*' and conflicts with any route on its path. route_paths and reserved_routes now carry the HTTP method for each route.
Summary
Adds the axum-free Tier-2 embedding hooks so a service gets the full
stateless REST/OIDC/forward-auth edge by adding the crate, with no
axuminits own
Cargo.toml(cargo tree -i axumshows axum only understructured-proxy). Also makes the previously hardcoded edge routesconfigurable. The default build stays a stateless data plane (README Non-goals
hold).
Hooks (
structured_proxy::hooks, all axum-free)AuthDecider— in-process forward-auth / PDP decision. Runs inline onevery proxied request and backs
/verify(path viawith_verify_path).Contract uses only
http/bytes(zero new deps);Allowinjects headers(client-forged copies stripped),
Denyshort-circuits,Redirect302 inline/ 401+
Locationon/verify.OidcBackend— stateless discovery / JWKS / userinfo; every path isconsumer-supplied; supersedes config-driven static discovery.
with_extra_routes— framework-agnostic route adapter (request parts in,response parts out); merges methods on a shared path.
Configurable edge routes
health(path / live / ready / startup) andmetrics(path) are nowconfigurable and disablable via YAML; defaults unchanged.
Fixes (in scope)
RedisStoreintra-doc link no longer warns in no-redisbuilds(
cfg_attr-gated); docs.rs builds with theredisfeature so the type isdocumented.
Breaking change
feat!—ProxyConfiggainshealthandmetricsfields. Code that buildsProxyConfigwith a struct literal must add them. YAML configs areunaffected (serde defaults). Title carries
!so squash-merge yields a MAJORbump.
Testing
cargo nextest run --workspace: 160 passed (+28), incl. negative / edge /security paths (forged-header strip, malformed location, unsupported method
skip, no-forwarding-header fallback, disabled/relocated routes).
cargo clippy --all-targets -- -D warningsclean (default andredis).cargo doc -D warningsclean (default andredis); doc-tests pass;aws_lc_rsbackend builds.Follow-ups (separate issues)
bfffeature: stateful BFF + OIDC authorization server, default-off, composesvia
with_extra_routes.Closes #66