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
| Token | Use from | Can do |
|---|---|---|
| Rivet token | Trusted backends and nodes only | Everything, including control plane calls |
| Scoped token | Anywhere | Only 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.