{"id":16726,"date":"2025-01-01T22:07:24","date_gmt":"2025-01-02T06:07:24","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=16726"},"modified":"2025-06-16T10:43:35","modified_gmt":"2025-06-16T17:43:35","slug":"permit-io-couchbase-access-control","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/permit-io-couchbase-access-control\/","title":{"rendered":"Como adicionar RBAC externo aos dados do Couchbase usando o Permit.io"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">As web applications grow in complexity, ensuring that only the right users have access to your Couchbase data is essential.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Without a well-defined access control system, unauthorized users may access sensitive information or perform harmful actions.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Integrating <\/span><a href=\"https:\/\/permit.io\/\"><span style=\"font-weight: 400;\">Permit<\/span><\/a><span style=\"font-weight: 400;\"> with Couchbase provides a robust solution for managing access control in applications leveraging Couchbase as the database. Permit is designed to streamline the authorization process, enabling developers to implement fine-grained access control while leveraging the advanced data management capabilities of Couchbase.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In this guide, we walk through building a simple request system where we pass a Couchbase query and check whether the relevant user has access to run that query based on rule-based format checks. If the user lacks permission, they\u2019ll be denied from running the query, if they have permission, they can proceed.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">What is Couchbase?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Couchbase is a robust NoSQL database, optimized for storing and managing JSON documents. Its ability to handle JSON objects is what sets it apart from traditional key value stores. This flexibility allows developers to be able to store, retrieve, and manage unstructured or semi-structured data easily, making it extremely useful for applications with evolving data models.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">One of the key strengths of Couchbase is its <\/span><a href=\"https:\/\/www.couchbase.com\/sqlplusplus\/\"><span style=\"font-weight: 400;\">SQL++ querying capability<\/span><\/a><span style=\"font-weight: 400;\"> which provides a familiar SQL-like syntax for JSON documents (formerly known as N1QL). This enables developers to perform powerful queries on their JSON data such as being able to add common table expressions, joins, and much more. This Couchbase query layer allows data to be stored in JSON format while also supporting sophisticated queries.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">What is RBAC?<\/span><span style=\"font-weight: 400;\"><br \/>\n<\/span><\/h2>\n<p><a href=\"https:\/\/www.permit.io\/rbac\"><span style=\"font-weight: 400;\">Role-Based Access Control (RBAC) <\/span><\/a><span style=\"font-weight: 400;\">is a model that helps simplify permission management inside of applications by organizing the system permissions around roles rather than specific individuals. It provides an approach to manage and restrict access to specific resources within a particular application or organization.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To implement external Role-Based Access Control with Couchbase, we will leverage <\/span><a href=\"https:\/\/permit.io\/\"><span style=\"font-weight: 400;\">Permit.io<\/span><\/a><span style=\"font-weight: 400;\">, an end-to-end solution for managing user permissions and roles with a simple UI. We will create a React application with the Express packet where the user passes the SQL++ query with the help of Couchbase. Then, we will see whether the user has the relevant permission. If they don&#8217;t, we&#8217;ll send out a message. If they do, we can modify the request.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Set up a Couchbase Cluster<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The first step is to create a free Capella account. To do this, navigate to <\/span><a href=\"https:\/\/cloud.couchbase.com\/\"><span style=\"font-weight: 400;\">cloud.couchbase.com <\/span><\/a><span style=\"font-weight: 400;\">and choose <\/span><b>Create Account<\/b><span style=\"font-weight: 400;\">, use an email and password combination. You can also sign up with your GitHub or Google account.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Once you have created your account on Capella, you can proceed with creating your database cluster. You can choose the <\/span><i><span style=\"font-weight: 400;\">Free tier<\/span><\/i><span style=\"font-weight: 400;\"> option for the cluster.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16728\" style=\"border: 1px black solid;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16-1024x607.jpg\" alt=\"\" width=\"900\" height=\"533\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16-1024x607.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16-300x178.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16-768x455.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image16.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">From the home page of your account, after logging in, click the<\/span><b> + Create Database<\/b><span style=\"font-weight: 400;\"> button in the top right corner and fill in the required details, including the name you chose for the database.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">When you are ready, go ahead and click on the final <\/span><b>Create Database<\/b><span style=\"font-weight: 400;\"> button.<\/span><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17.jpg\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16729\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17-1024x327.jpg\" alt=\"\" width=\"900\" height=\"287\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17-1024x327.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17-300x96.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17-768x245.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image17.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">You have now created a cluster. The next step is to add a bucket to hold your data. A bucket is similar to a database table, but with significant differences. Since you are working with unstructured and semi-structured JSON data, a single bucket can hold diverse types of data.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Head over to the <\/span><b>Data Tools<\/b><span style=\"font-weight: 400;\"> section, where you will find a pre-imported dataset known as the <\/span><i><span style=\"font-weight: 400;\">travel-sample<\/span><\/i><span style=\"font-weight: 400;\"> dataset.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16730\" style=\"border: 1px black solid;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18-1024x596.png\" alt=\"\" width=\"900\" height=\"524\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18-1024x596.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18-300x175.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18-768x447.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image18.png 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">You can insert more documents or create completely new buckets if needed. But for this demo we will use the <\/span><i><span style=\"font-weight: 400;\">travel-sample<\/span><\/i><span style=\"font-weight: 400;\"> dataset.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The following figure illustrates the relationship between the different kinds of documents in the travel-sample dataset. It shows the primary key, ID, and type fields that each document has, along with some other representative fields in each type of document.<\/span><\/p>\n<p><br style=\"font-weight: 400;\" \/><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image19.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-16731\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image19.png\" alt=\"\" width=\"538\" height=\"490\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image19.png 538w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image19-300x273.png 300w\" sizes=\"auto, (max-width: 538px) 100vw, 538px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">We will use this dataset for our demo. In order to interact with your data on Capella from your application, you need to know the connection string and create access credentials.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You can find the connection string by clicking the <\/span><b>Connect<\/b><span style=\"font-weight: 400;\"> button in the top navigation bar of the dashboard.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To add access credentials, navigate to this page in your Capella settings, as shown below, and click the <\/span><b>+ Create Database Access<\/b><span style=\"font-weight: 400;\"> button. Provide a name and password, then click <\/span><b>Save<\/b><span style=\"font-weight: 400;\">. Make sure to immediately add the credentials to an <\/span><i><span style=\"font-weight: 400;\">.env<\/span><\/i><span style=\"font-weight: 400;\"> file, as you won\u2019t be able to retrieve the password again after this.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16732\" style=\"border: 1px black solid;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20-1024x458.jpg\" alt=\"\" width=\"900\" height=\"403\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20-1024x458.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20-300x134.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20-768x343.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image20.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">After creating your credentials, your Capella setup is complete. Let\u2019s move to the RBAC part!<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Set up RBAC Permissions in Permit.io<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Ensure you have set up your account on <\/span><a href=\"https:\/\/permit.io\/\"><span style=\"font-weight: 400;\">Permit.io <\/span><\/a><span style=\"font-weight: 400;\">and created a project. In this demo, we will use the default project that was created.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Head over to the Policy Editor section, and within the Resources section, add the relevant resources corresponding to the <\/span><i><span style=\"font-weight: 400;\">travel-sample<\/span><\/i><span style=\"font-weight: 400;\"> dataset.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16733\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21-1024x353.png\" alt=\"\" width=\"900\" height=\"310\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21-1024x353.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21-300x103.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21-768x265.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image21.png 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">In this case, we will add the resources as <\/span><i><span style=\"font-weight: 400;\">Route<\/span><\/i><span style=\"font-weight: 400;\">, <\/span><i><span style=\"font-weight: 400;\">Airport<\/span><\/i><span style=\"font-weight: 400;\">, <\/span><i><span style=\"font-weight: 400;\">Hotel,<\/span><\/i><span style=\"font-weight: 400;\"> and <\/span><i><span style=\"font-weight: 400;\">Airline<\/span><\/i><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16734\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22-1024x665.jpg\" alt=\"\" width=\"900\" height=\"584\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22-1024x665.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22-300x195.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22-768x498.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image22.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Ensure that you have added the relevant actions.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Next, head over to the <\/span><b>Roles<\/b><span style=\"font-weight: 400;\"> section to add the specific user roles associated with the travel sample dataset.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For the dataset we\u2019re using, you will need to add the following roles: <\/span><i><span style=\"font-weight: 400;\">Traveler<\/span><\/i><span style=\"font-weight: 400;\">, <\/span><i><span style=\"font-weight: 400;\">Travel Agent<\/span><\/i><span style=\"font-weight: 400;\">, <\/span><i><span style=\"font-weight: 400;\">Airline Staff<\/span><\/i><span style=\"font-weight: 400;\"> and <\/span><i><span style=\"font-weight: 400;\">Hotel Staff<\/span><\/i><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><br style=\"font-weight: 400;\" \/><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16735\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23-1024x450.jpg\" alt=\"\" width=\"900\" height=\"396\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23-1024x450.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23-300x132.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23-768x337.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image23.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><span style=\"font-weight: 400;\">Now, head over to the <\/span><b>Policy Editor<\/b><span style=\"font-weight: 400;\"> section and define the relevant role-based access control definitions for each specific role corresponding to the resources defined. You can refer to the image below for the specific attributes to help create the policies. Then, go to the <\/span><b>Policy Editor<\/b><span style=\"font-weight: 400;\">, check all the checkboxes as shown below, and save your changes.<\/span><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16736\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-557x1024.png\" alt=\"\" width=\"557\" height=\"1024\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-557x1024.png 557w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-163x300.png 163w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-768x1412.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-836x1536.png 836w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24-300x551.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image24.png 940w\" sizes=\"auto, (max-width: 557px) 100vw, 557px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Next, head to the directory section to create a new tenant. Once you have created the tenant, add users based on their roles.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We will create new users for hotel staff, travel agents, and travelers.<\/span><\/p>\n<p><br style=\"font-weight: 400;\" \/><a href=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-16737\" style=\"border: 1px solid black;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13-1024x578.jpg\" alt=\"\" width=\"900\" height=\"508\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13-1024x578.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13-300x169.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13-768x433.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/image13.jpg 1248w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">For each user, add their email, first name, last name, and specific role in the top-level access section.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That&#8217;s all it took to create a Role-Based Access Control (RBAC) model for the travel sample dataset using Permit UI.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Implementing Fine-Grained RBAC for Couchbase with Permit.io<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Now let\u2019s implement our Couchbase SQL++ query parser with Permit.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">First, we\u2019ll set up a Node.js project with Express for our backend server. We&#8217;ll use the Couchbase SDK for Node.js and the Permit.io SDK.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here&#8217;s our <\/span><i><span style=\"font-weight: 400;\">package.json<\/span><\/i><span style=\"font-weight: 400;\"> file with the necessary dependencies:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">{\r\n  \"name\": \"backend\",\r\n  \"version\": \"1.0.0\",\r\n  \"main\": \"index.js\",\r\n  \"scripts\": {\r\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\r\n  },\r\n  \"keywords\": [],\r\n  \"author\": \"\",\r\n  \"license\": \"ISC\",\r\n  \"description\": \"\",\r\n  \"dependencies\": {\r\n    \"cors\": \"^2.8.5\",\r\n    \"couchbase\": \"^4.4.3\",\r\n    \"dotenv\": \"^16.4.5\",\r\n    \"express\": \"^4.21.1\",\r\n    \"permitio\": \"^2.6.1\"\r\n  }\r\n}<\/pre>\n<h3><span style=\"font-weight: 400;\">Implementing the Server<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Let&#8217;s break it down into key components:<\/span><\/p>\n<h4><b>Initialization<\/b><\/h4>\n<p><span style=\"font-weight: 400;\">We start by setting up our Express server and initializing the Permit.io client:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true \">const express = require('express');\r\nconst cors = require('cors');\r\nconst { Permit } = require('permitio'); const couchbase = require('couchbase'); require('dotenv').config();\r\nconst app = express();\r\nconst port = process.env.PORT || 3001;\r\napp.use(cors({\r\n  origin: 'https:\/\/localhost:5173',\r\n  methods: ['POST'],\r\n  allowedHeaders: ['Content-Type'],\r\n}));\r\n\r\n\/\/ Initialize Permit client\r\nconst permit = new Permit({\r\n  token: process.env.PERMIT_SDK_TOKEN,\r\n  pdp: \"https:\/\/cloudpdp.api.permit.io\"\r\n});<\/pre>\n<h4><b>Parsing SQL++ Queries<\/b><\/h4>\n<p><span style=\"font-weight: 400;\">To work with the incoming Couchbase queries, we need to parse them. We&#8217;ve implemented a simple parser that extracts the SELECT, FROM, and WHERE clauses from the input query.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s look at the core components of our parser:<\/span><\/p>\n<p><b>Query Parser<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The QueryParser class is the foundation of our security implementation. It handles two critical tasks:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Query Analysis: <\/b><span style=\"font-weight: 400;\">P<\/span><span style=\"font-weight: 400;\">arses SQL++ queries to determine:<\/span><\/li>\n<\/ol>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Operation type SELECT, UPDATE, DELETE, INSERT<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Resource being accessed<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Query structure validation<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre class=\"nums:false lang:js decode:true\">static parseQuery(query) {\r\n\u00a0 \/\/ Extract resource from SELECT statement (word before t const\r\n\u00a0 selectResourcePattern = \/SELECT\\s+(\\w+)\\.\/i;\r\n\r\n\u00a0 \/\/ Basic regex patterns for SQL operations\r\n\u00a0 const patterns = {\r\n\u00a0 \u00a0 select: \/^\\s*SELECT\\s+(?:(?!FROM).)*\\s+FROM\\s+[`]?(\\\r\n\u00a0 \u00a0 update: \/^\\s*UPDATE\\s+[`]?(\\w+)[`]?(?:\\.`?(\\w+)`?)?(\r\n\u00a0 \u00a0 delete: \/^\\s*DELETE\\s+FROM\\s+[`]?(\\w+)[`]?(?:\\.`?(\\w\r\n\u00a0 \u00a0 insert: \/^\\s*INSERT\\s+INTO\\s+[`]?(\\w+)[`]?(?:\\.`?(\\w\r\n\u00a0 };\r\n\r\n\u00a0 \/\/ Determine operation type and extract resource let operation = '';\r\n\u00a0 let resource = '';\r\n\u00a0 if (patterns.select.test(query)) {\r\n\u00a0 \u00a0 operation = 'read';\r\n\u00a0 \u00a0 const resourceMatch = query.match(selectResourcePatt if (resourceMatch &amp;&amp; resourceMatch[1]) {\r\n\u00a0 \u00a0 resource = resourceMatch[1];\r\n\u00a0 \u00a0 \u00a0 } else {\r\n\u00a0 \u00a0 throw new Error('Unable to parse resource from S\r\n\u00a0 \u00a0 }\r\n\u00a0 } else if (patterns.update.test(query)) { operation = 'update';\r\n\u00a0 \u00a0 const matches = query.match(patterns.update); resource = matches[3] || matches[2] || matches[1];\r\n\u00a0 } else if (patterns.delete.test(query)) {\r\n\u00a0 \u00a0 operation = 'delete';\r\n\u00a0 \u00a0 const matches = query.match(patterns.delete); resource = matches[3] || matches[2] || matches[1];\r\n\u00a0 } else if (patterns.insert.test(query)) { operation = 'create';\r\n\u00a0 \u00a0 const matches = query.match(patterns.insert); resource = matches[3] || matches[2] || matches[1];\r\n\u00a0 }\r\n\r\n\u00a0 if (!operation || !resource) {\r\n\u00a0 \u00a0 throw new Error('Unable to parse query operation or\r\n\u00a0 }\r\n\r\n\u00a0 return {\r\n\u00a0 \u00a0 query,\r\n\u00a0 \u00a0 permission: operation,\r\n\u00a0 \u00a0 resource: resource.toLowerCase()\r\n\u00a0 };\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>2. <b>Security Validation<\/b><span style=\"font-weight: 400;\">: Implements security checks to prevent SQL injection and other attacks:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">static validateQuery(query) {\r\n\r\n\u00a0 \/\/ Basic security validation\r\n\u00a0 const disallowedPatterns = [\r\n\u00a0   \/;.*;\/i,           \/\/ Multiple statements\r\n\u00a0   \/--\/,              \/\/ SQL comments\r\n\u00a0   \/\\\/\\*\/,            \/\/ Block comments\r\n\u00a0   \/xp_\/i,            \/\/ Extended stored procedur\r\n\u00a0   \/EXECUTE\\s+sp_\/i,  \/\/ Stored procedure executi\r\n\u00a0   \/EXEC\\s+sp_\/i,     \/\/ Stored procedure executi\r\n\u00a0   \/INTO\\s+OUTFILE\/i, \/\/ File operations\r\n\u00a0   \/LOAD_FILE\/i,      \/\/ File operations\r\n\u00a0 ];\r\n\r\n\u00a0 for (const pattern of disallowedPatterns) {\r\n\u00a0 \u00a0 if (pattern.test(query)) {\r\n\u00a0 \u00a0 \u00a0 throw new Error('Query contains potentially harm\r\n\u00a0 \u00a0 }\r\n\u00a0 }\r\n\r\n\u00a0 return true;\r\n}<\/pre>\n<h4><b>Permission Management<\/b><\/h4>\n<p><span style=\"font-weight: 400;\">The <\/span><i><span style=\"font-weight: 400;\">TravelQueryChecker<\/span><\/i><span style=\"font-weight: 400;\"> class handles the core permission logic:<\/span><\/p>\n<ol>\n<li><b>Initialization:<\/b><span style=\"font-weight: 400;\"> Sets up connections to both Permit.io and Couchbase:<\/span><\/li>\n<\/ol>\n<pre class=\"nums:false lang:js decode:true\">class TravelQueryChecker {\r\n  constructor() {\r\n    this.permit = new Permit({\r\n      token: process.env.PERMIT_SDK_TOKEN,\r\n      pdp: \"https:\/\/cloudpdp.api.permit.io\"\r\n    });\r\n\r\n    this.clusterConnStr = 'couchbases:\/\/cb.6gj2r4ygxyjrfcgf\r\n    this.username = 'shivay1';\r\n    this.password = 'Shivay1234!';\r\n    this.bucketName = 'travel-sample';\r\n  }\r\n\r\n  async init() {\r\n    try {\r\n      this.cluster = await couchbase.connect(this.clusterC username: this.username,\r\n        password: this.password,\r\n        configProfile: 'wanDevelopment',\r\n      });\r\n\r\n      this.bucket = this.cluster.bucket(this.bucketName); \r\n      this.collection = this.bucket.defaultCollection(); \r\n      console.log('Connected to Couchbase Capella');\r\n    } catch (error) {\r\n      console.error('Couchbase connection error:', error); \r\n      throw error;\r\n  }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<ol start=\"2\">\n<li><b>Permission Checking:<\/b><span style=\"font-weight: 400;\"> Verifies user permissions through Permit.io:<\/span><\/li>\n<\/ol>\n<pre class=\"nums:false lang:js decode:true\">async checkQueryPermission(userId, queryConfig) { if (!queryConfig) \r\n  {\r\n    return { permitted: false, error: 'Invalid query con\r\n  }\r\n  try {\r\n    const permitted = await this.permit.check(\r\n      String(userId),\r\n      queryConfig.permission,\r\n      {\r\n        type: queryConfig.resource,\r\n        tenant: \"default\",\r\n        resource: queryConfig.resource\r\n      }\r\n   );\r\n \r\n    return {\r\n      permitted,\r\n      query: queryConfig.query,\r\n      permission: queryConfig.permission,\r\n      resource: queryConfig.resource\r\n    };\r\n    } catch (error) {\r\n      console.error('Permission check error:', error); \r\n      return { permitted: false, error: error.message };\r\n    }\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">This function uses the <\/span><a href=\"https:\/\/permit.io\/\"><span style=\"font-weight: 400;\">Permit.io<\/span><\/a><span style=\"font-weight: 400;\"> SDK to check if a user has permission to perform a specific action on a resource.<\/span><\/p>\n<p>3. <b>Query Execution<\/b><span style=\"font-weight: 400;\">: Handles the complete flow from permission check to query execution:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">async executeQuery(userId, rawQuery, params = [])\r\n\u00a0 { try {\r\n\r\n\u00a0 \u00a0 \/\/Validate query for security\r\n\u00a0 \u00a0 QueryParser.validateQuery(rawQuery);\r\n\r\n\u00a0 \u00a0 \/\/Parse the query to get permission and resource\r\n\u00a0 \u00a0 const queryConfig = QueryParser.parseQuery(rawQuery)\r\n\u00a0 \u00a0 console.log('Parsed query config:', queryConfig);\r\n\u00a0 \u00a0 const permissionCheck = await this.checkQueryPermiss\r\n\r\n\u00a0 \u00a0 if (!permissionCheck.permitted) {\r\n\u00a0 \u00a0 \u00a0 return {\r\n\u00a0 \u00a0 \u00a0 \u00a0 status: 'not-permitted',\r\n\u00a0 \u00a0 \u00a0 \u00a0 error: `User ${userId} is not permitted to e \u00a0\r\n\u00a0 \u00a0 \u00a0 };\r\n\u00a0 \u00a0 }\r\n\r\n\u00a0 \u00a0 const options = { parameters: params };\r\n\u00a0 \u00a0 const result = await this.cluster.query(rawQuery,\r\n\u00a0 \u00a0 op return {\r\n\u00a0 \u00a0 \u00a0 status: 'permitted',\r\n\u00a0 \u00a0 \u00a0 success: true,\r\n\u00a0 \u00a0 \u00a0 results: result.rows,\r\n\u00a0 \u00a0 \u00a0 metadata: {\r\n\u00a0 \u00a0 \u00a0 \u00a0 metrics: result.metrics,\r\n\u00a0 \u00a0 \u00a0 \u00a0 profile: result.profile\r\n\u00a0 \u00a0 \u00a0 }\r\n\u00a0 \u00a0 };\r\n\u00a0 } catch (error) {\r\n\u00a0 \u00a0 \u00a0 console.error('Query execution error:', error);\r\n\u00a0 \u00a0 \u00a0 return {\r\n\u00a0 \u00a0 \u00a0 \u00a0 status: 'error',\r\n\u00a0 \u00a0 \u00a0 \u00a0 error: error.message\r\n\u00a0 \u00a0 };\r\n\u00a0 }\r\n}<\/pre>\n<h4><b>API Endpoint<\/b><\/h4>\n<p><span style=\"font-weight: 400;\">Finally, we expose an API endpoint to handle incoming queries:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true \">\/\/ Route to handle SQL++ queries\r\napp.post('\/query', async (req, res) =&gt; {\r\n  const { userId, query, params } = req.body;\r\n\r\n  if (!userId || !query) {\r\n    return res.status(400).json({ error: 'userId and query a\r\n  }\r\n\r\n  try {\r\n    const result = await queryChecker.executeQuery(userId, q res.json(result);\r\n  } catch (error) {\r\n    res.status(500).json({ error: error.message }); \r\n  }\r\n});<\/pre>\n<p>&nbsp;<\/p>\n<h4><b>Couchbase Connection<\/b><\/h4>\n<p><span style=\"font-weight: 400;\">We will now define the Couchbase connection code in our backend Express server, which helps us to connect to the Couchbase Cluster:<\/span><\/p>\n<pre class=\"nums:false lang:default decode:true\">\/\/ Connect to Couchbase cluster\r\n  async init() {\r\n    try {\r\n      this.cluster = await couchbase.connect(this.clusterC \r\n        username: this.username,\r\n        password: this.password,\r\n        configProfile: 'wanDevelopment',\r\n      });\r\n\r\n      this.bucket = this.cluster.bucket(this.bucketName); \r\n      this.collection = this.bucket.defaultCollection(); \r\n      console.log('Connected to Couchbase Capella');\r\n    } catch (error) {\r\n      console.error('Couchbase connection error:', error); \r\n      throw error;\r\n    }\r\n}<\/pre>\n<h3><span style=\"font-weight: 400;\">Frontend Code<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">To demonstrate the functionality for the integration, we&#8217;ve created a simple React frontend that allows users to input queries and see the results.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For setup, you can check this code for the existing UI components:<\/span><\/p>\n<pre class=\"nums:false lang:js decode:true\">import React, { useState } from 'react';\r\nimport { Button } from \"@\/components\/ui\/button\"\r\nimport { Input } from \"@\/components\/ui\/input\"\r\nimport { Textarea } from \"@\/components\/ui\/textarea\"\r\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@\/components\/ui\/card\"\r\nexport default function App() {\r\n  const [query, setQuery] = useState('');\r\n  const [user, setUser] = useState('');\r\n  const [result, setResult] = useState&lt;null | { success: boolean; results?: any[]; error?: string }&gt;(null);\r\n\r\n  const handleSubmit = async (e: React.FormEvent) =&gt; {\r\n    e.preventDefault();\r\n    try {\r\n      const response = await fetch('https:\/\/localhost:3001\/query', {\r\n        method: 'POST',\r\n        headers: {\r\n          'Content-Type': 'application\/json',\r\n        },\r\n        body: JSON.stringify({ query, user }),\r\n      });\r\n      const data = await response.json();\r\n      setResult(data);\r\n    } catch (error) {\r\n      console.error('Error:', error);\r\n      setResult({ success: false, error: 'An error occurred while processing your request.' });\r\n    }\r\n  };\r\n\r\n  return (\r\n    &lt;div className=\"container mx-auto p-4\"&gt;\r\n      &lt;Card className=\"w-full max-w-2xl mx-auto\"&gt;\r\n        &lt;CardHeader&gt;\r\n          &lt;CardTitle&gt;Permission Checker&lt;\/CardTitle&gt;\r\n          &lt;CardDescription&gt;Enter a query and user to check permissions&lt;\/CardDescription&gt;\r\n        &lt;\/CardHeader&gt;\r\n        &lt;CardContent&gt;\r\n          &lt;form onSubmit={handleSubmit} className=\"space-y-4\"&gt;\r\n            &lt;div&gt;\r\n              &lt;label htmlFor=\"query\" className=\"block text-sm font-medium text-gray-700\"&gt;Query&lt;\/label&gt;\r\n              &lt;Textarea\r\n                id=\"query\"\r\n                value={query}\r\n                onChange={(e) =&gt; setQuery(e.target.value)}\r\n                placeholder=\"Enter your SQL++ query here\"\r\n                className=\"mt-1\"\r\n                rows={4}\r\n              \/&gt;\r\n            &lt;\/div&gt;\r\n            &lt;div&gt;\r\n              &lt;label htmlFor=\"user\" className=\"block text-sm font-medium text-gray-700\"&gt;User&lt;\/label&gt;\r\n              &lt;Input\r\n                id=\"user\"\r\n                type=\"text\"\r\n                value={user}\r\n                onChange={(e) =&gt; setUser(e.target.value)}\r\n                placeholder=\"Enter user email\"\r\n                className=\"mt-1\"\r\n              \/&gt;\r\n            &lt;\/div&gt;\r\n            &lt;Button type=\"submit\" className=\"w-full\"&gt;Check Permissions&lt;\/Button&gt;\r\n          &lt;\/form&gt;\r\n        &lt;\/CardContent&gt;\r\n        &lt;CardFooter&gt;\r\n          {result &amp;&amp; (\r\n            &lt;div className={`mt-4 p-4 rounded ${result.success ? 'bg-green-100' : 'bg-red-100'}`}&gt;\r\n              {result.success ? (\r\n                &lt;div&gt;\r\n                  &lt;h3 className=\"font-bold text-green-800\"&gt;Permission Granted&lt;\/h3&gt;\r\n                  &lt;pre className=\"mt-2 whitespace-pre-wrap\"&gt;{JSON.stringify(result.results, null, 2)}&lt;\/pre&gt;\r\n                &lt;\/div&gt;\r\n              ) : (\r\n                &lt;div&gt;\r\n                  &lt;h3 className=\"font-bold text-red-800\"&gt;Permission Denied&lt;\/h3&gt;\r\n                  &lt;p&gt;{result.error}&lt;\/p&gt;\r\n                &lt;\/div&gt;\r\n              )}\r\n            &lt;\/div&gt;\r\n          )}\r\n        &lt;\/CardFooter&gt;\r\n      &lt;\/Card&gt;\r\n    &lt;\/div&gt;\r\n  );\r\n}\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">This given React component allows users to enter a query and their user identifier, then displays the results or any permission-related errors.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">For the complete code, check out the <\/span><a href=\"https:\/\/github.com\/Arindam200\/permit-couchbase\"><span style=\"font-weight: 400;\">Permit-Demo<\/span><\/a><span style=\"font-weight: 400;\"> GitHub repository.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Demo<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">With everything in place, you can run the backend Express server and the React application separately. Once both are running, you will see a UI like the one below. Add the query and the corresponding user, then click the <\/span><b>Check Permissions<\/b><span style=\"font-weight: 400;\"> button.<\/span><\/p>\n<div id=\"attachment_16738\" style=\"width: 910px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/prod-files-secure.s3.us-west-2.amazonaws.com\/990b93c0-b79d-4%20965-a17f-a8c192093951\/1452ba19-4cc7-42f8-a8ca-ae50f0f14429\/permit_%20(online-video-cutter.com).mp4\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-16738\" class=\"wp-image-16738 size-large\" style=\"border: 1px black solid;\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-1024x607.png\" alt=\"\" width=\"900\" height=\"533\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-1024x607.png 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-300x178.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-768x455.png 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-1536x911.png 1536w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-2048x1214.png 2048w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/Screenshot-2025-01-01-at-10.55.49\u202fPM-1320x783.png 1320w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><p id=\"caption-attachment-16738\" class=\"wp-caption-text\">Click on image to launch demo video<\/p><\/div>\n<p><span style=\"font-weight: 400;\">In the example above, you can see the user who has permission and the user who does not have permission to access the resource.<\/span><\/p>\n<h2>Conclusion<\/h2>\n<p><span style=\"font-weight: 400;\">In this tutorial, we explored how to set up and configure Permit to add RBAC settings for the Couchbase travel-sample dataset and how to check for permissions for a given SQL++ query.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">What if you want a more granular level of control than user roles, focusing on user-specific identities? For that and more, we recommend continuing to explore our learning materials, such as <\/span><a href=\"https:\/\/www.permit.io\/blog\/rbac-vs-abac\"><b>the difference between RBAC and ABAC<\/b> <\/a><span style=\"font-weight: 400;\">and <\/span><a href=\"https:\/\/www.permit.io\/abac\"><b>adding ABAC to your application with Permit<\/b><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Want to learn more about implementing authorization? Got questions? Reach out\u00a0<\/span><span style=\"font-weight: 400;\">to us in our <\/span><a href=\"https:\/\/io.permit.io\/permitslack\"><b>Slack community<\/b><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As web applications grow in complexity, ensuring that only the right users have access to your Couchbase data is essential. Without a well-defined access control system, unauthorized users may access sensitive information or perform harmful actions. Integrating Permit with Couchbase [&hellip;]<\/p>\n","protected":false},"author":85559,"featured_media":16739,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,3917,2242,2225,9921,1813],"tags":[10070,1903,1962],"ppma_author":[10069],"class_list":["post-16726","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-company","category-connectors","category-cloud","category-partners","category-security","tag-permit-io","tag-rbac","tag-role-based-access-control"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Adding External RBAC to Couchbase Data Using Permit.io - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Discover how to secure Couchbase data with Permit.io and implement fine-grained role-based access control (RBAC) for your applications.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/permit-io-couchbase-access-control\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Adding External RBAC to Couchbase Data Using Permit.io\" \/>\n<meta property=\"og:description\" content=\"Discover how to secure Couchbase data with Permit.io and implement fine-grained role-based access control (RBAC) for your applications.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/permit-io-couchbase-access-control\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-02T06:07:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-16T17:43:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Shivay Lamba, Developer Evangelist\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shivay Lamba, Developer Evangelist\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\"},\"author\":{\"name\":\"Shivay Lamba, Developer Evangelist\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/377d9b772c90439916236da79c02c418\"},\"headline\":\"Adding External RBAC to Couchbase Data Using Permit.io\",\"datePublished\":\"2025-01-02T06:07:24+00:00\",\"dateModified\":\"2025-06-16T17:43:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\"},\"wordCount\":1534,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/blog-permitio-rbac-couchbase.png\",\"keywords\":[\"permit.io\",\"RBAC\",\"Role Based Access Control (RBAC)\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Company\",\"Connectors\",\"Couchbase Capella\",\"Partners\",\"Security\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\",\"name\":\"Adding External RBAC to Couchbase Data Using Permit.io - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/blog-permitio-rbac-couchbase.png\",\"datePublished\":\"2025-01-02T06:07:24+00:00\",\"dateModified\":\"2025-06-16T17:43:35+00:00\",\"description\":\"Discover how to secure Couchbase data with Permit.io and implement fine-grained role-based access control (RBAC) for your applications.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/blog-permitio-rbac-couchbase.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/blog-permitio-rbac-couchbase.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Adding External RBAC to Couchbase Data Using Permit.io\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/377d9b772c90439916236da79c02c418\",\"name\":\"Shivay Lamba, Developer Evangelist\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/shivay-lambda-couchbase.jpeg7b5e7cd8007bd40de81c1ef6a9e0266f\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/shivay-lambda-couchbase.jpeg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2025\\\/01\\\/shivay-lambda-couchbase.jpeg\",\"caption\":\"Shivay Lamba, Developer Evangelist\"},\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/shivaylambda\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Adding External RBAC to Couchbase Data Using Permit.io - The Couchbase Blog","description":"Descubra como proteger os dados do Couchbase com o Permit.io e implementar o controle de acesso baseado em fun\u00e7\u00e3o (RBAC) refinado para seus aplicativos.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/permit-io-couchbase-access-control\/","og_locale":"pt_BR","og_type":"article","og_title":"Adding External RBAC to Couchbase Data Using Permit.io","og_description":"Discover how to secure Couchbase data with Permit.io and implement fine-grained role-based access control (RBAC) for your applications.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/permit-io-couchbase-access-control\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-01-02T06:07:24+00:00","article_modified_time":"2025-06-16T17:43:35+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png","type":"image\/png"}],"author":"Shivay Lamba, Developer Evangelist","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Shivay Lamba, Developer Evangelist","Est. reading time":"9 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"},"author":{"name":"Shivay Lamba, Developer Evangelist","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/377d9b772c90439916236da79c02c418"},"headline":"Adding External RBAC to Couchbase Data Using Permit.io","datePublished":"2025-01-02T06:07:24+00:00","dateModified":"2025-06-16T17:43:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"},"wordCount":1534,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png","keywords":["permit.io","RBAC","Role Based Access Control (RBAC)"],"articleSection":["Best Practices and Tutorials","Company","Connectors","Couchbase Capella","Partners","Security"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/","url":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/","name":"Adding External RBAC to Couchbase Data Using Permit.io - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png","datePublished":"2025-01-02T06:07:24+00:00","dateModified":"2025-06-16T17:43:35+00:00","description":"Descubra como proteger os dados do Couchbase com o Permit.io e implementar o controle de acesso baseado em fun\u00e7\u00e3o (RBAC) refinado para seus aplicativos.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/blog-permitio-rbac-couchbase.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Adding External RBAC to Couchbase Data Using Permit.io"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/377d9b772c90439916236da79c02c418","name":"Shivay Lamba, desenvolvedor evangelista","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/shivay-lambda-couchbase.jpeg7b5e7cd8007bd40de81c1ef6a9e0266f","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/shivay-lambda-couchbase.jpeg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/shivay-lambda-couchbase.jpeg","caption":"Shivay Lamba, Developer Evangelist"},"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/shivaylambda\/"}]}},"acf":[],"authors":[{"term_id":10069,"user_id":85559,"is_guest":0,"slug":"shivaylambda","display_name":"Shivay Lamba, Developer Evangelist","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/shivay-lambda-couchbase.jpeg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/01\/shivay-lambda-couchbase.jpeg"},"0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/16726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/85559"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=16726"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/16726\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/16739"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=16726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=16726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=16726"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=16726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}