Skip to main content
General

Authentication

How to authenticate HTTP requests to the Rivet gateway and control plane.

Every request carries a token. Where it goes depends on whether you are calling the gateway or the control plane.

Tokens

TokenUse fromCan do
Rivet tokenTrusted backends and nodes onlyEverything, including control plane calls
Scoped tokenAnywhereOnly the grants it was issued with, typically one actor

Your Rivet token is the auth.admin_token value in the control plane config. It is the credential portion of your endpoint URL:

RIVET_ENDPOINT=https://my-namespace:<rivet-token>@rivet.example.com

Scoped tokens are minted with Create Token and are the right choice for handing a browser access to a single actor. See Permissions for how this fits with your own user auth.

Never ship your Rivet token to a browser or mobile app. Anyone holding it can create, destroy, and read every actor in the namespace.

Gateway Requests

Gateway requests (/gateway/{actor}/...) accept a token in any of these places. If more than one is present, the path or query token wins over the header.

Header

The default. Works for every HTTP request.

curl "https://rivet.example.com/gateway/$ACTOR_ID/action/increment" \
  -H "x-rivet-token: $RIVET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"args": [1]}'

Inline Path

Append @{token} to the actor ID. Useful for environments where you cannot set headers, such as EventSource or <img> tags. Only allowed with actor IDs, not actor names.

curl "https://rivet.example.com/gateway/$ACTOR_ID@$RIVET_TOKEN/request/stream"

Query Parameter

Pass rvt-token alongside the other rvt-* selector parameters when addressing an actor by name.

curl "https://rivet.example.com/gateway/counter/action/increment?rvt-namespace=$RIVET_NAMESPACE&rvt-method=get&rvt-key=my-counter&rvt-token=$RIVET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"args": [1]}'

URL-encode tokens placed in the path or query string.

WebSocket Requests

Browsers cannot set headers on a WebSocket upgrade, so WebSocket endpoints read the token from the Sec-WebSocket-Protocol header instead. Send the plain rivet protocol so servers that require a matching protocol accept the upgrade, then add the token as a second entry prefixed with rivet_token.:

const ws = new WebSocket(
  `wss://rivet.example.com/gateway/${actorId}/websocket/chat`,
  ["rivet", `rivet_token.${token}`],
);

The inline {actor_id}@{token} path form and the rvt-token query parameter also work on gateway WebSockets, and are simpler for clients that cannot set subprotocols. This applies to Raw WebSocket, Connect, Inspector Connect, and Node Connection.

Control Plane Requests

Control plane requests use a bearer header and require the namespace query parameter on every call.

curl "https://rivet.example.com/actors?namespace=$RIVET_NAMESPACE" \
  -H "Authorization: Bearer $RIVET_TOKEN"

Use your Rivet token here, or a scoped token with the grants the call needs.

Authentication Errors

Rejected tokens return 401 with auth.invalid_token or auth.token_expired, and 403 with auth.insufficient_permissions when the token is valid but lacks a grant. See Error Codes for the full list and Errors for the response format.