Access Control

Control who can publish and subscribe to topics with fine-grained access control lists (ACLs).

ACL Basics

Each topic can have separate permissions for publishing and subscribing. This allows you to create read-only channels, write-only endpoints, or fully open topics.

Permission Levels

Each actor's access to a topic is defined by one of these permission levels:

PermissionDescription
subscribeCan only subscribe to the topic (read-only)
publishCan only publish to the topic (write-only)
pubSubCan both publish and subscribe (full access)

The Default Is Open

Access resolves in two layers, and both start permissive. This is why the quickstart connects successfully without any access-control step.

App level. A new app is created in open mode, which gives every actor in the project publish and subscribe rights on all of that app's topics.

Room level. A room with no grants inherits the app-level permission. Creating the first grant on a room flips it to private: from then on the broker admits only actors holding an explicit, unexpired grant. A grant naming a specific actorTokenId takes precedence over a broader actorType grant.

Two consequences worth planning for:

  • Until you add grants, any actor token in the project can read and write every topic in the app. The project is your outermost boundary, so keep unrelated workloads in separate projects and see Access Scopes for tenant isolation within one.
  • Because the first grant is what closes a room, granting access to one actor removes it from every other actor. Add grants for everything that needs the room, including your own backend services, in the same change.

Configuring ACLs

There are two ways to manage grants.

In the dashboard. Open your app, select a room, and manage its actor grants there.

Over the REST API. Room grants are a first-class resource, so a setup script or an agent can provision access without opening the dashboard:

# Grant one actor pub/sub on two topics in a room
curl -X POST https://api.nolag.app/v1/apps/{appId}/rooms/{roomId}/actors \
  -H "Authorization: Bearer nlg_live_xxx.secret" \
  -H "Content-Type: application/json" \
  -d '{
        "actorTokenId": "01939f83-8b57-7c3e-a456-426614174000",
        "permission": "pubSub",
        "topics": ["messages", "typing"]
      }'

# Or grant by actor type, covering every actor of that type
curl -X POST https://api.nolag.app/v1/apps/{appId}/rooms/{roomId}/actors \
  -H "Authorization: Bearer nlg_live_xxx.secret" \
  -H "Content-Type: application/json" \
  -d '{"actorType":"agent","permission":"subscribe"}'

# List the room's grants
curl https://api.nolag.app/v1/apps/{appId}/rooms/{roomId}/actors \
  -H "Authorization: Bearer nlg_live_xxx.secret"

# Revoke a grant
curl -X DELETE \
  https://api.nolag.app/v1/apps/{appId}/rooms/{roomId}/actors/{roomActorAccessId} \
  -H "Authorization: Bearer nlg_live_xxx.secret"

Supply either actorTokenId or actorType, plus a permission. Optionally scope the grant with topics, time-limit it with expiresAt, or disable it with isActive: false.

Not through the client SDKs. The JavaScript, Python, and Go SDKs are data-plane clients. They do not expose an ACL management API. Permission is enforced server-side when you subscribe or publish:

// Grants are managed in the dashboard or over the REST API, not from the SDK.
// When connecting via the SDK, permission is enforced automatically:
import { NoLag } from '@nolag/js-sdk'

const client = NoLag('your_access_token')
await client.connect()

const room = client.setApp('my-app').setRoom('general')

// This will only succeed if the actor has 'subscribe' or 'pubSub' permission
room.subscribe('announcements')

// This will only succeed if the actor has 'publish' or 'pubSub' permission
room.emit('chat', { text: 'Hello!' })

Common Patterns

Broadcast Channel

Server actors publish announcements, clients subscribe to receive them:

  • Server actors: publish
  • Client actors: subscribe

Chat Room

All participants can read and write messages:

  • All actors: pubSub

Private Notifications

Server sends notifications, user reads them:

  • Server actors: publish
  • User actor: subscribe

Next Steps