2.4. User Authentication and Access Control

2.4.1. User Authentication

xGT’s user authentication uses Linux’s Pluggable Authentication Modules (PAM) system to support multiple authentication sources. xGT is a PAM-aware application that can authenticate users based on different authentication services available on an installed Linux system.

The user identification and credentials (typically a password) provided by an xGT user in their Python connection object are passed directly to the PAM authentication service (or services) configured on the Linux system running the xGT server application (xgtd daemon). The Python getpass module can be used to securely authenticate a user’s password.

import getpass

conn = xgt.Connection(userid = "user01", credentials = getpass.getpass())

If the user is authenticated, then a session is created and access to the xGT server is granted. The session will persist while the Python client connection is maintained to the server for a given session lifetime as configured by security.session_ttl. Note that further actions on the xGT server are now subject to access control validation.

PAM configuration for xGT is typically set up in a system file located at /etc/pam.d/xgtd. A simple example would be to allow users already configured as UNIX users in the system to authenticate to the xGT server. Users would use their regular Linux user identification and password to authenticate against xGT. The following sample PAM configuration file illustrates that case:

#
# /etc/pam.d/xgtd - specify the PAM behavior for xgtd
#

auth       required     pam_unix.so
account    required     pam_unix.so
session    required     pam_unix.so

2.4.1.1. Group Membership

The xgtd daemon derives group membership for the user from the groups reported to it by Linux and PAM. For simple deployments, these correspond to the UNIX groups set up by the system administrator on the local Linux system running xgtd. For enterprise deployments, the groups reported back to xGT might not exist on the local Linux server, but can still be used. Group membership is important for access control. See Access Control.

2.4.1.2. Enterprise Deployments

xGT can be deployed to authenticate against enterprise-level directory services. Our currently supported enterprise-level authentication source is the Lightweight Directory Access Protocol (LDAP) service. PAM on xGT’s supported Linux platforms provides a module to interface to an LDAP directory server for authentication: PAM-LDAP (found as the pam_ldap.so shared library on Linux platforms).

The Linux server running the xgtd daemon should be configured as a client of the LDAP server and the Name Service Switch (NSS) service should be configured to validate users and groups from LDAP as well. The addition of these two services allows for xGT to authenticate users existing in the LDAP directory without them needing to have a UNIX account on the local Linux server running xGT. A sample configuration file for setting up xGT to authenticate against LDAP sources is as follows:

#
# /etc/pam.d/xgtd - specify the PAM behavior for xgtd
#

auth       required     pam_ldap.so
account    required     pam_ldap.so
session    required     pam_ldap.so

2.4.2. Access Control

Access control in xGT is enabled at the frame level. Each individual frame in the system can have different access permissions for different authenticated users. Access control is based on matching the access permissions required for a frame with the access permissions granted to an authenticated user. Access permissions are determined by matching security labels for frames with those that the user possesses.

A frame has four sets of labels, one for each of the following access types:

  • Create: The create access type allows the insertion of new rows into the frame in question.

  • Read: The read access type allows reading operations on the data rows held by the frame.

  • Update: The update access type allows the updating of existing rows in the frame. Columns of existing rows can be modified if this access type is granted.

  • Delete: The delete access type allows the deletion of existing rows from a frame. Delete access on a frame is also required to delete the frame itself.

Having create, update, or delete access requires also having read access.

xGT uses the term CRUD labels for the sets of labels attached to a frame.

2.4.2.1. User Labels and Validation

xGT uses a simple model for access control. The set of labels a user possesses must contain the labels on the frame the user wishes to access. The set of labels a user possesses is determined by taking the union of the labels of all the groups they belong to.

The rest of this section explains how access control works in detail. If you need to learn how to configure it see instead Configuring Groups and Labels.

When a user authenticates, a list of groups is retrieved from the external authentication system via PAM. xGT maps those groups to a set of labels for the user’s identity by using the mapping stored in the system frame xgt__Group_Label.

Each entry in the xgt__Group_Label frame maps a group to a specific label. Because a group may appear in multiple rows of the frame, the same group may map to different labels (one-to-many). The only restriction is that the labels must be present in the master label catalog in the frame xgt__Label.

System frames, such as the xgt__Label and xgt__Group_Label frames, are discussed in detail in System Frames in xGT.

Since a user can belong to multiple groups simultaneously, the mapping of users-to-labels is a many-to-many mapping. For example user01 may belong to groups groupA and groupB. The groupA group is mapped to labels label01, label02 and label03, while groupB is mapped to labels label03 and label05. The resulting set of labels for user01 is { label01, label02, label03, label05 }.

xGT assesses the type of operation requested by the user to determine which of the CRUD label sets to validate the user labels against. The following example shows a simple query without modifications to queried frames that writes to a results table.

MATCH (a:career__People)-[b:career__WorksFor]->[c:corp__Companies]
WHERE 100 >= a.person_id AND a.person_id <= 150
RETURN a.name, c.name
INTO results__Result

To be able to execute this query, the user’s labels must contain all the read labels on each frame being read: career__People, career__WorksFor and corp__Companies. The user’s labels must also contain the read labels of the results namespace frame and the read and create labels of the results__Result frame. If the results table doesn’t already exist, the user’s labels must also contain the create labels of the results namespace.

Namespaces and frame types are described in more detail in Graph Data Model: Frames and Namespaces.

2.4.2.2. Access Types for xGT Operations

As can be seen from the previous example, xGT operations will, in general, require multiple access types to multiple frames simultaneously.

  • TQL MATCH operations require read access to the frames present in the structural part of the query (graph pattern) and require create access for the results table. In addition, create access is required for the enclosing namespace of a results table if the table doesn’t already exist.

  • CREATE and MERGE operations insert new rows into a frame and require create access on the relevant frame.

  • SET operations modify properties of existing elements of a frame and require update access on the relevant frame.

  • DELETE and DETACH DELETE operations remove existing elements of a frame and require delete access on the relevant frame.

  • load() and insert() operations read data into xGT from external sources and require create access on the relevant frame.

  • save(), get_data(), and get_data_pandas() operations write data from an xGT frame to an external target and require read access on the relevant frame.

  • create_table_frame(), create_vertex_frame(), and create_edge_frame() operations require create access on the enclosing namespace frame. For example, creating the frame graph__EdgeFrame requires create access on the namespace frame graph.

  • create_namespace() operations require create access on __, the top-level namespaces frame.

  • drop_frame() operations require delete access on the enclosing namespace frame and on the frame being deleted. For example, deleting the table frame results__Result requires delete access on the enclosing results namespace and the Result frame.

  • drop_namespace() operations require delete access on __, the top-level namespaces frame.

  • get_table_frame(), get_vertex_frame(), and get_edge_frame() operations require read access on the frames being read. When no specific frames are requested, xGT returns the set of frames for which the user has read access.

  • get_namespaces() requires read access on __, the top-level namespaces frame.

  • schedule_job() and run_job() operations require create access on the xgt__Running_Jobs system frame (see System Frames in xGT).

  • wait_for_job() requires read access on the xgt__Running_Jobs system frame.

  • cancel_job() requires update access on the xgt__Running_Jobs system frame.

  • get_jobs() requires read access on the xgt__Running_Jobs and xgt__Job_History system frames.

  • get_config() operations require read access on the xgt__Config system frame.

  • set_config() operations require update access on the xgt__Config system frame.