It’s good practice to adapt UI based on permissions, even if your backend will enforce permissions on the server-side.
import { useStytchIsAuthorized } from '@stytch/react/b2b';const DocumentActions = () => { // Use the useStytchIsAuthorized hook to check if the current Member is authorized to perform an action. const { isAuthorized: canReadDocument } = useStytchIsAuthorized('documents', 'read'); const { isAuthorized: canWriteDocument } = useStytchIsAuthorized('documents', 'write'); return ( <div> { /* Disable a button if the Member is not authorized */ } <button disabled={!canReadDocument}>View Document</button>} { /* or just hide the button entirely */ } {canWriteDocument && <button>Edit Document</button>} </div> );};
You should also do pre-emptive client-side authorization checks to avoid any unnecessary API requests or ensure the user isn’t about to enter a flow they cannot complete.
const canReadDocument = await stytch.rbac.isAuthorized('documents', 'read');if (!canReadDocument) { throw new Error('You do not have permission to read documents');}loadDocument();
Stytch’s frontend SDKs offer built-in RBAC protections, allowing you to make requests directly from your public client without proxying through your backend.When you call methods like organization.update() or magicLinks.email.invite() directly from the client:
The frontend SDK will automatically include the logged in member’s session in the request to the Stytch API.
The Stytch API will only authorize the request if the session is valid and the Member has at least one Role that grants them permission to take that action.
To enable the SDK to make these requests, enable Member actions & organization modifications in the Stytch Dashboard.
Regardless of if you are using Stytch’s frontend SDKs, you must always perform server-side authorization checks before proceeding with a request by authorizing a valid Session Token or .
Session Tokens
JWTs
If you are using Session Tokens, session authentication will trigger an outbound call to Stytch and authorization will be done on Stytch’s servers.For example to check authorization in a python backend:
resp = stytch_client.sessions.authenticate( session_token='mZAYn5aLEqKUlZ_Ad9U_fWr38GaAQ1oFAhT8ds245v7Q', authorization_check={ 'organization_id': 'organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931', 'resource_id': 'documents', 'action': 'edit', })if resp.status_code != 200: # The Member is not authenticated, redirect to login page return 'not authenticated', 401if not resp.authorized: # The Member is authenticated, but does not have permission to edit the document return 'unauthorized', 403# Member is authenticated and has permission to edit the documentsave_document_edits()
If you are using Session JWTs, the Member’s Roles are contained in the JWT.When using authenticateJwt(), authorization checks will be done locally during the lifetime of the JWT without incurring any additional latency of an outbound call. Stytch’s backend SDKs will cache your Project’s RBAC policy and refresh it every five minutes, ensuring that any RBAC policy changes are incorporated into local evaluations within 5 minutes.If authenticateJwt() method detects the JWT is expired, it will make an outbound call to Stytch to refresh the JWT. This ensures that any changes to the Member’s Role will take effect within five minutes and that the underlying session has not been revoked.
resp = stytch_client.sessions.authenticateJwt( session_jwt="eyJ...", authorization_check={ 'organization_id': 'organization-test-07971b06-ac8b-4cdb-9c15-63b17e653931', 'resource_id': 'documents', 'action': 'edit', })if resp.status_code != 200: # The Member is not authenticated, redirect to login page return 'not authenticated', 401if not resp.authorized: # The Member is authenticated, but does not have permission to edit the document return 'unauthorized', 403# Member is authenticated and has permission to edit the documentsave_document_edits()
Any Stytch API endpoints and Backend SDK methods that act on a default Stytch Resource (e.g. stytch.self or stytch.organization) support passing the Member’s Session Token or Session JWT to have Stytch perform authentication and authorization prior to honoring the request.This allows the authentication and authorization checks to occur as close as possible to the action being taken, streamlining your handling.For example, if a Member makes a request to delete another Member from an Organization, you can pass their Session Token or JWT into the organizations.members.delete() call. Stytch will authenticate the session and perform an authorization check prior to honoring the call.