Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 0 additions & 47 deletions vendor/actors/docs/content/docs/access-control.mdx

This file was deleted.

124 changes: 0 additions & 124 deletions vendor/actors/docs/content/docs/authentication.mdx

This file was deleted.

2 changes: 1 addition & 1 deletion vendor/actors/docs/content/docs/connections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Connections are not visible in `c.conns` while `onBeforeConnect` is running.

<CodeSnippet file="examples/docs/actors-connections/on-before-connect.ts" />

Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication, see [Authentication](/actors/docs/authentication) for details.
Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication, see [Permissions](/actors/docs/permissions) for details.

### `onConnect`

Expand Down
2 changes: 1 addition & 1 deletion vendor/actors/docs/content/docs/crash-course.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ Use this pattern for long-lived, durable workflows that initialize resources, pr
- Use `c.conn.state` to securely identify users in actions rather than trusting action parameters.
- For cross-origin access, validate the request origin in `onBeforeConnect`.

[Authentication Documentation](/actors/docs/authentication) · [CORS Documentation](/actors/docs/cors)
[Authentication Documentation](/docs/authentication) · [Permissions Documentation](/actors/docs/permissions) · [CORS Documentation](/actors/docs/cors)

### Versions & Upgrades

Expand Down
4 changes: 2 additions & 2 deletions vendor/actors/docs/content/docs/lifecycle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ The `onBeforeConnect` hook does NOT return connection state - it's used solely f

<CodeSnippet file="examples/docs/actors-lifecycle/on-before-connect.ts" />

Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication - see [Authentication](/actors/docs/authentication) for details.
Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication, see [Permissions](/actors/docs/permissions) for details.

### `onConnect`

Expand All @@ -212,7 +212,7 @@ For actions, enforce authorization directly inside each action handler.

<CodeSnippet file="examples/docs/actors-lifecycle/can-publish-subscribe.ts" />

Use deny-by-default rules for each hook and return `false` unless explicitly allowed. See [Access Control](/actors/docs/access-control) for full guidance.
Use deny-by-default rules for each hook and return `false` unless explicitly allowed. See [Permissions](/actors/docs/permissions) for full guidance.

### `onDisconnect`

Expand Down
150 changes: 150 additions & 0 deletions vendor/actors/docs/content/docs/permissions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: "Permissions"
seoTitle: "Authorize Callers Inside Rivet Actors"
description: "Identify callers when they connect to a Rivet Actor, then authorize every action, queue publish, and event subscription with deny-by-default rules."
skill: true
---

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Medium · Capitalize Actor throughout the new user-facing copy

The new pages repeatedly use lowercase “actor” in prose (for example “inside your actor,” “which actor,” and “actor state”), while this website's terminology contract requires the product noun “Actor” to be capitalized everywhere in user-facing copy. The new authentication guide has the same issue. Update the upstream bundle to use “Actor” consistently and resync the vendored content.

Permissions are enforced inside your actor, on a caller that has already reached it. This is the only layer that can see `c.state`, `c.key`, and action arguments, so every domain rule lives here.

The layer above it decides which actor a client may reach at all. See [Authentication](/docs/authentication) for that, and [JWTs](/docs/jwt) to scope a client to a single actor before it ever gets here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Medium · Ship the shared authentication routes before linking to them

Neither /docs/authentication nor /docs/jwt has a backing MDX file or sidebar entry in this repository's general docs bundle (vendor/docs/docs/content), yet this change points multiple pages at those routes and deletes /actors/docs/authentication. The existing redirect for the deleted route also lands on the missing /docs/authentication, so both new navigation and old inbound links end in 404s. Sync the general authentication/JWT pages and sidebar in this change, or keep the existing Actor page and links until those routes are available.


## Quickstart

<Steps>

<Step title="Identify the caller and gate an action">

Use `createConnState` to turn a credential into connection state, then check that state in the actions that need it. Throwing from `createConnState` rejects the connection.

<CodeGroup workspace>
<CodeSnippet file="examples/docs/actors-permissions/quickstart/index.ts" title="index.ts" />
<CodeSnippet file="examples/docs/actors-permissions/quickstart/client.ts" title="client.ts" />
</CodeGroup>

</Step>

<Step title="Verify the rejection">

Running the client prints the allowed read, then the rejected edit:

```
(empty string)
ActorError: Admins only
```

</Step>

</Steps>

## Identifying the Caller

Two hooks run before a connection is usable. Both can be async, and throwing from either rejects the connection.

### `onBeforeConnect`

Use it for pass or fail validation when you do not need the result later.

<CodeSnippet file="examples/docs/actors-permissions/on-before-connect.ts" />

### `createConnState`

Use it when actions need to know who is calling. The returned object becomes `c.conn.state`. See [Connections](/actors/docs/connections) for the full lifecycle.

<CodeSnippet file="examples/docs/actors-permissions/create-conn-state.ts" />

### Available Data

Both hooks can read:

| Property | Description |
| --- | --- |
| `params` | Data the client passed when connecting. See [connection params](/actors/docs/connections#extracting-data-from-connection-params). |
| `c.request` | The underlying HTTP request. |
| `c.request.headers` | Request headers. Not available for `.connect()`. |
| `c.state` | Actor state, for authorization decisions. See [state](/actors/docs/state). |
| `c.key` | The actor's key. See [keys](/actors/docs/keys). |

Prefer `params` over `c.request.headers`. It works for both HTTP and WebSocket connections, while headers do not.

## Passing Credentials from the Client

<CodeGroup>
<CodeSnippet file="examples/docs/actors-permissions/passing-credentials-connection.ts" title="Connection" />
<CodeSnippet file="examples/docs/actors-permissions/passing-credentials-stateless.ts" title="Stateless-Action" />
<CodeSnippet file="examples/docs/actors-permissions/passing-credentials-headers.ts" title="HTTP-Headers" />
</CodeGroup>

Use `getParams` rather than `params` when the credential can change between attempts, such as a token that has to be fresh on every reconnect.

### Handling Errors

Rejections surface through the normal error system. See [errors](/actors/docs/errors).

<CodeGroup>
<CodeSnippet file="examples/docs/actors-permissions/handling-errors-connection.ts" title="Connection" />
<CodeSnippet file="examples/docs/actors-permissions/handling-errors-stateless.ts" title="Stateless-Action" />
</CodeGroup>

## Permission Surfaces

Authorization is explicit per surface. Nothing is checked implicitly.

- `onBeforeConnect` and `createConnState` reject unauthenticated connections.
- Action handlers enforce per-action rules.
- `queues.<name>.canPublish` allows or denies an inbound queue publish.
- `events.<name>.canSubscribe` allows or denies an event subscription.

<CodeSnippet file="examples/docs/actors-permissions/chat-room.ts" />

### Fail by Default

1. Keep connection hooks strict and reject invalid credentials.
2. In each action, allow the expected roles explicitly and throw `forbidden` otherwise.
3. In `canPublish` and `canSubscribe`, return `true` only for allowed roles and end with `return false`.

### Return Value Contract

`canPublish` and `canSubscribe` must return a boolean. `true` allows, `false` denies with `forbidden`. Returning `undefined`, `null`, or any non-boolean throws an internal error.

`canPublish` applies only to queue names declared in `queues`, and messages for undeclared queues are ignored while the publish still reports as completed. `canSubscribe` applies only to event names declared in `events`, and broadcasting an undeclared event still reaches its subscribers.

## Patterns

### Verifying a JWT from Your Auth Provider

Tokens from Clerk, Auth0, Supabase, or your own issuer are opaque to Rivet. Verify them here with your provider's SDK or a library such as `jose`, checking the signature, issuer, audience, and expiry.

<CodeSnippet file="examples/docs/actors-permissions/jwt.ts" />

### Calling an External Auth Service

<CodeSnippet file="examples/docs/actors-permissions/external-auth-provider.ts" />

### Authorizing Against Actor State

`c.state` and `c.key` are both available, so an actor can decide access from its own data.

<CodeSnippet file="examples/docs/actors-permissions/using-state.ts" />

### Role-Based Access Control

<CodeSnippet file="examples/docs/actors-permissions/role-based-access-control.ts" />

### Rate Limiting

Track attempts in `c.vars` and reject callers that exceed a limit.

<CodeSnippet file="examples/docs/actors-permissions/rate-limiting.ts" />

These counters are [ephemeral](/actors/docs/state#ephemeral-variables). Use `state` instead of `vars` to persist them.

### Caching Validated Tokens

Avoid revalidating the same token on every reconnect.

<CodeSnippet file="examples/docs/actors-permissions/caching-tokens.ts" />

## When You Need Less of This

If you scope each user's [JWT](/docs/jwt) to a single actor, that actor has exactly one participant and needs little authorization of its own. These hooks earn their keep once an actor is shared, as in a chat room or a per-tenant database.
9 changes: 5 additions & 4 deletions vendor/actors/docs/content/docs/production-checklist.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ actor, not before shipping it.

### Authentication

- **Validate connections in `createConnState` or `onBeforeConnect`.** Do not trust client input without validation. See [Authentication](/actors/docs/authentication).
- **Validate connections in `createConnState` or `onBeforeConnect`.** Do not trust client input without validation. See [Permissions](/actors/docs/permissions).
- **Never ship a secret to a public client.** Mint a short-lived, scoped [JWT](/docs/jwt) per user on your backend instead of embedding a token that reaches your whole namespace. See [Authentication](/docs/authentication).

### CORS

Expand All @@ -66,11 +67,11 @@ actor, not before shipping it.
- **Do not leak your secret token.** Never expose `sk_*` tokens in client-side code, public repositories, or browser environments. See [Endpoints](/docs/endpoints).
- **Verify you're connecting to the correct region.** Use the nearest datacenter endpoint (e.g. `api-us-west-1.rivet.dev`) for lowest latency.

### Access Control
### Permissions

Access control is only needed if you want granular permissions for different clients. For most use cases, basic authentication in `onBeforeConnect` or `createConnState` is sufficient.
Granular permissions are only needed if different clients should be able to do different things. For most use cases, basic validation in `onBeforeConnect` or `createConnState` is sufficient.

- **Use deny-by-default rules.** Reject unknown roles in `onBeforeConnect`, action handlers, `canPublish`, and `canSubscribe`. See [Access Control](/actors/docs/access-control).
- **Use deny-by-default rules.** Reject unknown roles in `onBeforeConnect`, action handlers, `canPublish`, and `canSubscribe`. See [Permissions](/actors/docs/permissions).
- **Authorize actions explicitly.** Check the caller's role in each action handler and throw `forbidden` for unauthorized access.
- **Gate event subscriptions and queue publishes.** Use `canSubscribe` and `canPublish` hooks to restrict which clients can subscribe to events or publish to queues.

Expand Down
2 changes: 1 addition & 1 deletion vendor/actors/docs/content/docs/queues.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ This means you can run normal code in `run` without worrying about sleep interru
## Recommendations

- Actions are for getting data, queue entries are for mutating data.
- Implement connection auth in `onBeforeConnect`. See [Authentication](/actors/docs/authentication).
- Implement connection auth in `onBeforeConnect`. See [Permissions](/actors/docs/permissions).
- Route most state changes through one queue loop so ordering stays predictable.
- If you need more complex multi-step run loops, consider using workflows.
- Use `c.aborted` and `c.abortSignal` for actor shutdown. Use your own `AbortController` for earlier loop cancellation.
Expand Down
Loading
Loading