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 ask Oso Cloud via the Actions API: what 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.

Get started with Oso Cloud →