Skip to content

DTK0013: Unauthorized RPC Access

Message

Unauthorized access to method {name} from client [{clientId}]

Cause

This error is thrown by the RPC resolver in createWsServer() when an untrusted WebSocket client attempts to call a protected RPC method. Any method whose name starts with anonymous: is exempt and callable before trust — that's the auth handshake (anonymous:devframe:auth and anonymous:devframe:auth:exchange). Every other method requires the client to be trusted.

A client becomes trusted through one of these mechanisms:

  1. Client auth is disabled (build mode, clientAuth: false, or VITE_DEVTOOLS_DISABLE_CLIENT_AUTH=true) — all clients are auto-trusted.
  2. One-time code exchange — an untrusted browser is shown a one-time code in the terminal, along with a ?devframe_otp= magic link. Entering the code (or opening the link) exchanges it via anonymous:devframe:auth:exchange for a node-issued bearer token; the browser persists that token and re-presents it (anonymous:devframe:auth) on reconnect.
  3. Static auth tokens — the token matches one listed in devtools.clientAuthTokens in your Vite config.

If none of these conditions are met, the client is untrusted and any call to a protected method triggers this error. A trusted browser can also hand its access back from Settings → Advanced → Revoke Access, which revokes its token and drops it to untrusted.

Example

An untrusted browser calling a protected method:

ts
// The browser hasn't completed the auth handshake yet — it's untrusted.
await rpc.call('my-plugin:get-data')
// Error: Unauthorized access to method "my-plugin:get-data" from client [abc123]

Fix

Authorize the browser. When an untrusted client connects, the dev-server terminal prints a one-time code and a magic link:

  • Enter the code in the DevTools authorization prompt, or
  • Open the magic link (<origin>/?devframe_otp=<code>) — the client reads the code, exchanges it for a bearer token, and persists it for future reconnects.

For automated setups (CI, shared machines), configure static trusted tokens instead — a client presenting one via the devframe_auth_token connection parameter is trusted without the interactive step:

ts
import { DevTools } from '@vitejs/devtools'
// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    DevTools(),
  ],
  devtools: {
    enabled: true,
    clientAuthTokens: ['your-trusted-token'],
  },
})

If you are developing locally and want to skip authentication entirely, see DTK0008 for how to disable client auth.

Source

  • packages/core/src/node/ws.ts — the WebSocket RPC resolver in createWsServer() throws DTK0013 when an untrusted client invokes a method that isn't anonymous:-prefixed (devframe's isAnonymousRpcMethod).

Released under the MIT License.