2.5. User Authentication and Access Control

2.5.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 and retrieve user group membership 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).

For more information on how a user will pass credentials to the client see User Authentication.

If the user is authenticated, a session is created, access to the xGT server is granted, and the user’s group membership is retrieved and used to populate their set of security labels. 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

With the pam_unix module, a user’s group membership will be determined by the user’s UNIX groups membership.

Alternatively, if running xGT in an exploratory capacity or as a single-user server, one may want to bypass the user authentication step. In that case a user would want to use the pam_permit module:

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

auth       required     pam_permit.so
account    required     pam_permit.so
session    required     pam_permit.so

Warning

Using pam_permit is insecure and should be used with caution.

The pam_permit module simply authenticates any given username and password. User groups can still be retrieved if xgtd is given a valid UNIX user (a valid password is not necessary to retrieve the groups).

2.5.1.1. Group Membership

The xgtd daemon derives group membership for the user from the groups reported to it by Linux and PAM. For the pam_unix module, these correspond to the UNIX groups set up by the system administrator on the local Linux system running xgtd. For the pam_ldap module, the groups reported back to xGT might not exist on the local Linux system, but on a remote ldap server. Group membership will be mapped to the security labels configured by the administrator of the server instance. For more discussion on security labels and their mapping see User Labels and Validation.

2.5.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

By default xGT uses an insecure channel for its remote connection. Secure Sockets Layer (SSL) should be enabled in a production environment where a server expects remote client connections. For information on setting up SSl with xGT see Using an SSL Secure Channel.

2.5.2. Access Control

Access control in xGT is enabled both on frames and rows.

2.5.2.1. Frame Access Control

Frame access control protects all the rows in a frame with the same permissions. Each frame in the system can have different access permissions for each authenticated user. Frame 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 the labels 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.

  • 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 (frame label).

2.5.2.2. Row Access Control

Row access control protects individual rows in frames. The word “row” means a frame element, such as a vertex in a vertex frame, an edge in an edge frame, or a row in a table frame. Each row in a frame can have multiple security labels attached to it and permission to access the row is determined by matching its labels with those that the user possesses. Unlike frame security, row access control is binary and does not have CRUD types: a user can either access a row or not (row label).

A frame with row security also has frame security. Both the frame and row permissions are checked when accessing data in xGT. To read, update, or delete a row, the user must have both the corresponding frame CRUD permissions and the security labels attached to that row. Frame labels restrict the type of operation that can be performed, while row labels restrict which rows will be affected by that operation.

For example, a user with read access to a frame may perform a read operation, but will only see those rows that the user has permission to access. Similarly, a user with delete and read access to frame WorksFor and People may perform the following query that deletes edges, but this only removes edges the user has permissions for. If there are edges that the user cannot access or whose endpoint vertices the user cannot access, they will be unaffected.

MATCH (a:People)-[b:WorksFor]->(:People)
WHERE a.status = transferred
DELETE b

2.5.2.3. 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 for the desired CRUD operation. To access a row within a frame with row security, the set of labels a user possesses must also contain the labels attached to that row. The set of labels a user possesses is determined by taking the union of the labels of all the groups they belong to (user labels).

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 (system frames).

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 groupA and groupB. The groupA group is mapped to labels label01, label02 and label03, while groupB is mapped to 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:People)-[b:WorksFor]->(c: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: People, WorksFor and 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. The query will only return a result for those edges and vertices whose row labels the user possesses. For any of the frames in the query that have row access control, the query will only return a result that includes rows whose row labels the user possesses. A query may mix frames with no labels attached, only frame labels, only row labels, or both.

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