feat(tokens): implement path-scoped relayfile tokens#42
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR implements the full ChangesPath-scoped token issuance implementation
Sequence Diagram(s)sequenceDiagram
participant Client
participant AuthMiddleware
participant TokenRoute
participant Storage
participant JWTLib
Client->>AuthMiddleware: POST /v1/tokens/path with relay_ws_* or x-api-key
AuthMiddleware->>AuthMiddleware: Extract workspace token from Bearer or x-api-key
AuthMiddleware->>TokenRoute: Forward authenticated request
TokenRoute->>TokenRoute: Validate relayauth:token:create:* scope
TokenRoute->>Storage: Resolve workspace and agent identities
TokenRoute->>TokenRoute: Normalize paths, expand to relayfile:fs:* scopes
TokenRoute->>TokenRoute: Validate scopes within workspace token grant
TokenRoute->>Storage: Create path token identity
TokenRoute->>JWTLib: Issue access token with path meta + scopes
TokenRoute->>JWTLib: Issue refresh token with path claims
JWTLib->>JWTLib: Wrap tokens with relay_pa_ prefix
TokenRoute->>Client: Return PathTokenResponse with relay_pa_* pair
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 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 unit tests (beta)
Comment |
| } | ||
|
|
||
| const [scheme, token] = authorization.split(/\s+/, 2); | ||
| if (scheme !== "Bearer" || !token.startsWith(WORKSPACE_TOKEN_PREFIX)) { |
There was a problem hiding this comment.
🔴 TypeError crash in extractBearerWorkspaceToken when Authorization header is "Bearer" with no token
When a request includes Authorization: Bearer (with no token value after the scheme), extractBearerWorkspaceToken crashes with a TypeError. At line 52, authorization.split(/\s+/, 2) on the string "Bearer" yields ["Bearer"], so token is undefined. At line 53, scheme !== "Bearer" evaluates to false (scheme IS "Bearer"), so the right side !token.startsWith(WORKSPACE_TOKEN_PREFIX) is evaluated — calling .startsWith() on undefined throws TypeError: Cannot read properties of undefined (reading 'startsWith'). This crashes the apiKeyAuth() middleware, which is mounted on all /v1/tokens/*, /v1/identities/*, and /v1/api-keys/* routes (packages/server/src/server.ts:128-131), making all those endpoints vulnerable to a trivial DoS from any client sending Authorization: Bearer. Note that the analogous authenticate() function in packages/server/src/lib/auth.ts:39 correctly guards against this with !token.
| if (scheme !== "Bearer" || !token.startsWith(WORKSPACE_TOKEN_PREFIX)) { | |
| if (scheme !== "Bearer" || !token || !token.startsWith(WORKSPACE_TOKEN_PREFIX)) { |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Fixed in 8339b71 by guarding !token before startsWith(), with a regression test covering Authorization: Bearer on an apiKeyAuth-mounted route.
Summary
/v1/tokens/path501 stub with realrelay_pa_*path token pair issuancex-api-keyand the cloud-compatibleAuthorization: Bearer relay_ws_*formSelf-review
Bearer relay_ws_*is treated as API-key-backed workspace-token auth.workspaceTokenIdmetadata, so existing workspace-token revocation checks still close the lineage./foo/**normalizes to/foo/*, and arbitrary scopes outside the requested path set are rejected before issuance.Verification
npm --workspace @relayauth/server exec -- node --test --import tsx src/__tests__/tokens-route.test.tsnpm --workspace @relayauth/sdk exec -- node --test --import tsx src/__tests__/client-tokens.test.tsnpm --workspace @relayauth/server run typechecknpm --workspace @relayauth/sdk run typechecknpm --workspace @relayauth/types run typecheckgit diff --checkCloses #40