User Authentication and Authorization

NuoDB supports role-based access control (RBAC) of NuoDB Admin functionality. NuoDB Admin exposes functionality via a REST API, which the NuoDB Command client tool uses. Authentication of the user issuing a REST API request is performed using one of two methods; X509 certificate-based authentication and password-based authentication. As is typical of RBAC systems, authorization to issue a REST API request is granted to a user based on the roles assigned to that user.

User and Role Management

Prior to version 4.1, there was no explicit concept of users. A management client (e.g. nuocmd) could invoke any NuoDB Admin functionality as long as it could authenticate itself (using an X509 certificate) to the NuoDB Admin process (AP) servicing its request.

Starting with version 4.1, users can be created and explicitly have access privileges granted to them. A user has a name, a set of roles, and authentication information associated with it. The supported authentication methods are X509 certificate-based authentication (i.e. mutual TLS authentication; see RFC 5246) and password-based authentication (i.e. HTTP Basic Authentication; see RFC 7617). A role has a name, a set of sub-roles, and a set of specifications for requests that users with that role are authorized to issue (authorized request specifications).

When a user issues a REST API request, its roles (and any roles it assumes as sub-roles) are checked for an authorized request specification that matches the request being serviced. If there is one, the request is serviced, otherwise the request is rejected.

Enabling User and Role Management

To enable user and role management, the nuoadmin.conf property domainUser must be set to a non-empty value. This value should be the Common Name of the X509 certificate in the truststore of APs that belongs to the domain user, which is the first user in the system and is authorized to invoke any NuoDB Admin functionality. The domainUser property must be set to the same value on all APs in the domain.

The nuoadmin.conf setting requireLocalDomainUser=true is used to prevent remote access for clients using the domain user certificate.

The examples below assume that the environment variable NUOCMD_CLIENT_KEY is set to the PEM file associated with the domain user. This sets the default value of --client-key for nuocmd invocations. The examples below also assume that an AP is running on the same host that the nuocmd commands are being invoked on.

To determine whether user and role management is enabled on an AP, the following command can be run:

$ nuocmd get server-config --server-id <the server ID> | grep domainUser
   domainUser = nuocmd.nuodb.com

In the example above, it is assumed that the domain user is the one that has the certificate with CN=nuocmd.nuodb.com. All of the certificates that are trusted by APs can be obtained by using the following command:

$ nuocmd --show-json get certificate-info
{
  ...
  "trustedCertificates": {
    "ca": {
      "caPathLength": 2147483647,
      "certificatePem": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
      "expires": 4719260648000,
      "expiresTimestamp": "2119-07-20T01:44:08.000+0000",
      "issuerName": "CN=ca.nuodb.com, OU=Eng, O=NuoDB, L=Boston, ST=MA, C=US",
      "subjectName": "CN=ca.nuodb.com, OU=Eng, O=NuoDB, L=Boston, ST=MA, C=US"
    },
    "nuocmd": {
      "caPathLength": -1,
      "certificatePem": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
      "expires": 4719260651000,
      "expiresTimestamp": "2119-07-20T01:44:11.000+0000",
      "issuerName": "CN=nuocmd.nuodb.com, OU=Eng, O=NuoDB, L=Boston, ST=MA, C=US",
      "subjectName": "CN=nuocmd.nuodb.com, OU=Eng, O=NuoDB, L=Boston, ST=MA, C=US"
    }
  }
}

Creating a Simple Role

As the domain user, a simple role can be created using the nuocmd command-line tool as follows:

nuocmd create role --name unrestricted --any-method --url '*'

This role is authorized for requests with any HTTP method and any URL. Role management is explored in more detail in a later section.

Creating Users with Certificate-based Authentication

As the domain user, an ordinary user can be created using the nuocmd command-line tool as follows:

nuocmd create user --name certuser --cert /etc/nuodb/keys/certuser.pem --roles unrestricted

The command above creates a user with certificate authentication. If the file specified with --cert does not exist, a PEM-encoded key and self-signed X509 certificate is generated and stored there. If the file specified with --cert does exist, it must be a self-signed certificate with a subject name that has attribute CN (Common Name) identical to the user name.

The command above also adds the certificate of the new user to the truststore of all APs in the domain, before finally creating the user. When an AP services a REST request that is authenticated with a client certificate, the user name is derived from the CN attribute of the certificate’s subject name.

To verify that the command above was successful, the truststore can be checked for the presence of the user certificate, and the user can be listed as follows:

$ nuocmd --show-json get certificate-info
{
  ...
  "trustedCertificates": {
    ...
    "user.certuser": {
      "caPathLength": -1,
      "certificatePem": "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
      "expires": 1608918881000,
      "expiresTimestamp": "2020-12-25T17:54:41.000+0000",
      "issuerName": "CN=certuser",
      "subjectName": "CN=certuser"
    }
  }
}

$ nuocmd get users
User(name=certuser, roles=[unrestricted])

Finally, to issue commands as the new user, the PEM file associated with the user can be explicitly specified:

nuocmd --client-key /etc/nuodb/keys/certuser.pem show domain
An error is not generated if a nonexistent role is specified for a user or as a sub-role of another role. A nonexistent role is equivalent to a role with no privileges.

Creating Users with Password-based Authentication

A user with password-based authentication can be created as follows:

nuocmd create user --name pwuser --password <secret> --roles pwrole

To issue commands as a password-authenticated user, the username and password must be specified using --basic-creds as follows:

nuocmd --basic-creds pwuser:<secret> show domain

Alternatively, the username and password of a password-authenticated user can be specified using the NUOCMD_BASIC_CREDS environment variable.

APs use the Argon2 password hashing algorithm to securely store salted hashes of user passwords needed for verification.

The user’s password hash is cached in memory on successful authentication to avoid calculating it on every REST API call made by this user. The cache has a time-based eviction policy which is controlled by the authCacheTimeoutMillis setting (by default 60 seconds) which can be configured in nuoadmin.conf. This optimization reduces any performance penalties and delays on password verification caused by the strong password hashing algorithms.

To prevent potential denial of service (DoS) attacks causing high CPU and memory usage in case malicious users send a high rate of REST API requests with a wrong password, an authentication failure threshold is available. Any requests originated by clients with a remote IP address for which authentication or authorization failures above the configured threshold rate have been registered will be throttled. The failure threshold rate is controlled by the allowedClientAuthFailuresPerSecond setting (by default 5.0) which can be configured in nuoadmin.conf.

Managing Users

Existing users can be updated to change authentication information, including changing the certificate for a user, changing the password for the user, or changing from certificate authentication to password authentication or vice-versa, by using the nuocmd update user-credentials subcommand:

nuocmd update user-credentials --name certuser --cert /etc/nuodb/keys/certuser_prime.pem

Existing users can have the set of roles assigned to them updated by using the nuocmd update user-roles subcommand:

nuocmd update user-roles --name certuser --roles-to-remove unrestricted --roles-to-add some_new_role

Finally, existing users can be deleted by using the nuocmd delete user subcommand:

nuocmd delete user --name certuser

Specifying Privileges

As mentioned earlier, users are assigned roles, which are granted privileges by specifying requests that they are authorized for and by specifying sub-roles, whose privileges they inherit. An authorized request specification has the following form:

{
  "method": ...,
  "url": ...,
  "pathParamConstraints": {
   ...
  },
  "queryParamConstraints": {
   ...
  },
  "payloadParamConstraints": {
   ...
  }
}

The method field specifies the HTTP request method, which is one of PUT, GET, POST, DELETE (these are the HTTP request methods used by the NuoAdmin REST API and not an exhaustive list of HTTP request methods), and *, which means that this request specification applies to any request method.

The url field specifies URL that this request specification applies to, which can include the wildcard character, *. The url field should not include base of the URL, i.e. the hostname and port, since that varies by AP, but request specification should apply to all APs. For example, the URL associated with database configuration operations can be specified as follows:

  "url": "/api/1/databases/*",

The pathParamConstraints, queryParamConstraints, and payloadParamConstraints fields specify constraints on request parameters as mappings of field name to required value. pathParamConstraints specify constraints on parameters that are part of the URL of a request, queryParamConstraints specify constraints on query parameters, and payloadParamConstraints specify constraints on the request body, which is encoded as JSON in the NuoAdmin REST API.

To specify a constraint on a sub-field nested within the request payload, the path to the sub-field can be specified using . as a delimiter. For example, to constrain a hot-copy request so that it has the form shown below, the following payload constraints can be specified:

  "payloadParamConstraints": {
   "backupSetDirs.0": "/var/opt/nuodb/backup/db"
  }
{
  ...
  "backupSetDirs": {
    0: "/var/opt/nuodb/backup/db",
  ...
  }
 ...
}
If an authorized request specification contains more than one of pathParamConstraints, queryParamConstraints, and payloadParamConstraints, then it is only applicable to requests that satisfy all of the constraints. In other words, parameter constraints are combined by using the AND operation.

Creating and Managing Roles

The nuocmd command-line tool can be used to create roles, to update the set of privileges granted to roles, and to delete roles. The nuocmd create role subcommand can be used to specify a set of sub-roles and to define the first authorized request specification for that role:

nuocmd create role --name <role name>
    --sub-roles <sub-role name> ...
    --method <request method> --url <url>
    --path-param-constraints <key> <value> ...
    --query-param-constraints <key> <value> ...
    --payload-param-constraints <key> <value> ...

The --method, --url, --path-param-constraints, --query-param-constraints, and --payload-param-constraints correspond to the fields of the authorized request specification described in the previous section. A role may have several authorized request specifications, not just one. To grant more privileges to an existing role, the nuocmd add role-privileges subcommand can be used, which takes the same arguments as nuocmd create role:

nuocmd add role-privileges --name <role name>
    --sub-roles <sub-role name> ...
    --method <request method> --url <url>
    --path-param-constraints <key> <value> ...
    --query-param-constraints <key> <value> ...
    --payload-param-constraints <key> <value> ...

To remove privileges from an existing role, the nuocmd remove role-privileges subcommand can be used, which takes the same arguments as nuocmd create role and nuocmd add role-privileges:

nuocmd remove role-privileges --name <role name>
    --sub-roles <sub-role name> ...
    --method <request method> --url <url>
    --path-param-constraints <key> <value> ...
    --query-param-constraints <key> <value> ...
    --payload-param-constraints <key> <value> ...

nuocmd remove role-privileges removes any specified sub-roles from the specified role, and the authorized request specification generated by the command.

An authorized request specification is only removed from a role if it is an exact match to the one generated by nuocmd remove role-privileges. A request specification is not removed because a more general one is specified with nuocmd remove role-privileges. For example, nuocmd remove role-privileges ... --any-method --url '*' would only remove the specification added by nuocmd add role-privileges ... --any-method --url '*'.

Using Role Templates

Since the NuoDB Admin REST API is not exposed directly to users of the nuocmd command-line tool, it is not clear which request methods and URLs a user needs to be authorized for in order to invoke a particular command. For this reason, nuocmd add role-templates allows predefined sets of related privileges to be granted to a role.

  • nuocmd add role-templates ... --accessor authorizes a role for nuocmd get and nuocmd show subcommands.

  • nuocmd add role-templates ... --domain-admin authorizes a role for domain administration, which includes removing APs from the domain membership, performing certificate rotation, and managing users and roles.

  • nuocmd add role-templates ... --db-admin <DB name> authorizes a role for database administration of the specified database.

  • nuocmd add role-templates ... --hotcopy-admin <DB name> authorizes a role for issuing backups on the specified database. This is a subset of the privileges granted via nuocmd add role-templates ... --db-admin <DB name>.