Create Token
Issue a scoped token. Use this to mint short-lived tokens that grant a client access to a single actor instead of sharing your namespace token.
Each grant names a resource type, a target ("any" or a specific { "id": ... }), and the operations it allows. A token carries 1 to 32 grants with 1 to 5 operations each. The RivetKit client wraps this as handle.issueToken().
POST https://rivet.example.com/auth/tokens
Examples
curl -X POST "https://rivet.example.com/auth/tokens" \
-H "Authorization: Bearer $RIVET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"namespace": "my-namespace",
"subject": "user-123",
"duration": 3600,
"grants": [
{
"resource": "actor_gateway",
"target": {
"id": "d97pbq1nyqxw1w5qdwz0iirbqiblh2"
},
"operations": [
"read"
]
}
]
}'
import { createClient } from "rivetkit/client";
import type { registry } from "./index";
const client = createClient<typeof registry>(process.env.RIVET_ENDPOINT);
const counter = client.counter.getOrCreate(["my-counter"]);
// issueToken() resolves the actor ID and sends POST /auth/tokens with a
// grant scoped to this actor. It defaults to actor_gateway read access.
// expiresIn is in seconds.
const { token, expiresAt } = await counter.issueToken({
subject: "user-123",
expiresIn: 60 * 60,
});
// Hand the token to a browser client. It can only reach this actor.
console.log(token, new Date(expiresAt));
Authentication
Requires the admin token, sent as a bearer token in the Authorization header. Namespace tokens are rejected. See Authentication.
Request Body
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
namespace | string | Yes | Namespace the token is valid in. It must exist. |
duration | integer | null | No | Lifetime in seconds, from 1 to the deployment’s maximum. Omit for the default lifetime. |
subject | string | null | No | Free-form subject to attach to the token, such as a user ID. At most 256 UTF-8 bytes. |
grants | object[] | Yes | Permissions the token carries. |
grants[].resource | "namespace" | "actor" | "node" | "pool" | "datacenter" | "actor_gateway" | "actor_kv" | Yes | Resource type the grant applies to. |
grants[].target | "any" | object | Yes | "any" for every resource of this type, or { "id": "..." } for one resource. |
grants[].operations | ("read" | "update" | "list" | "create" | "delete")[] | Yes | Operations the token may perform on the target. |
Responses
200
The issued token. The response carries Cache-Control: no-store.
| Field | Type | Description |
|---|---|---|
token | string | The issued token. Treat it as a secret. |
issued_ts | integer | When the token was issued, in Unix milliseconds. |
expires_ts | integer | When the token expires, in Unix milliseconds. |
{
"token": "eyJ...",
"issued_ts": 1700000000000,
"expires_ts": 1700000000000
}
400
validation.invalid_input: the subject exceeds 256 UTF-8 bytes, the duration is outside the allowed range, or the grant set is invalid (empty, more than 32 grants, a grant without operations or with more than 5, or a token, acl or jwt resource). envoy.invalid_namespace_name: the namespace value is not a DNS label of 1 to 63 lowercase letters, digits and hyphens.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "validation",
"code": "invalid_input",
"message": "subject exceeds 256 UTF-8 bytes"
}
401
auth.invalid_token: the request does not carry the admin token.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "invalid_token",
"message": "Authentication token is invalid."
}
403
auth.issuance_disabled: JWT issuance is not enabled for this deployment.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "issuance_disabled",
"message": "JWT issuance is not enabled for this deployment."
}
404
namespace.not_found: the namespace does not exist.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "namespace",
"code": "not_found",
"message": "The namespace does not exist."
}
415
The request is missing the Content-Type: application/json header. Returned as plain text.
Content type: text/plain.
422
The JSON body does not match the request schema, for example a missing required field, a wrong type or an unknown field where unknown fields are rejected. Returned as plain text.
Content type: text/plain.
500
core.internal_error: an unexpected failure, including a deployment without authentication configured.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "core",
"code": "internal_error",
"message": "An internal error occurred"
}
503
auth.issuance_unavailable: the signing service is temporarily unavailable. Retry the request.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "issuance_unavailable",
"message": "The server could not issue an authentication token because the signing service is temporarily unavailable. Retry the request."
}