Now Available! Permit Elements. Learn More

  • Elements

The Ultimate Guide to Permit Elements

Permit Elements are a set of prebuilt and embeddable UI components that provide fully functional access control, allowing you to delegate them to your end users safely. Here's a step-by-step guide to how it works

Filip Grebowski

Jan 24 2023
The Ultimate Guide to Permit Elements
Share:

Permit Elements are a set of out-of-the-box access control elements you can embed directly into your app.

Element features include:

  • High security to meet industry-standard protocols and ensure user authorization processes are robust

  • Responsive design to fit seamlessly on any screen size

  • Custom styling rules so you can match the look and feel of your site

  • Easy embedding process, allowing you to work with elements in just a few minutes

TLDR:

In this guide, you will learn how to implement Permit Elements, and how to configure your frontend methods (login and logout) - which will send the currently authenticated user to your backend, and log that user into or out of the elements within your application.

Note:
As Permit and Permit Elements implement very strict and secure implementation practices, you must remember to initialize Permit and perform all element logic on the server side.

Prerequisites:

Each element offers its own set of customization and configurations. Before we dive into those, let's dive into some of the mechanics here:

Permission Levels:

What are Permission Levels?

Every Permit Embeddable UI Element provides a way to control access and assign roles to different permission levels.

Permission levels provide a way to elevate or restrict access control for that specific element, and all the same element types in an environment. Roles are assigned to different levels via a simple drag-and-drop operation.

When creating a new element, all the permission levels start empty, with all the available roles inside the “Hidden Roles” section. These are all the roles you can drag into the permission levels of your choice. 

MacBook.png


Let’s go over what each permission level signifies: 

The 5 Permission Levels

Workspace Permission Level

Description

Workspace Owner

The highest level of permissions, the workspace owner has full access to the element. They can assign and remove roles, and thus, the permissions of every other user.

Manager

The Manager has access to all of the element’s components. They can assign and remove roles and permissions for other users, but they cannot make changes to the overall workspace.

Viewer

A viewer can only view the element, but cannot make any changes.

Assignable Roles

Assignable can be assigned to users by the workspace owner or manager. However, a user with that role will not see the element.

Hidden Roles

The hidden roles are roles that will not appear in the element.

As more elements come out, not every element will have the need to contain all five permission levels. Some elements will be ‘view only,' which means you can only expect the Hidden Roles and the Viewer levels to be available for configuration.

Live Preview Feature

Our embeddable UI elements include a preview feature that allows users to see how the element will look and function for different permission levels and tenants. This can be useful in understanding the various configurations available and how they may affect the appearance and functionality of the element.

How to use the Preview Feature

Once you enter the configuration panel of the element you are currently working on, you will see a preview on the right. Use the dropdown menus to select the desired permission level and tenant for the preview. The preview will update to show how the element will appear and function for the selected permission level and tenant, which have been assigned to a particular end user.

Customization

With every new element, you can adjust several settings to make the look and feel of the element match your own.

  • Change the background and primary color of any element to match your brand.

  • Give the element a title that makes sense to your end user, or hide it fully.

  • Decide if you want to display your user's Email, Full Name, or both on the element.

pasted image 0.png

Configuring the Webhook:

With some Permit Elements, you will get the option to configure a webhook to stay informed of the actions that are performed by the end users.

EXAMPLE:

For the User Management Element, a webhook will allow you to receive updates each time a new user is created in your system.

You will need to generate a new webhook URL that points to the running server-side application. As part of the configuration, you are required to pass in a secret key and we will pass it as Bearer auth header with the user email role and level.

Embedding the iFrame:

After you finish configuring and customizing your element, you are ready to embed it into your App. A code snippet for the element will be generated for you. This will be an <iframe> that you can insert anywhere on your website. It will look like the code snippet below.

<iframe
   title="Permit Element Name"
   src="https://embed.permit.io/name?envId=<SOME_UNIQUE_ID>"
   width="100%"
   height="100%"
   style="border: none;"
/>

Step 1:

Install the permit-js package

For Node:

npm i --save @permitio/permit-js

For yarn:

yarn add @permitio/permit-js

Step 2: 

If you are configuring this whole setup with your first setup of Permit, you will need to import the permit package and initialize the permit instance in your backend. If you are already using Permit, you will already have that instance defined. 

As part of the permit instance, Please remember to copy your `SDK Secret Key` and pass it into the initialized Permit object.

const { Permit } = require("permitio");
    const [permit] = new Permit(
        {token: permit_key_SERCRET}
    );

Step 3: 

Create a server-side login route

You need to create a route in your backend server to allow your client to `login_as` themselves and get access to the Permit Element.

The backend `login_as` route is a bit different if your backend is using cookies, a bearer token or custom auth http headers to authenticate users.

You can choose the one that suits your backend needs best. The option you choose will depend on how you already handle authentication in your application.

Three examples will now follow: 

  • Using cookies:
    const express = require("express");
     const app = express();
     app.get("/login_cookie", async (req, res) => {
         // const user_key = get_user_from_jwt();
         const ticket = await permit.elements.loginAs({userId: user_key, tenantId: TENANT});
         res.status(302).redirect(ticket.redirect_url);
     });
     app.listen(port, () => {
       console.log(`Example app listening at http://localhost:${port}`);
     });
  • Using a bearer token:
    const express = require("express");
     const app = express();
     app.get("/login_header", async (req, res) => {
         // const user_key = get_user_from_jwt();
         const ticket = await permit.elements.loginAs({userId: user_key, tenantId: TENANT});
         res.status(200).send(ticket.content);
     });
     app.listen(port, () => {
       console.log(`Example app listening at http://localhost:${port}`);
     });
    
  • Using any other http security header:
    const express = require("express");
     const app = express();
     app.get("/login_header", async (req, res) => {
         // const user_key = get_user_from_jwt();
         const ticket = await permit.elements.loginAs({userId: user_key, tenantId: TENANT});
         res.status(200).send(ticket.content);
     });
     app.listen(port, () => {
       console.log(`Example app listening at http://localhost:${port}`);
     });
    
    

Step 4: 

Client-side login method

Two login methods need to be called in your frontend application. The login method, and the logout method.

The login function should be called as early as possible in your App. It is best to do this inside an App/index file,  right after the users had their identity confirmed by the Authorization provider of your choice, but just before the Embedded component is loaded.

This is a client-side element login method that calls the backend route we have previously configured server-side. It sends the relevant information to the server, which allows us to login into the Permit elements within the app.

permit.elements.login({
        loginUrl: 'https://your_app_url.com/permit_login,
        tenant: 'your_tenant_key',
        token:'<TOKEN>',
        loginMethod: LoginMethod.bearer
    });

There are a couple of things that need to be configured here:

loginUrl - The URL that corresponds to your backend login route created in the last step.

loginMethod - The login method you are using in your backend.

tenant (Optional) - The name of the tenant that the user is part of. You can set it at your backend as well.

token (Optional) - If your login method is a bearer token, you need to pass the token here.

headers (Optional) - If your login method has custom headers, you need to pass the headers here.

There are three supported login options - choose the one you use in your backend.

  • Cookie Login Method
    permit.elements.login({
        loginUrl: 'https://your_app_url.com/permit_login,
        tenant: 'your_tenant_key'
    }).then((res: any) => {//optional handle success
     }).catch((err: any) => {//handle error
    });
    
  • Bearer Token Login Method

    permit.elements.login({
        loginUrl: backendUrl,
        tenant: 'your_tenant_key',
        loginMethod: LoginMethod.bearer,
        token: JWT_secret
    }).then((res: any) => {//optional handle success
     }).catch((err: any) => {//handle error
    });
  • Any other header login Method

    permit.elements.login({
        loginUrl: backendUrl,
        tenant: 'your_tenant_key',
        loginMethod: LoginMethod.header,
        headers: {'<secure header name>': 'secret'}
    }).then((res: any) => {//optional handle success
     }).catch((err: any) => {//handle error
    });
    

Step 5: Client-side logout method

This function should be called along with the logout logic that you have within your App. 
This is to make sure the user does not continue to have access to the Permit Element.

permit.elements.logout();

Possible Login Errors

There are a few possible errors you might encounter while working Permit Elements, and user login.

Error

Description

USER_NOT_FOUND

This error can appear if you are trying to log in as a particular user, but that user does not exist within Permit.

TENANT_NOT_FOUND

This error can appear when you pass in a tenant, either in the frontend permit.elements.login function, or in your backend URL endpoint, where the tenant has not been created in Permit.

INVALID_PERMISSION_LEVEL

The error will appear when you try to access part of the Element to which you have not been given access too. This usually means the role that the person obtained has remained in the Hidden Roles permission level.

FORBIDDEN_ACCESS

This error will emerge when you are trying to log in to an Element you have not been given permission to see.

Having Trouble? 

Let us know in our Slack Community - we will be more than happy to help 🙂

Filip Grebowski

Developer Advocate at Permit.io, Software Engineer, and YouTube Creator

decorative background