You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 67c0d13
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/content/2.adapters/1.initiate.md
+28Lines changed: 28 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -131,6 +131,34 @@ Fetch handlers only hand over `Request`s, so the host framework binds the RPC so
131
131
132
132
The running devframe **gates by default**. The interactive OTP handler wires automatically, printing its code/magic-link banner when an untrusted browser client asks for a code (`rpc.requestAuthCode()`); an already-authorized page triggers no print. The magic link's origin comes from the `origin` option, or is derived from a request whose own origin is loopback or exactly matches an `allowedOrigins` entry. A non-loopback deployment (behind a proxy, on a LAN, on a public host) sets `origin` explicitly so the magic link resolves to the intended address; a raw inbound `Host` header and forwarded headers are never trusted. Pass `auth: false` for single-user localhost, or a `DevframeAuthHandler` for a custom scheme.
133
133
134
+
## Request access policy
135
+
136
+
Use the server-only `access` option on `initDevframe` or `initHub` to restrict requests by connected peer address and an optional callback:
Both restrictions must pass. Addresses use exact matching; IPv6 addresses are normalized and IPv4-mapped IPv6 addresses match their IPv4 form. An empty `internalIPs` list denies everyone. With `access` configured, a missing peer address denies the request before invoking the callback. `authorize` receives a typed `RequestAccessContext` and returns `boolean` or `Promise<boolean>`. It runs during authorization, after setup, rather than while resolving configuration. Callback failures produce HTTP errors or close the WebSocket with a diagnostic containing the cause.
149
+
150
+
The policy runs before HTTP routes, including connection metadata, UI bootstrap, SSE RPC, and enabled MCP endpoints. It also runs before WebSocket admission and every inbound message, including messages from authenticated connections. A changed policy takes effect on the next request or inbound message; it does not proactively cancel an idle connection or retract data already sent. Routes mounted outside the instance must call `await devtools.authorizeRequest(req)` before returning credentials or capabilities. Return HTTP 403 when that helper returns `false`; let callback errors reach the server error handler.
151
+
152
+
Authentication stays independent: `access` adds a restriction, while `auth: false` explicitly opts out of interactive authentication. Trusted tokens and authentication opt-outs cannot bypass the request policy. MCP keeps its own origin and authorization checks after this gate. With `access` omitted, existing behavior is preserved.
153
+
154
+
::warning
155
+
Use addresses from the actual connection. Forwarding headers such as `X-Forwarded-For`, `Forwarded`, and `X-Real-IP` are ignored. Behind a reverse proxy the peer is the proxy; allowing its address grants this gate to every caller it forwards. Keep authentication enabled unless another trusted boundary limits those callers. Host and Origin checks remain active; configure `allowedOrigins` for a non-loopback origin.
156
+
::
157
+
158
+
The Node middleware obtains peer metadata from the socket. Fetch hosts must preserve trusted server request metadata (`request.context.clientAddress` or the runtime's `request.ip`); a plain browser-style `Request` has neither and is denied. Owned Bun and Deno listeners obtain addresses from their runtime. Keep callbacks and policy values in server configuration; connection metadata contains neither.
159
+
160
+
Live standalone instances use the same policy. An external `ws.url` server owns its transport and needs its own policy. Static build files require access control in the web server serving them; runtime callbacks apply to live requests only.
161
+
134
162
## Relation to the other adapters
135
163
136
164
`createDevServer`, `devframeViteBridge` (`@devframes/vite`), and `@devframes/next` are assembled from it internally. To host **many** devframes, use [`initHub`](/guide/hub-initiate).
description: 'Request access authorization failed on a WebSocket connection.'
4
+
---
5
+
6
+
## Message
7
+
8
+
> Request access authorization failed on a WebSocket connection.
9
+
10
+
## Cause
11
+
12
+
The server-side request access callback threw an error or rejected its promise during an upgrade or an inbound message. The socket is rejected or closed before the request can reach RPC dispatch. The diagnostic retains the original error as its cause.
13
+
14
+
## Example
15
+
16
+
```ts
17
+
initHub({
18
+
access: {
19
+
authorize: async () =>awaitcheckInternalAccess(),
20
+
},
21
+
})
22
+
```
23
+
24
+
## Fix
25
+
26
+
Inspect the reported cause and repair the callback or its dependency. Return `false` for an expected denial.
27
+
28
+
## Source
29
+
30
+
-[`packages/devframe/src/rpc/transports/ws-server.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/rpc/transports/ws-server.ts) reports callback failures during upgrades and inbound messages.
0 commit comments