In this tutorial you will learn how to use Cerbos to add fine-grained access control to any Nuxt web application, simplifying authorization as a result.
Check out a working example of a Cerbos integration in a Nuxt application on GitHub.
Having met the prerequisites, the steps are as follows:
A Cerbos policy repository is a collection of YAML files that define access control rules for your application. It's essential for specifying who can do what within your app. These policies dictate the actions different user roles can perform on various resources. A resource is an application-specific concept that applies to anything that requires access rules. For example, a document is a resource that can be altered, viewed, deleted, etc. by different users depending on the access control rules. Read more about the best practices for structuring your policy repository in our documentation.
Your Cerbos policy repository can be stored on your disk, on git, or any S3-compatible storage system. To set up a Cerbos policy repository on the disk, within the Nuxt application, do the following:
cerbos
` folder, then a ` policies
` sub-folder within it.policies
` folder, create a YAML file which will contain the rules for performing permission checks in your Nuxt application. For example, create a ` documents.yaml
` resource policy file.documents.yaml
` file with rules for actions that can be performed on a document, check the example below. Learn more in Cerbos resource policies documentation.apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: default
resource: document
rules:
- actions: ['view', 'change', 'destroy']
effect: EFFECT_ALLOW
roles:
- admin
- actions: ['view', 'change']
effect: EFFECT_ALLOW
roles:
- user
condition:
match:
expr: request.resource.attr.author == request.principal.id
Now we’ve defined a simple resource policy file ` documents.yaml
` which allows admin users to ` view
`, ` change
`, and ` destroy
` any ` document
` resource within the system. Non-admin users are allowed to `view` and ` change
` the ` document
` resource if the condition is matched that the given user is also the document author.
Note that a separate policy file is expected for different types of resources and principals we want to create policies about. Our GitHub demo shows an example of a ` contacts.yaml
` resource policy file alongside the ` documents.yaml
` one.
Cerbos policy repository can be further enriched with defining context-aware roles, schemas, scopes, tests, and various other features explained in comprehensive Cerbos documentation.
Cerbos PDP is the Policy Decision Point, a component that evaluates application requests against authZ policies to make access decisions; determining whether a user action on a resource is allowed.
In this demo, we’ll set a Cerbos PDP within your repository, as a separate module, using the previously created ` cerbos
` directory. To run Cerbos PDP locally, do the following:
cerbos
` directory. You can name it ` conf.yaml
`.conf.yaml
` file define the port exposed for listening to HTTP (and/or gRPC) requests and the location of the Cerbos policy repository. The simplest ` conf.yaml
` file would look like the one shown below:server:
httpListenAddr: ":3592"
storage:
driver: "disk"
disk:
directory: /policies
For more robust configuration, make sure to check our Cerbos PDP configuration documentation.
Your file Cerbos-related file structure now might look like the following:
.
├── cerbos
│ └── policies
│ ├── documents.yaml
│ └── contacts.yaml
└── conf.yaml
Position your terminal within the ` cerbos
` directory. If you have Docker installed, you can simply run the following command to start Cerbos PDP locally in a Docker container.
docker run --rm --name cerbos -t \
-v $(pwd)/policies:/policies \
-p 3592:3592 \
ghcr.io/cerbos/cerbos:latest server
--config=conf.yaml
Cerbos PDP runs as a separate process from your Nuxt application. Here, we ran it as a standalone service within a docker container, but this is not a requirement. Cerbos is designed to be adaptable to your infrastructure. So if you want to run Cerbos PDP as a service, a sidecar, or a lambda function, for instance, check the Cerbos deployment documentation to learn more about Cerbos deployment patterns.
Adding a Cerbos client is essential for simplifying the communication between your Nuxt application and the Cerbos PDP. The Client will allow you to make user permission checks from your Nuxt application in an elegant manner.
To add the Cerbos client to your Nuxt application, follow these steps:
@cerbos/http
` for HTTP interactions or ` @cerbos/grpc
` for gRPC in server-side applications.npm install
` commandcerbos.ts
` to instantiate the Cerbos client.The ` cerbos.ts
` file would look like this:
import { HTTP as Cerbos} from "@cerbos/http";
export const cerbos = new Cerbos("localhost:3592");
A Nuxt API route is a feature in Nuxt.js used to define server-side logic and handle HTTP requests within the Nuxt application. These routes allow developers to create various back-end functionalities in the Nuxt project, such as data fetching, form submissions, or in this case authorization.
To create an API route in Nuxt for Cerbos permission checks:
isAllowed.ts
` file within the ` server/api
` folder of your Nuxt application.isAllowed.ts
` file, use ` defineEventHandler
` from ` nuxt-helpers
` to export your API handling function..isAllowed(...)
` method to check user permissions based on the request's user and resource details.import { cerbos } from "../utils/cerbos";
// Pull the user info from the session in your Nuxt applications
const user = {
id: "000012345",
roles: ["user"]
}
export default defineEventHandler(async (event) => {
const query = getQuery(event)
const document = {
id: query.documentId as string
}
const requestBody = {
principal: user,
resource: { // Pull the resource info from the data storage in your Nuxt applications. Pass Resource ID within the event as a query param, like we did here.
kind: "document",
id: document.id,
attributes: {
author: "000012347"
}
},
action: "approve"
}
const isAllowed = await cerbos.isAllowed(requestBody)
.catch( (error)=> {
console.log( error );
return false;
})
})
That’s it! You can now universally call this API as ` /api/isAllowed
` across your Nuxt application pages and components.
Let’s see the usage of Cerbos permission checks across your Nuxt application pages in action. Let’s say we’ve created a page for each of our documents on the path ` /documents/[id]
`. To do that
documents
` folder under the `pages` folder of your application.documents
` folder, create an ` [id].vue
` file.Nuxt offers route validation via the ` validate
` property in ` definePageMeta()
` in each page you wish to validate. The `validate` property accepts the route as an argument.
To use the ` /api/isAllowed
` route defined in the previous step you can add the following snippet to the bottom of your recently created ` [id].vue
` (or any other vue) file.
definePageMeta({
validate: async (route) => {
const { data: isAllowed } = await useFetch('/api/isAllowed',
{
headers: useRequestHeaders(),
query: { documentId: route.params.id }
})
return isAllowed.value;
}
})
It’s that simple!
All you have to do to use Cerbos authorization in your Nuxt application is to:
.isAllowed(...)
` checks and determine whether your application user should be allowed to make a certain action on a certain resource.In this tutorial you saw how to add fine-grained access control with Cerbos to your Nuxt applications. If you liked it make sure to check out Cerbos Hub.
Cerbos Hub saves time managing and synchronizing every Cerbos PDP and policy repository across all your applications and services. It helps connect your Cerbos policy repository and your Cerbos PDP instances and manage them collaboratively and smoothly from a single place.
We also published a series of articles with step-by-step instructions on how to Get started with Cerbos Hub. Take a look if you’re interested in seeing how it works!
Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team
Join thousands of developers | Features and updates | 1x per month | No spam, just goodies.