On this page
Enforce Backend Authorization
Frontend controls what users SEE. Backend controls what users MAY DO. Every protected operation must enforce authorization in the Function, regardless of which buttons or JavaScript modules the frontend displays.
Protect a role-restricted operation
- Read the trusted identity from
env.MINIUP_USER. - Verify the member’s role before loading private data or making a change.
- Verify any record-specific rule, such as whether a record belongs to that member.
- Validate the submitted fields independently of the permission check.
- Return only the fields the authorized caller needs.
const user = env.MINIUP_USER;
if (!user) {
return Response.json({ error: "Sign in required" }, { status: 401 });
}
if (user.role !== "owner" && user.role !== "admin") {
return Response.json({ error: "Forbidden" }, { status: 403 });
}
// Perform the administrative operation only after these checks.Understand why hiding UI is insufficient
A user can call an endpoint directly even if the page hides its Admin button. Loading admin.js conditionally is useful for navigation and performance, but it does not protect data. A browser-supplied record owner or role must not override the trusted member identity.
For a “My requests” page, filter records using the trusted user.id in the backend. Do not return every user’s records to the browser and rely on client-side filtering.
Protect credentials and persistent data
Keep private records in Tables or private services and access them through a Function with Secrets. Check the underlying Table’s own access policy too: protecting a Function does not protect a separate publicly readable Table API.
Test authorization explicitly
Test the same administrative request as Owner, Admin, Editor, Viewer, and while signed out. Lower-privilege users should receive a denied response without private data or side effects. Retest after changing roles or removing a member.