/ security

Security built into the protocol.

NoLag enforces isolation, access control, and authentication at the infrastructure level. Your application code handles business logic, not security plumbing.

Protocol-Level Security

TLS at Your Proxy

kraken listens on plain ws:// and does not terminate TLS itself. Put a reverse proxy or load balancer in front of it to terminate TLS, and have clients connect with wss:// in production.

Binary MessagePack

Messages are serialized as binary MessagePack rather than JSON, for smaller payloads and faster parsing. Encoding is not encryption, so TLS still matters.

Broker-Level Enforcement

Permissions, scopes, and access rules are enforced at the broker not in your application code. No middleware to forget, no filter to misconfigure.

Short-Lived Client Tokens

With @nolag/core, browsers authenticate with JWTs your backend mints from a project signing key, expiring in minutes. Long-lived access tokens never leave your servers.

Multi-Tenancy via Access Scopes

Assign actors to scopes and all communication is automatically partitioned. Messages, webhooks, presence, and state are isolated per tenant at the broker level, no application-level filtering required.

Tip: Scope metadata flows through webhooks automatically. Your backend receives the tenant scope in every webhook payload, so you always know which tenant triggered the event.

# Without scopes, all actors share topics

app/room/orders ← all tenants

app/room/analytics ← all tenants

# With scopes, automatic namespace partitioning

tenant-a/room/orders ← tenant A only

tenant-b/room/orders ← tenant B only

tenant-a/room/analytics ← tenant A only

tenant-b/room/analytics ← tenant B only

Room-Level Access Control

With @nolag/core, rooms are public by default. Any actor in the app can join. Attach at least one actor to a room and it becomes private: only explicitly granted actors can access it. No toggles, no config flags.

No actors = public. At least one actor = private. The access model is implicit from the actor list.

Public Room

No actors attached, open to all

Private Room

Actors attached, restricted access

Per-Topic ACL

Every topic has granular read/write permissions per actor type. Permissions are enforced at the broker, not in your middleware.

TopicActor TypePermission
ordersDeviceRead only
ordersServiceRead + Write
analyticsUserNo access
analyticsServiceWrite only
notificationsDeviceRead only
notificationsSessionRead only

Actor Authentication

Four actor types, each with its own access token and topic grants. Each actor type has distinct capabilities and auth mechanisms.

Device

Frontend clients: browsers, mobile apps, embedded devices.

  • WebSocket connections
  • Scoped topic access
  • Presence tracking

User

Authenticated users with identity tied to your auth provider.

  • JWT-based auth
  • Role-based permissions
  • Cross-device sessions

Service

Backend services, workers and scripts that authenticate with an actor access token.

  • Access token auth
  • Broad topic grants
  • Webhook integration

Session

Temporary, anonymous connections for guests and previews.

  • Time-limited tokens
  • Restricted scope
  • No persistent identity

Running It Yourself

NoLag is software you run, not a service we operate. The broker enforces access rules, but the deployment around it is yours to secure.

Terminate TLS

kraken serves plain ws:// on port 8080. Run it behind a TLS-terminating proxy and never expose the plain port to the internet.

Keep secrets secret

Use long random access tokens, keep auth.json out of version control, and set BACKEND_SECRET when kraken calls your own auth service.

Dev mode stays in dev

AUTH_ALLOW_ALL accepts any token with full access. It exists for local testing and must be off everywhere else.

Do not expose the core example host

The @nolag/core example host and admin UI authenticate nobody. Keep them on a private network, or write your own host behind your own auth.

Security questions?

Read the production guide before you deploy, or open an issue on GitHub.