{"id":4427,"date":"2025-01-01T22:07:24","date_gmt":"2025-01-02T06:07:24","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"},"modified":"2025-01-01T22:07:24","modified_gmt":"2025-01-02T06:07:24","slug":"permit-io-couchbase-access-control","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/permit-io-couchbase-access-control\/","title":{"rendered":"Adding External RBAC to Couchbase Data Using Permit.io"},"content":{"rendered":"\n<p><span>As web applications grow in complexity, ensuring that only the right users have access to your Couchbase data is essential.<\/span><\/p>\n\n\n\n<p><span>Without a well-defined access control system, unauthorized users may access sensitive information or perform harmful actions.<\/span><\/p>\n\n\n\n<p><span>Integrating <\/span><a href=\"https:\/\/permit.io\/\"><span>Permit<\/span><\/a><span> 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\n\n\n<p><span>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\n\n\n<h2 class=\"wp-block-heading\"><span>What is Couchbase?<\/span><\/h2>\n\n\n\n<p><span>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\n\n\n<p><span>One of the key strengths of Couchbase is its <\/span><a href=\"https:\/\/www.couchbase.com\/sqlplusplus\/\"><span>SQL++ querying capability<\/span><\/a><span> 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\n\n\n<h2 class=\"wp-block-heading\"><span>What is RBAC?<\/span><span><br>\n<\/span><\/h2>\n\n\n\n<p><a href=\"https:\/\/www.permit.io\/rbac\"><span>Role-Based Access Control (RBAC) <\/span><\/a><span>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\n\n\n<p><span>To implement external Role-Based Access Control with Couchbase, we will leverage <\/span><a href=\"https:\/\/permit.io\/\"><span>Permit.io<\/span><\/a><span>, 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\n\n\n<h2 class=\"wp-block-heading\"><span>Set up a Couchbase Cluster<\/span><\/h2>\n\n\n\n<p><span>The first step is to create a free Capella account. To do this, navigate to <\/span><a href=\"https:\/\/cloud.couchbase.com\/\"><span>cloud.couchbase.com <\/span><\/a><span>and choose <\/span><b>Create Account<\/b><span>, use an email and password combination. You can also sign up with your GitHub or Google account.<\/span><\/p>\n\n\n\n<p><span>Once you have created your account on Capella, you can proceed with creating your database cluster. You can choose the <\/span><i><span>Free tier<\/span><\/i><span> option for the cluster.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image16-1024x607-1.jpg\" alt=\"\" width=\"900\" height=\"533\"><\/a><\/p>\n\n\n\n<p><span>From the home page of your account, after logging in, click the<\/span><b> + Create Database<\/b><span> button in the top right corner and fill in the required details, including the name you chose for the database.<\/span><\/p>\n\n\n\n<p><span>When you are ready, go ahead and click on the final <\/span><b>Create Database<\/b><span> 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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image17-1024x327-1.jpg\" alt=\"\" width=\"900\" height=\"287\"><\/a><\/p>\n\n\n\n<p><span>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\n\n\n<p><span>Head over to the <\/span><b>Data Tools<\/b><span> section, where you will find a pre-imported dataset known as the <\/span><i><span>travel-sample<\/span><\/i><span> dataset.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image18-1024x596-1.png\" alt=\"\" width=\"900\" height=\"524\"><\/a><\/p>\n\n\n\n<p><span>You can insert more documents or create completely new buckets if needed. But for this demo we will use the <\/span><i><span>travel-sample<\/span><\/i><span> dataset.<\/span><\/p>\n\n\n\n<p><span>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\n\n\n<p><br><a href=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image19-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-16731\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image19-3.png\" alt=\"\" width=\"538\" height=\"490\"><\/a><\/p>\n\n\n\n<p><span>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\n\n\n<p><span>You can find the connection string by clicking the <\/span><b>Connect<\/b><span> button in the top navigation bar of the dashboard.<\/span><\/p>\n\n\n\n<p><span>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> button. Provide a name and password, then click <\/span><b>Save<\/b><span>. Make sure to immediately add the credentials to an <\/span><i><span>.env<\/span><\/i><span> file, as you won\u2019t be able to retrieve the password again after this.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image20-1024x458-1.jpg\" alt=\"\" width=\"900\" height=\"403\"><\/a><\/p>\n\n\n\n<p><span>After creating your credentials, your Capella setup is complete. Let\u2019s move to the RBAC part!<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>Set up RBAC Permissions in Permit.io<\/span><\/h2>\n\n\n\n<p><span>Ensure you have set up your account on <\/span><a href=\"https:\/\/permit.io\/\"><span>Permit.io <\/span><\/a><span>and created a project. In this demo, we will use the default project that was created.<\/span><\/p>\n\n\n\n<p><span>Head over to the Policy Editor section, and within the Resources section, add the relevant resources corresponding to the <\/span><i><span>travel-sample<\/span><\/i><span> dataset.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image21-1024x353-1.png\" alt=\"\" width=\"900\" height=\"310\"><\/a><\/p>\n\n\n\n<p><span>In this case, we will add the resources as <\/span><i><span>Route<\/span><\/i><span>, <\/span><i><span>Airport<\/span><\/i><span>, <\/span><i><span>Hotel,<\/span><\/i><span> and <\/span><i><span>Airline<\/span><\/i><span>.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image22-1024x665-1.jpg\" alt=\"\" width=\"900\" height=\"584\"><\/a><\/p>\n\n\n\n<p><span>Ensure that you have added the relevant actions.<\/span><\/p>\n\n\n\n<p><span>Next, head over to the <\/span><b>Roles<\/b><span> section to add the specific user roles associated with the travel sample dataset.<\/span><\/p>\n\n\n\n<p><span>For the dataset we\u2019re using, you will need to add the following roles: <\/span><i><span>Traveler<\/span><\/i><span>, <\/span><i><span>Travel Agent<\/span><\/i><span>, <\/span><i><span>Airline Staff<\/span><\/i><span> and <\/span><i><span>Hotel Staff<\/span><\/i><span>.<\/span><\/p>\n\n\n\n<p><br><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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image23-1024x450-1.jpg\" alt=\"\" width=\"900\" height=\"396\"><\/a><span>Now, head over to the <\/span><b>Policy Editor<\/b><span> 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>, check all the checkboxes as shown below, and save your changes.<\/span><\/p>\n\n\n\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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image24-557x1024-1.png\" alt=\"\" width=\"557\" height=\"1024\"><\/a><\/p>\n\n\n\n<p><span>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\n\n\n<p><span>We will create new users for hotel staff, travel agents, and travelers.<\/span><\/p>\n\n\n\n<p><br><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\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/image13-1024x578-1.jpg\" alt=\"\" width=\"900\" height=\"508\"><\/a><\/p>\n\n\n\n<p><span>For each user, add their email, first name, last name, and specific role in the top-level access section.<\/span><\/p>\n\n\n\n<p><span>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\n\n\n<h2 class=\"wp-block-heading\"><span>Implementing Fine-Grained RBAC for Couchbase with Permit.io<\/span><\/h2>\n\n\n\n<p><span>Now let\u2019s implement our Couchbase SQL++ query parser with Permit.<\/span><\/p>\n\n\n\n<p><span>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\n\n\n<p><span>Here&#8217;s our <\/span><i><span>package.json<\/span><\/i><span> file with the necessary dependencies:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]{<br \/>\n  &#8220;name&#8221;: &#8220;backend&#8221;,<br \/>\n  &#8220;version&#8221;: &#8220;1.0.0&#8221;,<br \/>\n  &#8220;main&#8221;: &#8220;index.js&#8221;,<br \/>\n  &#8220;scripts&#8221;: {<br \/>\n    &#8220;test&#8221;: &#8220;echo &#8220;Error: no test specified&#8221; &amp;&amp; exit 1&#8243;<br \/>\n  },<br \/>\n  &#8220;keywords&#8221;: [],<br \/>\n  &#8220;author&#8221;: &#8220;&#8221;,<br \/>\n  &#8220;license&#8221;: &#8220;ISC&#8221;,<br \/>\n  &#8220;description&#8221;: &#8220;&#8221;,<br \/>\n  &#8220;dependencies&#8221;: {<br \/>\n    &#8220;cors&#8221;: &#8220;^2.8.5&#8221;,<br \/>\n    &#8220;couchbase&#8221;: &#8220;^4.4.3&#8221;,<br \/>\n    &#8220;dotenv&#8221;: &#8220;^16.4.5&#8221;,<br \/>\n    &#8220;express&#8221;: &#8220;^4.21.1&#8221;,<br \/>\n    &#8220;permitio&#8221;: &#8220;^2.6.1&#8221;<br \/>\n  }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Implementing the Server<\/span><\/h3>\n\n\n\n<p><span>Let&#8217;s break it down into key components:<\/span><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><b>Initialization<\/b><\/h4>\n\n\n\n<p><span>We start by setting up our Express server and initializing the Permit.io client:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]const express = require(&#8216;express&#8217;);<br \/>\nconst cors = require(&#8216;cors&#8217;);<br \/>\nconst { Permit } = require(&#8216;permitio&#8217;); const couchbase = require(&#8216;couchbase&#8217;); require(&#8216;dotenv&#8217;).config();<br \/>\nconst app = express();<br \/>\nconst port = process.env.PORT || 3001;<br \/>\napp.use(cors({<br \/>\n  origin: &#8216;https:\/\/localhost:5173&#8217;,<br \/>\n  methods: [&#8216;POST&#8217;],<br \/>\n  allowedHeaders: [&#8216;Content-Type&#8217;],<br \/>\n}));<\/p>\n<p>\/\/ Initialize Permit client<br \/>\nconst permit = new Permit({<br \/>\n  token: process.env.PERMIT_SDK_TOKEN,<br \/>\n  pdp: &#8220;https:\/\/cloudpdp.api.permit.io&#8221;<br \/>\n});[\/crayon]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><b>Parsing SQL++ Queries<\/b><\/h4>\n\n\n\n<p><span>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\n\n\n<p><span>Let\u2019s look at the core components of our parser:<\/span><\/p>\n\n\n\n<p><b>Query Parser<\/b><\/p>\n\n\n\n<p><span>The QueryParser class is the foundation of our security implementation. It handles two critical tasks:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><b>Query Analysis: <\/b><span>P<\/span><span>arses SQL++ queries to determine:<\/span><\/li>\n\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span>Operation type SELECT, UPDATE, DELETE, INSERT<\/span><\/li>\n\n\n<li><span>Resource being accessed<\/span><\/li>\n\n\n<li><span>Query structure validation<\/span><\/li>\n\n<\/ul>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]static parseQuery(query) {<br \/>\n\u00a0 \/\/ Extract resource from SELECT statement (word before t const<br \/>\n\u00a0 selectResourcePattern = \/SELECTs+(w+).\/i;<\/p>\n<p>\u00a0 \/\/ Basic regex patterns for SQL operations<br \/>\n\u00a0 const patterns = {<br \/>\n\u00a0 \u00a0 select: \/^s*SELECTs+(?:(?!FROM).)*s+FROMs+[`]?(<br \/>\n\u00a0 \u00a0 update: \/^s*UPDATEs+[`]?(w+)[`]?(?:.`?(w+)`?)?(<br \/>\n\u00a0 \u00a0 delete: \/^s*DELETEs+FROMs+[`]?(w+)[`]?(?:.`?(w<br \/>\n\u00a0 \u00a0 insert: \/^s*INSERTs+INTOs+[`]?(w+)[`]?(?:.`?(w<br \/>\n\u00a0 };<\/p>\n<p>\u00a0 \/\/ Determine operation type and extract resource let operation = &#8221;;<br \/>\n\u00a0 let resource = &#8221;;<br \/>\n\u00a0 if (patterns.select.test(query)) {<br \/>\n\u00a0 \u00a0 operation = &#8216;read&#8217;;<br \/>\n\u00a0 \u00a0 const resourceMatch = query.match(selectResourcePatt if (resourceMatch &amp;&amp; resourceMatch[1]) {<br \/>\n\u00a0 \u00a0 resource = resourceMatch[1];<br \/>\n\u00a0 \u00a0 \u00a0 } else {<br \/>\n\u00a0 \u00a0 throw new Error(&#8216;Unable to parse resource from S<br \/>\n\u00a0 \u00a0 }<br \/>\n\u00a0 } else if (patterns.update.test(query)) { operation = &#8216;update&#8217;;<br \/>\n\u00a0 \u00a0 const matches = query.match(patterns.update); resource = matches[3] || matches[2] || matches[1];<br \/>\n\u00a0 } else if (patterns.delete.test(query)) {<br \/>\n\u00a0 \u00a0 operation = &#8216;delete&#8217;;<br \/>\n\u00a0 \u00a0 const matches = query.match(patterns.delete); resource = matches[3] || matches[2] || matches[1];<br \/>\n\u00a0 } else if (patterns.insert.test(query)) { operation = &#8216;create&#8217;;<br \/>\n\u00a0 \u00a0 const matches = query.match(patterns.insert); resource = matches[3] || matches[2] || matches[1];<br \/>\n\u00a0 }<\/p>\n<p>\u00a0 if (!operation || !resource) {<br \/>\n\u00a0 \u00a0 throw new Error(&#8216;Unable to parse query operation or<br \/>\n\u00a0 }<\/p>\n<p>\u00a0 return {<br \/>\n\u00a0 \u00a0 query,<br \/>\n\u00a0 \u00a0 permission: operation,<br \/>\n\u00a0 \u00a0 resource: resource.toLowerCase()<br \/>\n\u00a0 };<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<p>2. <b>Security Validation<\/b><span>: Implements security checks to prevent SQL injection and other attacks:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]static validateQuery(query) {<\/p>\n<p>\u00a0 \/\/ Basic security validation<br \/>\n\u00a0 const disallowedPatterns = [<br \/>\n\u00a0   \/;.*;\/i,           \/\/ Multiple statements<br \/>\n\u00a0   \/&#8211;\/,              \/\/ SQL comments<br \/>\n\u00a0   \/\/*\/,            \/\/ Block comments<br \/>\n\u00a0   \/xp_\/i,            \/\/ Extended stored procedur<br \/>\n\u00a0   \/EXECUTEs+sp_\/i,  \/\/ Stored procedure executi<br \/>\n\u00a0   \/EXECs+sp_\/i,     \/\/ Stored procedure executi<br \/>\n\u00a0   \/INTOs+OUTFILE\/i, \/\/ File operations<br \/>\n\u00a0   \/LOAD_FILE\/i,      \/\/ File operations<br \/>\n\u00a0 ];<\/p>\n<p>\u00a0 for (const pattern of disallowedPatterns) {<br \/>\n\u00a0 \u00a0 if (pattern.test(query)) {<br \/>\n\u00a0 \u00a0 \u00a0 throw new Error(&#8216;Query contains potentially harm<br \/>\n\u00a0 \u00a0 }<br \/>\n\u00a0 }<\/p>\n<p>\u00a0 return true;<br \/>\n}[\/crayon]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><b>Permission Management<\/b><\/h4>\n\n\n\n<p><span>The <\/span><i><span>TravelQueryChecker<\/span><\/i><span> class handles the core permission logic:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><b>Initialization:<\/b><span> Sets up connections to both Permit.io and Couchbase:<\/span><\/li>\n\n<\/ol>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]class TravelQueryChecker {<br \/>\n  constructor() {<br \/>\n    this.permit = new Permit({<br \/>\n      token: process.env.PERMIT_SDK_TOKEN,<br \/>\n      pdp: &#8220;https:\/\/cloudpdp.api.permit.io&#8221;<br \/>\n    });<\/p>\n<p>    this.clusterConnStr = &#8216;couchbases:\/\/cb.6gj2r4ygxyjrfcgf<br \/>\n    this.username = &#8216;shivay1&#8217;;<br \/>\n    this.password = &#8216;Shivay1234!&#8217;;<br \/>\n    this.bucketName = &#8216;travel-sample&#8217;;<br \/>\n  }<\/p>\n<p>  async init() {<br \/>\n    try {<br \/>\n      this.cluster = await couchbase.connect(this.clusterC username: this.username,<br \/>\n        password: this.password,<br \/>\n        configProfile: &#8216;wanDevelopment&#8217;,<br \/>\n      });<\/p>\n<p>      this.bucket = this.cluster.bucket(this.bucketName);<br \/>\n      this.collection = this.bucket.defaultCollection();<br \/>\n      console.log(&#8216;Connected to Couchbase Capella&#8217;);<br \/>\n    } catch (error) {<br \/>\n      console.error(&#8216;Couchbase connection error:&#8217;, error);<br \/>\n      throw error;<br \/>\n  }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><b>Permission Checking:<\/b><span> Verifies user permissions through Permit.io:<\/span><\/li>\n\n<\/ol>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]async checkQueryPermission(userId, queryConfig) { if (!queryConfig)<br \/>\n  {<br \/>\n    return { permitted: false, error: &#8216;Invalid query con<br \/>\n  }<br \/>\n  try {<br \/>\n    const permitted = await this.permit.check(<br \/>\n      String(userId),<br \/>\n      queryConfig.permission,<br \/>\n      {<br \/>\n        type: queryConfig.resource,<br \/>\n        tenant: &#8220;default&#8221;,<br \/>\n        resource: queryConfig.resource<br \/>\n      }<br \/>\n   );<\/p>\n<p>    return {<br \/>\n      permitted,<br \/>\n      query: queryConfig.query,<br \/>\n      permission: queryConfig.permission,<br \/>\n      resource: queryConfig.resource<br \/>\n    };<br \/>\n    } catch (error) {<br \/>\n      console.error(&#8216;Permission check error:&#8217;, error);<br \/>\n      return { permitted: false, error: error.message };<br \/>\n    }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<p><span>This function uses the <\/span><a href=\"https:\/\/permit.io\/\"><span>Permit.io<\/span><\/a><span> SDK to check if a user has permission to perform a specific action on a resource.<\/span><\/p>\n\n\n\n<p>3. <b>Query Execution<\/b><span>: Handles the complete flow from permission check to query execution:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]async executeQuery(userId, rawQuery, params = [])<br \/>\n\u00a0 { try {<\/p>\n<p>\u00a0 \u00a0 \/\/Validate query for security<br \/>\n\u00a0 \u00a0 QueryParser.validateQuery(rawQuery);<\/p>\n<p>\u00a0 \u00a0 \/\/Parse the query to get permission and resource<br \/>\n\u00a0 \u00a0 const queryConfig = QueryParser.parseQuery(rawQuery)<br \/>\n\u00a0 \u00a0 console.log(&#8216;Parsed query config:&#8217;, queryConfig);<br \/>\n\u00a0 \u00a0 const permissionCheck = await this.checkQueryPermiss<\/p>\n<p>\u00a0 \u00a0 if (!permissionCheck.permitted) {<br \/>\n\u00a0 \u00a0 \u00a0 return {<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 status: &#8216;not-permitted&#8217;,<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 error: `User ${userId} is not permitted to e \u00a0<br \/>\n\u00a0 \u00a0 \u00a0 };<br \/>\n\u00a0 \u00a0 }<\/p>\n<p>\u00a0 \u00a0 const options = { parameters: params };<br \/>\n\u00a0 \u00a0 const result = await this.cluster.query(rawQuery,<br \/>\n\u00a0 \u00a0 op return {<br \/>\n\u00a0 \u00a0 \u00a0 status: &#8216;permitted&#8217;,<br \/>\n\u00a0 \u00a0 \u00a0 success: true,<br \/>\n\u00a0 \u00a0 \u00a0 results: result.rows,<br \/>\n\u00a0 \u00a0 \u00a0 metadata: {<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 metrics: result.metrics,<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 profile: result.profile<br \/>\n\u00a0 \u00a0 \u00a0 }<br \/>\n\u00a0 \u00a0 };<br \/>\n\u00a0 } catch (error) {<br \/>\n\u00a0 \u00a0 \u00a0 console.error(&#8216;Query execution error:&#8217;, error);<br \/>\n\u00a0 \u00a0 \u00a0 return {<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 status: &#8216;error&#8217;,<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 error: error.message<br \/>\n\u00a0 \u00a0 };<br \/>\n\u00a0 }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><b>API Endpoint<\/b><\/h4>\n\n\n\n<p><span>Finally, we expose an API endpoint to handle incoming queries:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]\/\/ Route to handle SQL++ queries<br \/>\napp.post(&#8216;\/query&#8217;, async (req, res) =&gt; {<br \/>\n  const { userId, query, params } = req.body;<\/p>\n<p>  if (!userId || !query) {<br \/>\n    return res.status(400).json({ error: &#8216;userId and query a<br \/>\n  }<\/p>\n<p>  try {<br \/>\n    const result = await queryChecker.executeQuery(userId, q res.json(result);<br \/>\n  } catch (error) {<br \/>\n    res.status(500).json({ error: error.message });<br \/>\n  }<br \/>\n});[\/crayon]<\/p>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><b>Couchbase Connection<\/b><\/h4>\n\n\n\n<p><span>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\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;default&#8221; decode=&#8221;true&#8221;]\/\/ Connect to Couchbase cluster<br \/>\n  async init() {<br \/>\n    try {<br \/>\n      this.cluster = await couchbase.connect(this.clusterC<br \/>\n        username: this.username,<br \/>\n        password: this.password,<br \/>\n        configProfile: &#8216;wanDevelopment&#8217;,<br \/>\n      });<\/p>\n<p>      this.bucket = this.cluster.bucket(this.bucketName);<br \/>\n      this.collection = this.bucket.defaultCollection();<br \/>\n      console.log(&#8216;Connected to Couchbase Capella&#8217;);<br \/>\n    } catch (error) {<br \/>\n      console.error(&#8216;Couchbase connection error:&#8217;, error);<br \/>\n      throw error;<br \/>\n    }<br \/>\n}[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span>Frontend Code<\/span><\/h3>\n\n\n\n<p><span>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\n\n\n<p><span>For setup, you can check this code for the existing UI components:<\/span><\/p>\n\n\n<p>[crayon nums=&#8221;false&#8221; lang=&#8221;js&#8221; decode=&#8221;true&#8221;]import React, { useState } from &#8216;react&#8217;;<br \/>\nimport { Button } from &#8220;@\/components\/ui\/button&#8221;<br \/>\nimport { Input } from &#8220;@\/components\/ui\/input&#8221;<br \/>\nimport { Textarea } from &#8220;@\/components\/ui\/textarea&#8221;<br \/>\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from &#8220;@\/components\/ui\/card&#8221;<br \/>\nexport default function App() {<br \/>\n  const [query, setQuery] = useState(&#8221;);<br \/>\n  const [user, setUser] = useState(&#8221;);<br \/>\n  const [result, setResult] = useState&lt;null | { success: boolean; results?: any[]; error?: string }&gt;(null);<\/p>\n<p>  const handleSubmit = async (e: React.FormEvent) =&gt; {<br \/>\n    e.preventDefault();<br \/>\n    try {<br \/>\n      const response = await fetch(&#8216;https:\/\/localhost:3001\/query&#8217;, {<br \/>\n        method: &#8216;POST&#8217;,<br \/>\n        headers: {<br \/>\n          &#8216;Content-Type&#8217;: &#8216;application\/json&#8217;,<br \/>\n        },<br \/>\n        body: JSON.stringify({ query, user }),<br \/>\n      });<br \/>\n      const data = await response.json();<br \/>\n      setResult(data);<br \/>\n    } catch (error) {<br \/>\n      console.error(&#8216;Error:&#8217;, error);<br \/>\n      setResult({ success: false, error: &#8216;An error occurred while processing your request.&#8217; });<br \/>\n    }<br \/>\n  };<\/p>\n<p>  return (<br \/>\n    &lt;div className=&#8221;container mx-auto p-4&#8243;&gt;<br \/>\n      &lt;Card className=&#8221;w-full max-w-2xl mx-auto&#8221;&gt;<br \/>\n        &lt;CardHeader&gt;<br \/>\n          &lt;CardTitle&gt;Permission Checker&lt;\/CardTitle&gt;<br \/>\n          &lt;CardDescription&gt;Enter a query and user to check permissions&lt;\/CardDescription&gt;<br \/>\n        &lt;\/CardHeader&gt;<br \/>\n        &lt;CardContent&gt;<br \/>\n          &lt;form onSubmit={handleSubmit} className=&#8221;space-y-4&#8243;&gt;<br \/>\n            &lt;div&gt;<br \/>\n              &lt;label htmlFor=&#8221;query&#8221; className=&#8221;block text-sm font-medium text-gray-700&#8243;&gt;Query&lt;\/label&gt;<br \/>\n              &lt;Textarea<br \/>\n                id=&#8221;query&#8221;<br \/>\n                value={query}<br \/>\n                onChange={(e) =&gt; setQuery(e.target.value)}<br \/>\n                placeholder=&#8221;Enter your SQL++ query here&#8221;<br \/>\n                className=&#8221;mt-1&#8243;<br \/>\n                rows={4}<br \/>\n              \/&gt;<br \/>\n            &lt;\/div&gt;<br \/>\n            &lt;div&gt;<br \/>\n              &lt;label htmlFor=&#8221;user&#8221; className=&#8221;block text-sm font-medium text-gray-700&#8243;&gt;User&lt;\/label&gt;<br \/>\n              &lt;Input<br \/>\n                id=&#8221;user&#8221;<br \/>\n                type=&#8221;text&#8221;<br \/>\n                value={user}<br \/>\n                onChange={(e) =&gt; setUser(e.target.value)}<br \/>\n                placeholder=&#8221;Enter user email&#8221;<br \/>\n                className=&#8221;mt-1&#8243;<br \/>\n              \/&gt;<br \/>\n            &lt;\/div&gt;<br \/>\n            &lt;Button type=&#8221;submit&#8221; className=&#8221;w-full&#8221;&gt;Check Permissions&lt;\/Button&gt;<br \/>\n          &lt;\/form&gt;<br \/>\n        &lt;\/CardContent&gt;<br \/>\n        &lt;CardFooter&gt;<br \/>\n          {result &amp;&amp; (<br \/>\n            &lt;div className={`mt-4 p-4 rounded ${result.success ? &#8216;bg-green-100&#8217; : &#8216;bg-red-100&#8217;}`}&gt;<br \/>\n              {result.success ? (<br \/>\n                &lt;div&gt;<br \/>\n                  &lt;h3 className=&#8221;font-bold text-green-800&#8243;&gt;Permission Granted&lt;\/h3&gt;<br \/>\n                  &lt;pre className=&#8221;mt-2 whitespace-pre-wrap&#8221;&gt;{JSON.stringify(result.results, null, 2)}&lt;\/pre&gt;<br \/>\n                &lt;\/div&gt;<br \/>\n              ) : (<br \/>\n                &lt;div&gt;<br \/>\n                  &lt;h3 className=&#8221;font-bold text-red-800&#8243;&gt;Permission Denied&lt;\/h3&gt;<br \/>\n                  &lt;p&gt;{result.error}&lt;\/p&gt;<br \/>\n                &lt;\/div&gt;<br \/>\n              )}<br \/>\n            &lt;\/div&gt;<br \/>\n          )}<br \/>\n        &lt;\/CardFooter&gt;<br \/>\n      &lt;\/Card&gt;<br \/>\n    &lt;\/div&gt;<br \/>\n  );<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p><span>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\n\n\n<p><span>For the complete code, check out the <\/span><a href=\"https:\/\/github.com\/Arindam200\/permit-couchbase\"><span>Permit-Demo<\/span><\/a><span> GitHub repository.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span>Demo<\/span><\/h2>\n\n\n\n<p><span>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> button.<\/span><\/p>\n\n\n\n<figure id=\"attachment_16738\" aria-describedby=\"caption-attachment-16738\" style=\"width: 900px\" 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\" class=\"wp-image-16738 size-large\" src=\"https:\/\/www.couchbase.com\/wp-content\/uploads\/sites\/5\/2026\/05\/Screenshot-2025-01-01-at-10.55.49-PM-1024x607-1.png\" alt=\"\" width=\"900\" height=\"533\"><\/a><figcaption id=\"caption-attachment-16738\" class=\"wp-caption-text\">Click on image to launch demo video<\/figcaption><\/figure>\n\n\n\n<p><span>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\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p><span>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\n\n\n<p><span>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>and <\/span><a href=\"https:\/\/www.permit.io\/abac\"><b>adding ABAC to your application with Permit<\/b><\/a><span>.<\/span><\/p>\n\n\n\n<p><span>Want to learn more about implementing authorization? Got questions? Reach out\u00a0<\/span><span>to us in our <\/span><a href=\"https:\/\/io.permit.io\/permitslack\"><b>Slack community<\/b><\/a><span>.<\/span><\/p>\n\n\n\n<p>\u00a0<\/p>\n\n\n\n<p>\u00a0<\/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 provides a robust solution for managing access control in applications leveraging Couchbase as the database. [&hellip;]<\/p>\n","protected":false},"author":85559,"featured_media":4424,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_acf":"","footnotes":""},"categories":[136,199,178,301,516,94],"tags":[934,261,440],"ppma_author":[935],"class_list":["post-4427","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.6 (Yoast SEO v27.6) - 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\/es\/permit-io-couchbase-access-control\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/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\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\"},\"wordCount\":2597,\"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\\\/5\\\/2026\\\/05\\\/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\":\"es\",\"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\\\/5\\\/2026\\\/05\\\/blog-permitio-rbac-couchbase.png\",\"datePublished\":\"2025-01-02T06:07:24+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\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/permit-io-couchbase-access-control\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/blog-permitio-rbac-couchbase.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"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\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=ge6192df7fcab3a423d4c8f6e1c30858f\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=g\",\"caption\":\"Shivay Lamba, Developer Evangelist\"},\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/es\\\/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":"Discover how to secure Couchbase data with Permit.io and implement fine-grained role-based access control (RBAC) for your applications.","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\/es\/permit-io-couchbase-access-control\/","og_locale":"es_MX","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\/es\/permit-io-couchbase-access-control\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-01-02T06:07:24+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/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","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"},"wordCount":2597,"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\/5\/2026\/05\/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":"es","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\/5\/2026\/05\/blog-permitio-rbac-couchbase.png","datePublished":"2025-01-02T06:07:24+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":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/permit-io-couchbase-access-control\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/blog-permitio-rbac-couchbase.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","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":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=ge6192df7fcab3a423d4c8f6e1c30858f","url":"https:\/\/secure.gravatar.com\/avatar\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c3c8ba40dfa67893e20e70fb9d37a9dc978cbbeb10e5d0418e70af1f672d200b?s=96&d=mm&r=g","caption":"Shivay Lamba, Developer Evangelist"},"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/shivaylambda\/"}]}},"acf":[],"authors":[{"term_id":935,"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\/5\/2026\/05\/shivay-lambda-couchbase-16.jpeg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/shivay-lambda-couchbase-16.jpeg"},"author_category":"1","first_name":"Shivay","last_name":"Lamba - Developer Evangelist","user_url":"","job_title":"","description":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/85559"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=4427"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/4427\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/4424"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=4427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=4427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=4427"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=4427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}