Drop-in org chat any app can add with one script tag.
ASL Messaging is a multi-tenant instant-messaging platform service. Any app on the platform can let its already-authenticated users message each other within their own organization — without standing up chat infrastructure. It holds no user database, no passwords, and no sessions; the consuming app's backend vouches for a signed-in user with a short-lived signed connect token. Real-time delivery runs over a dependency-free WebSocket, strictly scoped per tenant.
The problem
Every app building its own chat is a lot of wasted, risky work.
Adding colleague-to-colleague messaging usually means either a heavyweight third-party chat vendor — new data-sharing, new billing, new dependency — or building real-time chat from scratch in every product, and getting tenant isolation and impersonation-resistance right each time.
ASL Messaging is one shared service every app talks to. Apps onboard by adding a few routes and a script tag — no auth migration, no chat vendor, no per-app chat backend.
Secrets stay server-side
- Connect tokens minted server-to-server over loopback
- Gated by a per-app shared secret the browser never sees
- Scoped to one user + one tenant, ~1h lifetime
- Strict isolation per (app, organization)
Capabilities
Real-time chat without the real-time chore.
Multi-tenant isolation
Channels and messages are strictly scoped per (appId, externalOrgId) — there's no cross-tenant path.
Vouched connect tokens
The consuming app's backend mints a short-lived signed token; the platform holds no passwords or sessions of its own.
Group & direct channels
Both group channels and direct messages, delivered in real time over a dependency-free WebSocket.
Roster sync
A roster API deactivates (rather than deletes) departed staff, so channel history survives a personnel change.
Impersonation-resistant
Channel creation pulls display names from the roster, not the caller — so a client can't spoof another user's name.
Colleague directory
A picker that distinguishes "no one else here yet" from "not yet synced" — no confusing empty states.
Tamper-evident audit
A hash-chained admin_audit_log over structural events.
Embeddable widget
A client.js widget with ASLMessaging.mount(), themeable via CSS variables to match the host app.
Narrow public surface
Only /healthz, /client.js, /ws, and /api/* are exposed; /admin/* is loopback-only.
Add chat once, for every app.
Real-time, self-hosted, multi-tenant messaging that onboards with a script tag — no chat vendor, no auth migration, no per-app backend.