For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
API trust
Hide buttons for UX, but enforce every mutation on the Hono API. Never authorize from a client-supplied organization id alone.
Access control has two jobs:
- Prove who the caller is (authentication)
- Prove what they are allowed to do (authorization)
On mobile, (1) starts with the Better Auth session on the device. (2) must still happen on the API. Hiding a menu item in React Native is not enough.
Call protected routes
The Expo app uses the shared Hono client with the user session. Sensitive reads and all mutations should hit routes guarded by enforceAuth (and permission middleware when needed).
// After the user is signed in on device
const { data } = await handle(api.billing.summary.$get)({
query: { referenceId: user.id },
});If a screen is “private”, still assume a modified client can call the endpoint directly. The server decides.
See Protected routes and Web access control for middleware details.
Client RBAC is UX only
Organization helpers like hasPermission / checkRolePermission on the auth client are useful to disable buttons and hide screens.
They are NOT a security boundary. Repeat the same checks in the API with enforceOrganizationPermission or enforceMembership.
Organizations RBAC
Roles and client-side permission helpers.
Multi-tenant isolation
Never authorize from a client-provided organizationId alone. Send the id if the API needs it, but the server must verify membership for the authenticated user before scoping queries.
When you add features (projects, documents, …):
- Authenticate the request (
enforceAuth) - Confirm membership / permission for that organization
- Filter every query by the verified tenant id
Feature and plan gates
Plan-based UI (paywalls, locked screens) should match server enforcement - feature middleware or entitlement checks on the API. See the feature-based access recipe.
Practical rules
- Do not embed admin-only logic that only runs on the device
- Do not trust boolean flags stored only in AsyncStorage / SecureStore as proof of entitlement
- Do not pass secret API keys into the mobile client “to make a shortcut”
- Do log auth failures and 401/403 spikes in monitoring so abuse is visible
How is this guide?
Last updated on