Advisory auth vs the backend gate
Authentication appears in the SDK as a deliberately small surface: the
session snapshot, the session.changed event, and two helpers,
getRoles() and hasRole(role). That is the whole of it. There is
no “check this permission” call, because there is nothing in the SDK that could enforce one.
What the SDK gives you
Section titled “What the SDK gives you”platform.session is a snapshot of the current user — whether they are authenticated, who they are,
and an advisory list of roles. session.changed fires when that snapshot changes (a sign-in, a
sign-out, a role grant). hasRole is a convenience over the snapshot’s roles.
You use all of this for exactly one thing: deciding what to render. Show the “view invoices”
button when hasRole("invoices:read"); hide it otherwise.
What the SDK does not give you
Section titled “What the SDK does not give you”It does not give you a way to authorize an action, and that omission is the design. The session cookie, the introspection the platform performs against it, and the role enforcement that gates each request all live below the SDK, in infrastructure your app never touches through the client. From inside your app, they are invisible — and that is correct, because:
- The backend is the single source of truth. Authorization is checked where the data lives, on every request, against the live session — not against a snapshot the client happened to receive.
- A client-side check is not a security boundary. Anything the SDK hands your iframe, a user can read and change. A role boolean flipped in devtools reveals a button; it does not grant access. The backend serving that button’s data still returns a 403.
The rule
Section titled “The rule”
hasRoledecides whether to show a control. The backend decides whether the action behind it is allowed. Never let the first stand in for the second.
If you treat the advisory roles as enforcement, you have not built a permission system — you have built
a UI hint that looks like one. Build the affordance with hasRole
(how-to); let the backend be the gate.