5. Security#

QuasarDB employs state of the art security mechanisms that handle all aspects of a secure database cluster:

  • Authentication between clients and servers are done using public/private key authentication;

  • The communication between client and servers can optionally be encrypted using these keypairs;

  • Cluster-side, node-to-node communication can optionally be encrypted;

  • Granular privilege authorization ensures that users are able to perform a subset of operations on a set of resources.

Warning

QuasarDB does not employ full stream encryption by default. To enable it, see Encrypted communication.

5.1. Enable access-control#

Before we can continue setting up security controls, you must enable access control by setting the correct security configuration parameters.

5.2. Key management#

QuasarDB’s security mechanism uses public/private key authenitcation, and has four distinct types of files that manage these:

  • A cluster public key, typically located in /usr/share/qdb/cluster_public.key. This file is safe to be shared with anyone that wants to connect to the database.

  • A cluster private key, typically located in /etc/qdb/cluster_private.key. This file contains sensitive data and should never be shared with users, and kept in a safe place.

  • A file that contains data and metadata about all users that can access the QuasarDB daemon, typically located in /etc/qdb/users.txt. This file should not be shared with anyone.

  • For each user, a private security token is generated which they can use to authenticate against the database.

The cluster public key cluster_public.key, private key cluster_private.key and the user metdata file users.txt must be identically replicated and available on all QuasarDB nodes.

5.3. Cluster key generation#

A QuasarDB daemon node needs to have the cluster’s public and private key files in order to operate. If you installed QuasarDB through a package manager, it’s likely that these keys have already been generated. If this is not the case, or if you want more control over the process you can use the qdb_cluster_keygen tool to generate these keys:

$ qdb_cluster_keygen --output-public /usr/share/qdb/cluster_public.key --output-secret /etc/qdb/cluster_private.key

The cluster_private.key should be stored on each of the QuasarDB nodes, and corresponds to the global.security.cluster_private_file configuration parameter in the QuasarDB configuration file. This is a sensitive file that should never be shared with anyone.

The cluster_public.key contains the public key and should be shared with each of the users that wishes to connect to the QuasarDB daemon.

5.4. User management#

QuasarDB stores all user accounts in a single JSON file (default /etc/qdb/users.txt) that must be replicated verbatim on every node. Each record holds the UID, username, privilege bit-mask, public key, and status flags. Administrators can update that file in two ways:

  • Online (recommended) – run SQL statements in qdbsh while the cluster is up.

  • Offline – run the qdb_user_add utility when the daemon is stopped, ideal for bootstrapping the very first superuser.

Both tools only edit the file; you remain responsible for persisting it across container rebuilds or VM images.

Note

For every account QuasarDB stores the public key. The user keeps the matching private key (for example, analyst.key). Authentication and all wire-level encryption derive directly from this key-pair — similar to OpenSSH.

5.4.1. Online management with the query language#

The SQL dialect exposes full lifecycle control. Run the commands below in qdbsh:

-- create a user with read-only privileges
CREATE USER 'analyst' UID=1
  USER_SECURITY_FILE='/etc/qdb/analyst.pub'
  PRIVILEGES=SELECT;

-- enable and grant more rights later
ALTER USER 'analyst' ADD PRIVILEGES=SET_TRANSACTION;

-- inspect current settings
SHOW USER 'analyst';

-- remove the account
DROP USER 'analyst';

5.4.1.1. Key facts for operators#

  • USER_SECURITY_FILE points to a path on the server, never the client workstation.

  • All privilege operations are incremental — ADD, DROP, or SET to overwrite.

  • RELOAD USER CONFIG re-parses the on-disk file specified by global.security.user_list in qdbd.conf. Use it after manual edits or file-sync operations.

5.4.2. Offline bootstrapping with qdb_user_add#

When the cluster is down or not yet initialised, use the standalone binary:

$ qdb_user_add                                \
    --uid 10                                  \
    --username admin                          \
    --privileges ALL                          \
    --output-private-key /tmp/admin.key       \
    --user-list /etc/qdb/users.txt

Highlights:

  • Works without a running qdbd — perfect for golden-image builds or disaster recovery.

  • Generates and prints a new private key in PEM format.

  • Field meanings map 1-to-1 onto the SQL clauses, so later maintenance can move to qdbsh seamlessly.

5.4.3. Synchronising the users file#

Keep /etc/qdb/users.txt under your configuration-management system:

  • Containers – bake the file into the base image or mount it from a read-only ConfigMap / Secret.

  • Virtual machines – copy it to the template disk before cloning new nodes.

  • Bare metal – distribute it with Ansible, Salt, or rsync, then run RELOAD USER CONFIG on each host.

Failure to replicate the file consistently will lead to authentication errors rather than silent privilege drift.

5.5. Authentication#

Authentication is the process of establishing the identity of a client. When security is enabled, QuasarDB requires all clients to authenticate with the cluster in order to establish their identity.

In order to do this, a user needs to provide the following:

  • A username;

  • A user private key;

  • A cluster public key.

For the username and user private key, one can take a look at one of the user security files:

{
  "username": "analyst",
  "secret_key": "SlqrtVosIcR0Y/awboeHO/1G1HK7S4tIFiiJ6oXx1Wr0="
}

You can establish a secure connection using the QuasarDB shell as follows:

$ qdbsh --cluster-public-key /usr/share/qdb/cluster_public.key --user-security-file /path/to/my_private.key

If you want to establish a secure connection using one of the language APIs, please refer to the secure connection tutorial.

5.6. Authorization#

Authorization is the process of determining the privileges a user has on a certain resource. Authorization works in conjunction with authenitcation, as privileges are assigned based on a user’s identity.

A user’s privileges for a certain object are determined on two levels:

  • The default privileges assigned to a user with qdb_user_add;

  • Additional privileges for the user manually assigned to the table using ../queries/grant or Revoke.

Each privilege is a flag with a number, for which you can view an overview below. To combine several privileges into a single number, one simply add the codes of each of the privileges. For example, to assign the select, insert and set_transaction privileges, the calculation would be:

select (2) + insert (4) + set_transaction (16384) = 2 + 4 + 16384 = 16390

Name

Code

Description

denied

1

The absence of privileges. When this flag is present, all other privileges will be ignored.

select

2

The right to select (read) information from an object.

insert

4

The right to insert (add additional) information into an object.

update

8

The right to update existing value(s) of an object.

delete

16

The right to delete value(s) inside an object.

index

32

The right to create or modify indexes of tables.

alter

64

The right to alter the properties of an object.

create

128

The right to create an object.

drop

256

The right to delete an object.

grant

512

The right to manage rights of an object.

user_manage

1024

The right to manage users inside the system.

system

2048

The right to execute cluster-wide commands such as purging the caches.

set_acl

4096

The right to modify access control to entries.

get_acl

8192

The right to read access control list of entries.

set_transaction

16384

The right to commit or rollback a transaction.

Note

The most common authorizations for a user are read and write access. However, since the primary method of interacting with QuasarDB is through an API, the standard select(2) and insert(4) privileges might be insufficient, as our APIs internally use transactions for multiple operations. Hence, to ensure seamless integration with the QuasarDB APIs, we recommend setting the privilege level to 16386 for read access and 16390 for write access.

5.7. Encrypted communication#

QuasarDB allows you to encrypt communication between client and server, including node-to-node communication. This is disabled by default, as there is a non-neglectible performance overhead in full stream encryption, and most deployments have secured L2/L3 communications anyway.

To enable full stream encryption, enable the global.security.encrypt_traffic in the security configuration parameters.

Note

Traffic is encrypted using AES GCM with a 256-bit key. It requires the AES-NI instructions or equivalent.

5.8. Access control#

In addition to default privileges, you can specify access control for every entry. The explicit access specification overrides the default privileges of the user.

You can use access control to:

  • Give more access than the default privileges

  • Give less access than the default privileges

Modifying access control requires the “set_acl” privilege.

To give explicit privileges to an entry use the GRANT query (see ../queries/grant) to remove privileges use the REVOKE query (see Revoke).

To improve performance, nodes will cache ACL information. The size and duration of the cache is configuration. This means that it may take up to the cache date validity for updated ACL information to propagate in the cluster.