> For the complete documentation index, see [llms.txt](https://fusionauth.io/docs/llms.txt)

# Step 4 - Role-Based Access Control | FusionAuth Docs

Learn how to use FusionAuth by using an example application that has a protected page defined.

# Step 4 - Role-Based Access Control

[Edit on GitHub](https://github.com/FusionAuth/fusionauth-site/blob/main/astro/src/content/docs/get-started/start-here/step-4.mdx)

[View Markdown](https://fusionauth.io/docs/get-started/start-here/step-4.md)

The [Kickstart](https://fusionauth.io/docs/get-started/download-and-install/development/kickstart.md) from step one created two roles for our Changebank application. These are `admin` and `user`. It assigned these roles to the two users it created as well. The user `admin@example.com` was granted the `admin` role and the user `richard@example.com` was granted the `user` role.

Roles are the way that FusionAuth manages user authorization to applications. And authorization is the process an application determines what a user is allowed to do. Access control is the method that is used to enforce these constraints. A common form of authorization and access controls is Role-Based Access Controls (RBAC).

When a user logs into an application, the user's roles for that application are included in their access token. Since FusionAuth access tokens are JWTs, it is simple to decode the JWT and analyze the roles a user has been granted.

Let's take a look at how our example application uses roles to verify the user's access.

If you open the `src/sdk.ts` file and scroll to the `userHasAccess` function, you'll see that the final parameter of this function is an array. This array contains the names of the roles that are allowed to access a specific page in the application. For example, the `/account` route calls this method like this:

```typescript
app.get("/account", async (req, res) => {
  if (!await sdk.userHasAccess(req, res, ["admin", "user"])) {
    res.redirect(302, '/login');
    return;
  }

  res.sendFile(path.join(__dirname, '../templates/account.html'));
});
```

This means that the user must have either the `admin` or the `user` role in order to access the `/account` page.

Similarly, the `/admin` route makes a similar check like this:

```typescript
app.get("/admin", async (req, res) => {
  if (!await sdk.userHasAccess(req, res, ["admin"])) {
    res.redirect(302, '/account');
    return;
  }

  res.sendFile(path.join(__dirname, '../templates/admin.html'));
});
```

However, this route requires that the user has the `admin` role.

The check for the roles is located in the `userHasAccess` function of the `src/sdk.ts` file. If you jump over to that function, you can see that the function confirms that the user has one of the specified roles like this:

```typescript
async userHasAccess(req: Request, res: Response, roles: Array<string>): Promise<boolean> {
  const jwt = await this.getUser(req, res);

  // @ts-ignore
  if (!jwt || !jwt.roles || jwt.roles.length === 0) {
    return false;
  }

  // @ts-ignore
  return jwt.roles.some(role => roles.includes(role));
}
```

You can write a similar function to verify roles and in some languages you can leverage security frameworks and libraries as well. The general rule is to ensure that every protected route has an access control check before it renders the response.

## Next steps

[<- Step 3: Protected Page](step-3)

[Step 5: Session Management \->](step-5)