Repository navigation
feat: add request-based access policy to server boundaries - #468
Closed
mukundshah wants to merge 1 commit into
Closed
mukundshah wants to merge 1 commit into
mukundshah wants to merge 1 commit into
Conversation
|
@mukundshah is attempting to deploy a commit to the NuxtLabs Team on Vercel. A member of the Team first needs to authorize it. |
|
👁️🗨️ Review this pull request with grouped, summarized diffs at: raw result💭 analyzed by {
"headSha": "67c0d13b0e04d9ba2483ddfcb56acdcd65a2c37f",
"result": {
"overallSummary": "Adds an independent, server-only request access policy (allowlisted peer addresses + optional async authorize callback) to `initDevframe`/`initHub`, enforced across HTTP routes and WebSocket admission/messages ahead of existing authentication, as a prerequisite for Vite DevTools' `internalIPs`/`enabled` options.",
"groups": [
{
"key": "request-access-policy",
"label": "Request access policy",
"summary": "Introduces a server-only `access` policy (allowlisted peer addresses plus an optional async authorize callback) enforced in the shared instance shell before HTTP routes dispatch and in every shared/caller-driven/sidecar WebSocket binding, both at upgrade and on each inbound message. `authorizeRequest` exposes the same check for routes mounted outside the instance, and a new DF0082 diagnostic reports callback failures.",
"category": "security",
"filePaths": [
"packages/devframe/src/node/request-access.ts",
"packages/devframe/src/node/instance-shell.ts",
"packages/devframe/src/rpc/transports/ws-server.ts",
"packages/devframe/src/rpc/transports/ws-bun.ts",
"packages/devframe/src/rpc/transports/ws-deno.ts",
"packages/devframe/src/adapters/initiate.ts",
"packages/hub/src/node/initiate.ts",
"packages/devframe/src/node/diagnostics.ts",
"packages/devframe/src/internal/index.ts",
"packages/devframe/src/node/index.ts"
],
"critical": true,
"fileNotes": [
{
"path": "packages/devframe/src/node/request-access.ts",
"text": "Core policy: normalizes IPv4/IPv6 addresses (including IPv4-mapped IPv6 and zone-aware canonicalization), builds an allowlist, and combines it with an optional async callback. Missing peer metadata or an empty allowlist denies by default."
},
{
"path": "packages/devframe/src/node/instance-shell.ts",
"text": "Wires the policy into the h3 app (host/origin checks plus peer authorization middleware), the Node HTTP fallback path, and all WS binding modes; also derives peer metadata for native Bun/Deno fetch handlers via `request.context.clientAddress`.",
"critical": true
},
{
"path": "packages/devframe/src/rpc/transports/ws-server.ts",
"text": "Rechecks authorization on every inbound WebSocket message, even for already-admitted connections, and closes the socket with DF0082 on callback failure.",
"critical": true
}
]
},
{
"key": "tests",
"label": "Tests and type snapshots",
"summary": "Unit tests for address normalization and policy evaluation, end-to-end hub tests covering HTTP/MCP/SSE/WebSocket admission and spoofed-header resistance, and the exported-type snapshots updated to reflect the new public `access`/`authorizeRequest` surface.",
"category": "tests",
"filePaths": [
"packages/devframe/src/node/__tests__/request-access.test.ts",
"packages/hub/src/node/__tests__/initiate.test.ts",
"tests/__snapshots__/tsnapi/@devframes/hub/initiate.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/initiate.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/internal.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/node.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/rpc/transports/ws-bun.snapshot.d.ts",
"tests/__snapshots__/tsnapi/devframe/rpc/transports/ws-deno.snapshot.d.ts"
]
},
{
"key": "docs",
"label": "Access policy docs",
"summary": "Documents the new `access` option, its security model (forwarding headers ignored, proxy caveats), compatibility guarantees, and the new DF0082 error.",
"category": "docs",
"filePaths": [
"docs/content/2.adapters/1.initiate.md",
"docs/content/6.errors/DF0082.md"
]
},
{
"key": "deps",
"label": "Dependency updates",
"summary": "Adds the `ws` dependency to the hub package (used by its new WebSocket-based access tests) and refreshes the lockfile.",
"category": "deps",
"filePaths": [
"packages/hub/package.json",
"pnpm-lock.yaml"
]
}
],
"schemaVersion": 1,
"source": "llm",
"generatedAt": "2026-10-29T05:24:41.636Z",
"model": "vercel-ai-gateway/anthropic/claude-sonnet-5",
"locale": "en"
}
} |
mukundshah
marked this pull request as draft
October 29, 2026 05:25
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add an independent, server-only request access policy to
initDevframeandinitHub.This is the prerequisite for Vite DevTools' requested
internalIPsand request-timeenabledcallback. Refs #467.The shared shell gates HTTP routes before dispatch, including discovery, connection metadata, UI bootstrap, SSE, and enabled MCP. Shared-server, caller-driven, and sidecar WebSocket bindings check admission and recheck each inbound message. A rejected message closes the socket, including connections already admitted through authentication.
authorizeRequest(req)lets a host apply the same policy to metadata served outside the hub base.Behavior And Compatibility
accesspreserves existing behavior.accessrequires a known peer address. Missing or invalid metadata denies access before the callback runs.internalIPsuses exact normalized address matching. An empty list denies everyone. IPv4-mapped IPv6 matches IPv4; IPv6 spellings are canonicalized.booleanorPromise<boolean>and run during authorization, never configuration resolution.auth: falsecannot override it. Callback errors remain visible; WebSocket failures close/reject the socket and report DF0082 with the original cause.Downstream Vite Contract
This PR supplies enforcement primitives, not the Vite public API. The Vite change must wait for an available upstream release and cover its externally mounted metadata routes with
authorizeRequest.enabled: falseinternalIPsonlyinternalIPsDownstream restrictions must also survive
clientAuth: false, the authentication-disable environment variable, trusted/build tokens, live standalone mode, and enabled MCP. These Vite-specific settings are not implemented or verified by this prerequisite.Security Considerations
Requestwithout a peer fails closed. Owned native listeners obtain metadata from Bun/Deno, and native WebSocket adapters use their runtime peer metadata.ws.urlservers own their transport and need their own policy. Routes outside the mounted instance must explicitly call the authorization helper.Verification
Passed:
pnpm lintpnpm knip(exit 0; existing UnoCSS missing-config warnings)pnpm test --run: 158 files, 1,784 tests passed, 13 skippedpnpm typecheck: 43 tasks passed, including typecheck coverage verificationpnpm build: 29 tasks passedpnpm test:runtime:bun: native WebSocket and shared-server SSE smoke checks passedgit diff --checkFocused coverage includes defaults, empty and denied allowlists, IPv4/IPv6 normalization and scopes, missing peers, spoofed forwarding headers, sync/async callbacks, combined restrictions, callback errors in the evaluator, auth enabled/disabled, HTTP metadata/bootstrap, hostile Host/Origin, MCP, SSE, shared/sidecar WebSocket admission, connection rechecks, and the external-route helper.
Native-runtime policy paths are typechecked. Bun's existing transport smoke tests passed; the new policy-specific integration tests run on Node. Deno is unavailable, so its runtime execution remains unverified. Vite-specific integration remains blocked on this prerequisite. The repository-required
i-have-adhdandsimple-englishskills were unavailable; the written contribution rules were followed and the availableantfu-designskill was loaded.