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.
| Topic | Actor Type | Permission |
|---|---|---|
| orders | Device | Read only |
| orders | Service | Read + Write |
| analytics | User | No access |
| analytics | Service | Write only |
| notifications | Device | Read only |
| notifications | Session | Read 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.