Authentication

RBAC requires that users pass appropriate credentials to Couchbase Server in order to access cluster-resources. The SDK provides enhanced support for the passing of credentials.

RBAC and the SDK

Couchbase Server 5.0 Enterprise Edition introduces Role-Based Access Control. This ensures that cluster-resources can only be accessed by users with appropriate privileges. Privileges are grouped in Couchbase-defined sets; and each set is associated with a specific role. Users can each be assigned one or more roles, and are thereby granted the privileges associated with each role.

In order to access cluster-resources, programs, including those supported by the Couchbase SDK, must authenticate with Couchbase Server, and so be identified as existing users, each associated with one or more roles. Authentication requires the passing of credentials; which consist of a username and (in most cases) a password. Users may be defined either locally to Couchbase Server, or externally (for example, by means of an LDAP server).

Once authentication has succeeded, an authorization process checks the roles associated with the identified user. If role-associated privileges correspond to the level of resource-access requested by the user, access is duly granted; otherwise, it is denied.

Authenticating with Legacy SDK Versions

For versions of Couchbase Server 5.0 and beyond, Role-Based Access Control (RBAC) is applied to all cluster-resources. Under RBAC, bucket-passwords are no longer used: instead, a username and user-password must be specified.

All pre-RBAC versions of the SDK can continue to be used with Couchbase Server 5.0 and beyond: the pre-RBAC authentication procedure need not change. However, when passed:

  • The value formerly interpreted as a bucket-name is now interpreted as a username. The username must correspond to a user defined on the cluster that is being accessed.

  • The value formerly interpreted as a bucket-password is now interpreted as the password of the defined user.

Note that on Couchbase Server 5.0 and beyond, the only buckets that can be accessed without a user-password are those that were created on legacy versions of the server; were not originally created with a bucket-password; and continue to be available on 5.0 and beyond, following the required upgrade process. See Upgrading to RBAC for information on server-upgrade to 5.0, and how this affects access to legacy buckets.

On Couchbase Server 5.0 and beyond, for any bucket to be accessed successfully, the defined user attempting access must have been assigned appropriate roles. See Manage Users and Roles for information on user-management.

Legacy Connection Code

These code snippets will enable you to use older, non-RBAC SDK clients with Couchbase Server 5.0 (and beyond).

Upgraded Couchbase Server 5.0 with passwordless buckets set up in an older version of Couchabse Server

If a cluster with passwordless buckets is upgraded to Couchbase Server 5.0, the corresponding RBAC user entries are generated with username equal to the bucket name and with role set to "Full Bucket Access". This process enables older SDK versions to access the buckets without creating the "Authentication Object". The following snippet for a Java SDK with version < 2.4.4 will successfully return the bucket object as there is a user which has the username "beer-sample" (the same as the bucket name).

Cluster cluster = CouchbaseCluster.create(<hostname>);
Bucket bucket = cluster.openBucket("beer-sample");
Connecting to buckets created in Couchbase Server 5.0 from pre-RBAC SDK Verison

To connect to buckets created in Couchbase Server 5.0 itself, using older client versions, you need to manually create a user with username equal the bucket name, and with role set to "Bucket Full Access". The client can then connect to the bucket using the following sample snippet:

Cluster cluster = CouchbaseCluster.create(<hostname>);
Bucket bucket = cluster.openBucket(<bucket-name>, <password for the newly created user>);

Passing Credentials

The most recent versions of the SDK are RBAC-enabled, and provide enhanced support for authentication. Code examples for Java can be found in Getting Started with the SDK, and also as part of the Sample Code provided to demonstrate user management.

Upgrading to RBAC-Enabled SDK-Versions

The last pre-RBAC version of the Java SDK was 2.4.3. The first RBAC-enabled version was 2.4.4. See the SDK Release Notes for more information.

With the most recent versions of the SDK, the legacy authentication interface and the new, optimized authentication interface can both be used: each supports access to buckets on Couchbase Servers whose version is either 5.0 and beyond, or pre-5.0.

Further Information on RBAC

All aspects of the Couchbase RBAC system are covered in the section Authorization. Specifically, for information on:

Certificate-Based Authentication

Couchbase Server supports the use of X.509 certificates to authenticate clients (only available in the Enterprise Edition, not the Community Edition). This allows authenticated users to access specific resources by means of the data service, in Couchbase Server 5.1 and up, and all other services in more recent releases of Couchbase Data Platform.

The process relies on a certificate authority, for the issuing of certificates that validate identities. A certificate includes information such as the name of the entity it identifies, an expiration date, the name of the authority that issued the certificate, and the digital signature of the authority. A client attempting to access Couchbase Server can present a certificate to the server, allowing the server to check the validity of the certificate. If the certificate is valid, the user under whose identity the client is running, and the roles assigned that user, are verified. If the assigned roles are appropriate for the level of access requested to the specified resource, access is granted.

Note that this means that the explicit authentication process otherwise required by Couchbase Role-Based Access Control — whereby, in Java, username and password are passed by means of the authenticate method on the Cluster object — must not be used (instead the CertAuthenticator is passed in). (See Start Using the SDK for an example of such standard authentication.)

For a more detailed conceptual description of using certificates, see Certificates.

For sample procedures whereby certificates can be generated and deployed, see Manage Certificates. Note that this section includes the steps whereby a Java keystore is created, to enable certificate-based authentication by a Java client.

Authenticating a Java Client by Certificate

To authenticate with Couchbase Server by means of a client certificate, a Java application must have access to an appropriate keystore or truststore. A procedure for the creation of such a keystore is provided in Manage Certificates. The following Java code assumes that this procedure has been followed. The procedure’s resulting keystore assigns the travel-sample user-identity to the client. The Couchbase Server-node that is accessed is expected to feature a user-definition where the username is indeed travel-sample, and where the Bucket Full Access role has been granted to that user for the travel-sample bucket.

package certificatetest.java;

import com.couchbase.client.java.Bucket;
import com.couchbase.client.java.Cluster;
import com.couchbase.client.java.CouchbaseCluster;
import com.couchbase.client.java.auth.CertAuthenticator;
import com.couchbase.client.java.document.JsonDocument;
import com.couchbase.client.java.env.CouchbaseEnvironment;
import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;

public class CertificateTest {

    public static void main(String... args) {

        CouchbaseEnvironment env = DefaultCouchbaseEnvironment
            .builder()
            .sslEnabled(true)
            .sslKeystoreFile("/user/ubuntu/my.keystore")
            .sslKeystorePassword("storepass")
            .certAuthEnabled(true)
            .build();

        Cluster userCluster = CouchbaseCluster.create(env, "10.143.173.101");
        userCluster.authenticate(CertAuthenticator.INSTANCE);
        Bucket travelSample = userCluster.openBucket("travel-sample");

        JsonDocument returnedAirline10doc = travelSample.get("airline_10");
        System.out.println("Found: " + returnedAirline10doc);
    }

}

As this example shows, certificate-based authentication is enabled by means of the CouchbaseEnvironment class as well as passing in the CertAuthenticator. (See Client Settings for details). The certificate-related options are as follows:

  • .sslEnabled: Enables use of Secure Sockets: the default value is true.

  • .sslKeystoreFile: Specifies the local pathname of the keystore to be used by the Java client in authentication: the default value is null. (Alternatively, the keystore can be specified as a Java object, in which case the default value is none.)

  • .sslKeystorePassword: Specifies the password of the keystore. The default value is null.

  • .certAuthEnabled: Enables the server’s authentication of the client by means of the certificates within the client’s keystore. Can only be used in combination with .sslEnabled and related methods. The default is false.

The username travel-sample is specified within the keystore: therefore, neither the username or associated password need be explicitly passed in the Java code (only the bucket-name, travel-sample is specified, in order to open the bucket).

A formatted version of the program-output is as follows:

Found: JsonDocument
{
    id='airline_10',
    cas=1506602602177888256,
    expiry=0,
    content={
        "country":"United States",
        "iata":"Q5",
        "callsign":"MILE-AIR",
        "name":"40-Mile Air","icao":"MLA",
        "id":10,
        "type":"airline"},
    mutationToken=null
}