Frontend (UI) Authorization
The authorization rules that secure your application’s backend often have implications for the frontend as well. For example, you may want to hide a link to another page if the current user doesn’t have access to that page. Or perhaps you’d like to display an "edit" button only if the user can actually edit the resource in question.
This guide covers the best practices for implementing frontend (UI) authorization with Oso Cloud.
Keep Enforcement in the Backend
The first rule of frontend authorization: keep the frontend in charge of presentation and the backend in charge of enforcement. Because the end user has a large degree of control over code that runs in their browser, you can never fully trust its requests. The user’s browser might insist they’re an admin who should have unfettered access to your entire application, but your backend should ask Oso Cloud what they’re really allowed to do.
For security reasons, you should never make requests directly to Oso Cloud from your frontend. Your Oso Cloud API token should be kept secret and never exposed in your users’ browsers. A malicious actor could use even a read-only API token to exfiltrate your authorization policy and data.
Expose Permissions to the Frontend
Frontends ask a single authorization question over and over: what actions can
the current user perform on various resources rendered on the current page? If
they’re looking at details about an organization but don’t have permission to
edit or delete it, we shouldn’t render Edit
or Delete
buttons.
The general pattern for a back end API responding to a front end request:
- Ask Oso Cloud via the Authorize API: is the current user authorized to access the resource?
- If they have access, then querying Oso Cloud for which actions can the current user take on the resource?
- Return the permissions along with the response payload so that your front end knows which buttons and links to render alongside details about the resource.
Here’s an example (opens in a new tab) of that pattern in our GitCloud example app’s Python back end:
def show_organization(org_id): # Is the current user authorized to access the resource? if not oso.authorize(current_user, "read", {"type": "Organization", "id": org_id}): raise NotFound org = Organization.get_from_database(org_id) json = org.as_json() # What actions can the current user take on the resource? actions = oso.actions(current_user, org) # Return the permissions along with the response payload. json["permissions"] = actions return json
The front end then uses the returned permissions to decide whether to show or hide UI elements. Here’s an example (opens in a new tab) of that in GitCloud’s React front end:
{ org.permissions?.includes("create_repositories") && ( <Button>Create new repository</Button> );}
We only show the Create new repository
button if the current user has the
"create_repositories"
permission on the organization.
Talk to an Oso Engineer
If you'd like to learn more about using Oso Cloud in your app or have any questions about this guide, connect with us on Slack. We're happy to help.