How-to Guide: Couchbase User RBAC

    +
    A how-to guide on configuring Couchbase user authentication and authorization using the Autonomous Operator.

    Overview

    This guide will describe how to create authenticated users and bind them to specific roles to provide multiple levels of authorization using the Autonomous Operator. Users can be authenticated either by Couchbase’s built-in authentication system or by an external authentication system such as OpenLDAP.

    The Autonomous Operator refers to Couchbase Authentication as the local domain, and LDAP Authentication as the external domain. This guide will focus on using the local domain for authentication.

    Prerequisites

    • If you are new to role-based access control in Couchbase, refer to the Roles Page

    • If you are new to Couchbase Autonomous Operator (CAO), refer to the Autonomous Operator Introduction

    • Couchbase Scopes and Collections was added in Version 7.0. Refer to the Couchbase Scopes and Collections page to learn more about these.

    • Some of the examples in this guide use the cbc CLI tool, see the installation page here for more details.

    Setup a bucket called Travel, a scope called Inventory, and two collections called Transport and Hotel. See Manage Scopes and Collections for more information on how to do this.

    We’ll create two users named Alice and Bob in the next steps, but we won’t assign any roles to them just yet. As we progress through this guide, we’ll assign roles based on scenarios.

    Create Users

    In order to create a user, we need to create a password first, in the form of a Kubernetes secret.

    The local Couchbase domain performs internal password management and requires a password to be provided during user creation.

    The below command creates the password for users "Alice" and "Bob":

    cat << EOF | kubectl create -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: alice-password
    type: Opaque
    data:
      password: cGFzc3dvcmQ=   # password
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: bob-password
    type: Opaque
    data:
      password: cGFzc3dvcmQ=   # password
    EOF

    Using the above secrets, we are going to create the users.

    cat << EOF | kubectl apply -f -
    apiVersion: couchbase.com/v2
    kind: CouchbaseUser
    metadata:
      name: alice
    spec:
      fullName: "Alice"
      authDomain: local
      authSecret: alice-password (1)
    ---
    apiVersion: couchbase.com/v2
    kind: CouchbaseUser
    metadata:
      name: bob
    spec:
      fullName: "Bob"
      authDomain: local
      authSecret: bob-password (2)
    EOF
    1 Password for Alice
    2 Password for Bob

    Create Groups and RoleBindings

    Now that we’ve created the users, we can bind them with groups. In order to do that, we are going to create groups and bind them with the users using role bindings.

    Copy the below command to create a group and role binding for user "Alice":

    cat << EOF | kubectl apply -f -
    apiVersion: couchbase.com/v2
    kind: CouchbaseGroup
    metadata:
      name: group-for-alice
    spec:
      roles: []
    ---
    apiVersion: couchbase.com/v2
    kind: CouchbaseRoleBinding
    metadata:
      name: role-binding-for-alice (1)
    spec:
      subjects:
      - kind: CouchbaseUser
        name: alice
      roleRef:
        kind: CouchbaseGroup
        name: group-for-alice
    EOF
    1 The new role binding, with name role-binding-for-alice, binds the new user (alice) with the new group (group-for-alice).

    In the above groups we have not assigned any roles to them. We’ll do it in the next section.

    Scenarios

    Single Scope and Collection

    As you may know, buckets contain scopes, and scopes have collections. We’ll use one scope and one collection for this scenario — named Inventory and Transport, respectively.

    Alice is the Transport collection’s Data Writer, and Bob is the Transport collection’s Data Reader. This means that Alice can write but not read data in the Transport collection, and Bob can read but not write data in the same.

    rbac single scope coll

    Updating Roles

    In order to give access to Alice and Bob, we need to update the groups created for them in the previous section.

    Copy the below command to update the groups with appropriate roles.

    cat << EOF | kubectl apply -f -
    apiVersion: couchbase.com/v2
    kind: CouchbaseGroup
    metadata:
      name: group-for-alice
    spec:
      roles: (1)
      - name: data_writer
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: transport
    ---
    apiVersion: couchbase.com/v2
    kind: CouchbaseGroup
    metadata:
      name: group-for-bob
    spec:
      roles: (2)
      - name: data_reader
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: transport
    EOF
    1 The couchbase roles that we want to assign to Alice.
    2 The couchbase roles that we want to assign to Bob.

    Once the roles are configured, users will have the appropriate permissions, which can be verified in the Couchbase UI.

    rbac users single scope coll

    Verification

    Using the data_writer and data_reader roles, we cannot use the UI to login.

    To verify that the users are assigned the desired roles, use the cbc CLI or one of the SDK Clients.

    Let’s try with user Alice first, and use the cbc CLI tool to create a document in Couchbase.

    cbc create -u alice -P password mydoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                Stored. CAS=0x16d48f429afe0000
                         SYNCTOKEN=948,114825287260906,3

    We can see from the above example that Alice was able to write the data. Let’s see whether Alice can read the data or not.

    cbc get mydoc -u alice -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                LCB_ERR_AUTHENTICATION_FAILURE (206)
                         Ref:                      Context:

    We can observe that Alice was unable to read data, and an authentication failure error was returned.

    Now, let’s try the same thing with Bob.

    cbc create -u bob -P password mydoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                LCB_ERR_AUTHENTICATION_FAILURE (206)
    
                         Ref:

    We can see that Bob was unable to write the data and received an authentication failure error in this example. Let’s see whether Bob can read the data or not.

    cbc get mydoc -u bob -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                 CAS=0x16d48f429afe0000, Flags=0x0, Size=15, Datatype=0x01(JSON)
    {"key":"value"}

    Bob was able to read the data, as can be seen from the above example.

    This confirms that Alice can only write data to the Transport collection and Bob can only read data from it.

    Single Scope and Multiple Collections

    In this scenario, we’ll use one scope named Inventory and two collections named Transport and Hotel.

    Alice is the Transport collection’s Data Writer and Hotel collection’s Data Reader. Bob is the Transport collection’s Data Reader and Hotel collection’s Data Writer.

    This means that Alice can write in the Transport collection and read data from the Hotel collection, and Bob can read data from the Transport collection and write data in the Hotel collection.

    rbac single scope multiple coll

    Updating Roles

    In order to give access to Alice and Bob, we need to update the groups created for them in the previous section.

    Copy the below command to update the groups with appropriate roles.

    cat << EOF | kubectl apply -f -
    apiVersion: couchbase.com/v2
    kind: CouchbaseGroup
    metadata:
      name: group-for-alice
    spec:
      roles: (1)
      - name: data_writer
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: transport
      - name: data_reader
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: hotel
    ---
    apiVersion: couchbase.com/v2
    kind: CouchbaseGroup
    metadata:
      name: group-for-bob
    spec:
      roles: (2)
      - name: data_reader
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: transport
      - name: data_writer
        bucket: travel
        scopes:
          resources:
          - name: inventory
        collections:
          resources:
          - name: hotel
    EOF
    1 The couchbase roles that we want to assign to Alice.
    2 The couchbase roles that we want to assign to Bob.

    Once the roles are configured, users will have the appropriate permissions and it can be verified in Couchbase UI, as demonstrated in the image below.

    rbac users single scope multiple coll

    Verification

    Now, we can verify that the users are assigned the desired roles for both collections.

    • Transport Collection

    • Hotel Collection

    Let’s try with user Alice first, and use the cbc CLI tool to create a document in Couchbase.

    cbc create -u alice -P password mydoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                Stored. CAS=0x16d48f429afe0000
                         SYNCTOKEN=948,114825287260906,3

    We can see from the above example that Alice was able to write the data. Let’s see whether Alice can read the data or not.

    cbc get mydoc -u alice -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                LCB_ERR_AUTHENTICATION_FAILURE (206)
                         Ref:                      Context:

    We can observe that Alice was unable to read data, and an authentication failure error was returned.

    Now, let’s try the same thing with Bob.

    cbc create -u bob -P password mydoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                LCB_ERR_AUTHENTICATION_FAILURE (206)
                         Ref:

    We can see that Bob was unable to write the data and received an authentication failure error in this example. Let’s see whether Bob can read the data or not.

    cbc get mydoc -u bob -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Transport
    Result
    mydoc                 CAS=0x16d48f429afe0000, Flags=0x0, Size=15, Datatype=0x01(JSON)
    {"key":"value"}

    Bob was able to read the data, as can be seen from the above example.

    Let’s try with user Bob first, and use the cbc CLI tool to create a document in Couchbase.

    cbc create -u bob -P password bobdoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Hotel
    Result
    bobdoc               Stored. CAS=0x16d4905332b90000
                         SYNCTOKEN=947,114707412110497,4

    We can see from the above example that Bob was able to write the data. Let’s see whether Bob can read the data or not.

    cbc get bobdoc -u bob -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Hotel
    Result
    bobdoc               LCB_ERR_AUTHENTICATION_FAILURE (206)
                         Ref:                      Context:

    We can observe that Bob was unable to read data, and an authentication failure error was returned. Now, let’s try the same thing with Alice.

    cbc create -u alice -P password alicedoc -V '{"key":"value"}' -M upsert -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Hotel
    Result
    alicedoc             LCB_ERR_AUTHENTICATION_FAILURE (206)
    
                         Ref:

    We can see that Alice was unable to write the data and received an authentication failure error in this example. Let’s see whether Alice can read the data or not.

    cbc get bobdoc -u alice -P password -U couchbase://cb-example/travel \
    --scope Inventory \
    --collection Hotel
    Result
    bobdoc               CAS=0x16d4905332b90000, Flags=0x0, Size=15, Datatype=0x01(JSON)
    {"key":"value"}

    Alice was able to read the data, as can be seen from the above example.

    This confirms that Alice can write data to the Transport collection and read data from the Hotel collection. Bob can write data to the Hotel collection and read data from the Transport collection.