Extended Attributes (XATTRs)
- Capella Operational
Use Extended Attributes (XATTRs) to manage access control in App Services.
Understanding Access Grant Properties
To manage access control in App Services, you can use:
- The Document Body
-
You can embed channels and roles directly within the document’s content. This method allows the document itself to govern access and routing.
- Extended Attributes (XATTRs)
-
You can store channels and roles as user extended attributes (XATTRs). This is a more secure alternative that uses metadata, outside of the document content, to grant access.
Advantages of Using XATTRs
Use XATTRs as a secure repository for data to drive document routing and access control. Some benefits of using XATTRs include:
- Enhanced Security with Metadata Isolation
-
Since XATTRs are metadata and not part of the document’s main content, they are inaccessible to users. This prevents users from identifying the channels and roles a document is associated with by reading its content.
- Separation of Concerns with Access Grant Independence
-
Storing access grants as XATTRs means that changes to this metadata do not affect the document’s revision history. Modifications to access grants do not result in new document revisions being pushed to clients. This maintains a separation between document content and access control metadata.
Configure an XATTR Property
You can enable and define XATTR properties through your endpoint settings in the Capella UI.
To configure your XATTR property:
-
Navigate to the App Endpoint Settings.
-
Click the checkbox to enable using XATTRs for storing access grants.
-
Define the XATTR property name as a string value.
This property name will be used to associate access grant metadata with your documents.
Setting XATTR Property Values
Assign values to your XATTR property, with the Couchbase SDKs.
-
SDK API: The Couchbase Server SDK API provides the necessary functions to set XATTR values.
You can’t set XATTR values using the APP Services REST API. |
This example shows how XATTR values can be set and maintained using the Couchbase Server .Net SDK.
using System;
using System.Threading.Tasks;
using Couchbase;
using Couchbase.KeyValue;
namespace examples
{
class Program
{
static async Task Main(string[] args)
{
// Set scope - cluster, bucket and collection
var cluster =
await Cluster.ConnectAsync(
"couchbase://localhost",
"Administrator",
"password");
var bucket = await cluster.BucketAsync("travel-sample");
var collection = bucket.DefaultCollection();
// Set required user_xattr_key name and value
var our_user_xattr_key_name = "channelXattr";
String[] channelXattrValue =
{"channel1","channel3", "useradmin" };
var ourDocumentType = "hotel";
var documentKey = "";
// Find our documents and get their ids
var queryResult =
await cluster.QueryAsync<dynamic>(
"select meta().id from `travel-sample`.`_default`.`_default` h where h.type = $1",
new Couchbase.Query.QueryOptions().Parameter(ourDocumentType));
await foreach (var row in queryResult)
{
documentKey = row.id;
Console.WriteLine("Working with document id: {0} ",
documentKey);
// Check if the document has an existing
// user_xattr_key and update or insert new value
var result =
await collection.LookupInAsync(
documentKey,
specs => specs.Exists(
path: our_user_xattr_key_name,
isXattr: true)
);
if (result.Exists(0))
{
// Update xattr for retrieved Id
await collection.MutateInAsync(
documentKey,
specs => specs.Upsert(
path: our_user_xattr_key_name,
value: channelXattrValue,
isXattr: true));
Console.Write("Updated Existing user_xattr_key: {0} to this value: {1}\n",
our_user_xattr_key_name,
string.Join(", ", channelXattrValue));
}
else
{
// Insert xattr for retrieved id
await collection.MutateInAsync(
documentKey,
specs => specs.Insert(
path: our_user_xattr_key_name,
value: channelXattrValue,
isXattr: true));
Console.Write("Inserted New user_xattr_key: {0} with value {1}\n",
our_user_xattr_key_name,
string.Join(", ", channelXattrValue));
}
}
Console.WriteLine("Completed Changes\n");
}
}
}
-
Couchbase.KeyValue provides access to the
MutateInSpec
class.-
The
MutateInSpec
class provides access to sub-documents, of which metadata is a special class.
-
-
You can store the name of your XATTR in a
String
such asour_user_xattr_key_name
.-
You can store channels you want to include as the XATTR value via a
String Array
as shown inchannelXattrValue
.
-
-
You can then get all documents that you want to set the XATTR on (type = 'hotel' in this instance).
It is best practice to check if the XATTR has been defined before performing operations on it. |
-
Once the documents have been retrieved, you can perform operations on them asynchronously.
-
If an XATTR exists, you can update the XATTR, specifying the item to update.
-
You can set the XATTR value required.
-
You can specify the item is an XATTR.
-
-
If no XATTR exists in target documents (
hotel
), you can insert an XATTR, specifying the item to add (channelXattr
).-
You can set the required value using
channelXattrValue
. -
You can then specify the item is an XATTR.
-
Running the code produces the following output:
Working with document id: 1000
Updated Existing user_xattr_key:
channelXattr to this value: channel1, channel3, useradmin
Working with document id: 1001
Inserted New user_xattr_key:
channelXattr with this value: channel1, channel3, useradmin
Completed Changes
Using Your XATTRs
You can use your user defined XATTRs within the Access Control and Data Validation function to set access grants.
In the following example Access Control and Data Validation function, the XATTRs defines channel settings. The provided Javascript function executes every time a new revision or update is made to a document.
The function shown performs validation for an existing user defined XATTR or creates one suitable for your needs.
function (doc, oldDoc, meta) {
if (meta.xattrs.channelXattr === undefined)
{
console.log("no user_xattr_key defined")
channel(null)
} else {
channel(meta.xattrs.channelXattr)
}
}
The meta parameter exposes the user defined user_xattr_key if defined and uses the content of the XATTR to define the channels
setting for the document.
You can navigate to the Access Control and Data Validation Function with the Capella UI:
-
From the App Services screen, go to App Endpoints.
Figure 1. Select App Endpoint -
Go to
.Figure 2. Updating the Access Control and Data Validation FunctionThe Capella UI checks that the JavaScript function is valid when you click Apply. You can restore the function to its original default by clicking Restore to Default. The default function performs no validation.