Authentication and Access Control

AnzoGraph DB supports two basic modes of authentication and access control for users submitting requests to access data.

  1. The first mode is one in which both user authentication and authorization of privileges are performed entirely by AnzoGraph DB.
  2. In the second mode, a trusted external LDAP or directory service system provides authentication of users to validate their identity before submitting a request to AnzoGraph DB.

In many access control systems, privileges are often referred to as permissions.

Regardless of the authentication mode selected, AnzoGraph DB supports Access Control Lists (ACLs) to manage and control which users have privileges to read or write (update) database objects such as graphs and views. The ACLs are "role-based" which means, for example, that someone in a "manager" role may be permitted to read and update certain graphs, but someone in an "admin" role, with additional privileges, may be permitted to create and drop graphs. When remote authentication is used, an LDAP or directory server returns the list of groups/roles that a validated user is a member of and AnzoGraph DB checks if the user is authorized to perform the requested operation.

The following sections provide details about how AnzoGraph DB authentication and access control works, instructions for setting it up, and configuring or changing roles and privileges to access data.

Access Control Basics and Terminology

When you configure AnzoGraph DB to perform its own authentication of users (without using LDAP or another external directory service), AnzoGraph DB stores both user credentials as well as the privileges that a user has been given. An administrator, or another authorized user given the same authority, can grant users additional privileges or add users to other roles where they will inherit the privileges associated with those roles. When a user submits a request to perform some operation, AnzoGraph DB first validates the user's credentials and then checks the user's privileges before processing their request.

With the integration of LDAP or another directory service, users are authenticated remotely. Before a user's request to access data is sent to AnzoGraph DB, a user's identity is first validated based on the credentials they present for the directory server. If the user's credentials are validated, the service passes to AnzoGraph DB the list of groups/roles that the user is a member of. AnzoGraph DB uses that information to check the user's privileges against the defined ACLs. AnzoGraph DB then processes the user's requested operation if the user's privileges allow it.

In LDAP and other external directory services, roles are commonly referred to as groups. When LDAP or another directory service is used to authenticate users, administrators of those systems are responsible to make sure the group (role) names that are maintained in the directory service match and are kept in sync with the role names defined in AnzoGraph DB.

If a group/role name specified by a directory service does not yet exist as a role defined in AnzoGraph DB, an authenticated user is granted access only to the database objects authorized for whatever other roles the user is a member of. The definition of AnzoGraph DB roles can be specified in the db.ini file used to configure roles and privileges when AnzoGraph DB is restarted. Roles can also be modified later by a user assigned SUPERUSER role privileges. See AnzoGraph DB Roles for more information.

ACL Configuration Settings

Two configuration settings, enable_acl and enable_external_auth, in the <install_path>/config/settings.conf file, control the methods of authentication and authorization are used. The enable_acl setting controls whether any type of access control, local or remote, is enabled. If access control is first enabled, the enable_external_auth setting specifies whether users are authenticated by an external LDAP or directory service or whether AnzoGraph DB is used to authenticate users.

AnzoGraph DB Roles

Access to AnzoGraph DB database objects (graphs, views, and queries) and the ability to perform other operations is controlled by defining "user" roles or "group" roles to which users can be assigned. Each role specifies a set of privileges that will be granted to members assigned to the role. Role and privilege information is saved in a system graph, which can be queried just like any other graph data by users with sufficient privileges.

A role can be either a "user" role (when using local authentication), a "group" role, or both. Roles can own database objects or entities and members of those roles can assign privileges on those same objects to other roles. Additionally, it is possible to grant membership of a role to a group, which allows all members of that role all the privileges assigned to that group.

After a user has been authenticated and is logged in, any subsequent queries and other operations run in a current session are attributed to that user (which is the user role when using local AnzoGraph DB authentication). For example, if the current logged-in user runs the CREATE GRAPH command, the newly created graph will have the current user designated as the owner of the graph. Similarly, if a SELECT query is run, the privileges to perform the query are verified against the privileges granted to the current user through their membership in specific group roles.

When configured to have AnzoGraph DB provide user authentication, only user roles that have the LOGIN attribute enabled can connect to AnzoGraph DB.

Role Attributes

Role attributes define privileges or permissions provided to members of a specific role. You assign attributes to a role using the CREATE ROLE command, or update later with the ALTER ROLE command. You can also delete roles with the DROP ROLE command.

Attributes you can assign to a role are the following:

LOGIN | NOLOGIN

Only roles that have the LOGIN attribute set can be used to connect to AnzoGraph DB (when using AnzoGraph DB "local" authentication). The default role setting is NOLOGIN.

INHERIT | NOINHERIT

If a role is created with this attribute, and when it is added to another group role, then this role will inherit all the privileges of the group role. The default role setting is INHERIT.

SUPERUSER | NOSUPERUSER

The SUPERUSER attribute designates a role with superuser privileges. A database superuser bypasses all available privileges and checks to access AnzoGraph DB data. So, it is recommended that the SUPERUSER attribute only be used very rarely, and that most database operations be done within a role that is not assigned superuser privileges. The default setting for roles is NOSUPERUSER.

PASSWORD = “password” | NOPASSWORD

The PASSWORD | NOPASSWORD attribute specifies whether a password is required for user login when AnzoGraph DB is used to provide authentication. If a PASSWORD is supplied at the time of role creation (or added later), then login must supply this same password to connect to the database for that role.

CREATEROLE | NOCREATEROLE

This attribute allows a role to create other roles. Any user logged in as a member of this role with the CREATEROLE attribute set can create, alter, or drop roles as well as grant or revoke membership of roles. A SUPERUSER privilege is required to change the membership of a superuser status.

SYSCATALOG | NOSYSCATALOG

This attribute determines if a role has the ability to SELECT from system graphs or views. The default is NOSYSCATALOG. Only users with SUPERUSER privilege can create a role having the SYSCATALOG privilege.

CREATEGRAPH | NOCREATEGRAPH

This attribute allows a role to create graphs. The default role setting is NOCREATEGRAPH.

CREATEVIEW | NOCREATEVIEW

This attribute allows a role to create views. The default role setting is NOCREATEVIEW.

CREATEQUERY | NOCREATEQUERY

This attribute allows a role to create queries. The default role setting is NOCREATEQUERY.

ROWLIMIT = <num_rows> | NOROWLIMIT

This attribute specifies a positive integer value that determines the maximum number of output rows this role is allowed to retrieve from a SELECT query. The default role setting is NOROWLIMIT.

PRIORITY = <priority_value> | NOPRIORITY

The priority value of a role determines its priority for AnzoGraph DB job scheduling. The default priority value is 50. The range of values allowed is between 1 to 100, with 100 being the highest priority.

Creating, Altering, or Dropping Roles

Two commands are available to create or delete (drop) a role. The syntax for these commands is the following:

CREATE ROLE <rolename> [privilege attributes list]

When you create a role, AnzoGraph DB inserts the following triples into the <sbxroles> system graph based on the attributes specified with the CREATE ROLE command:

<role>
  <attrs> attributes;	        # combined list of attributes
  <password> “password”^^xsd:string; # optional triple added if PASSWORD set
  <rowlimit> NNN;                    # optional triple added if ROWLIMIT set  
  <priority> NNN;                    # optional triple added if PRIORITY set
  <grants> “member1,member2,...”;  # list of all the members to which privilege is granted
.

For more information on system graphs used to store AnzoGraph DB roles and privileges, see Access Control System Graphs.

The syntax of the command to delete or drop a role is the following:

DROP ROLE <rolename>

In both the CREATE ROLE and DROP ROLE commands, <rolename> is a URI, which specifies a user role (when using only local authentication), or a group role that define privileges granted to group members for specific operations.

Once a role is created, its attributes can be altered with the ALTER ROLE command. The syntax for this command is the following:

ALTER ROLE <rolename> [LOGIN | NOLOGIN | INHERIT | NOINHERIT |
                        SUPERUSER | NOSUPERUSER | CREATEGRAPH | NOCREATEGRAPH |
                        CREATEVIEW | NOCREATEVIEW | CREATEQUERY | NOCREATEQUERY |
                        CREATEROLE | NOCREATEROLE | PASSWORD "password"| NOPASSWORD | ...]

The ALTER ROLE command can specify multiple attributes in the same statement. For example:

ALTER ROLE <manager> LOGIN NOINHERIT CREATEGRAPH CREATEROLE 

After roles are defined, you can use the GRANT command to add role membership to other roles. Similarly, you can use the REVOKE command to remove a role's membership from another role. In addition, a couple of additional commands, SET ROLE and RESET ROLE, allow you to clear and reset roles to their original definitions.

The following section describes inheritance of roles when one role is added as a member of another role, and use of the GRANT, REVOKE, SET ROLE, and RESET ROLE commands to change role membership and associated privileges.

Role Membership and Inheritance

There are few differences between "user” roles and "group" roles. If you assign (or grant) a user role to another role, that group simply becomes a group role. To grant privileges of a group to another role, you can run the following command:

GRANT <group_rolename> TO <rolename>

To remove privileges of a group from a role, you can run the following command:

REVOKE <group_role> FROM <rolename>

For example:

CREATE ROLE <msmith>  LOGIN INHERIT;;
CREATE ROLE <pjones> LOGIN INHERIT;;
CREATE ROLE <engineers> NOLOGIN INHERIT;;
CREATE ROLE <managers> NOLOGIN INHERIT;;
GRANT <managers>  TO <msmith> ;;         # privileges of <managers> added to <msmith>
GRANT <engineers> TO <pjones> ;;         # privileges of <engineers> added to <pjones>
GRANT <engineers> TO <managers> ;;       # <engineers> privileges added to <managers>
GRANT <dba> TO <msmith> ;;               # <dba> privileges added to <msmith>

After the statements above are executed, the <msmith> role will have all the privileges it was originally assigned, but will also inherit all the privileges defined for the <managers> role. In addition, the <managers> role will inherit all the privileges of the <engineers> role with the GRANT command. Any role can be granted multiple other roles (that is, it may be added to more than one group). The structure of roles can be thought of as a hierarchical inheritance structure, with a single user having the combined privileges of all the groups they are a member of.

To remove membership in a role, you can use the REVOKE command. For example:

REVOKE <dba> FROM <msmith>

If a user is logged into AnzoGraph DB as <msmith>, you can use the SET ROLE command to remove all of <msmith>’s assigned privileges, so the <msmith> role will just be assigned all the privileges from the user or group role it is set to. For example:

SET ROLE <msmith> TO <engineers>

To reset a role to its original definition, you can execute the following commands:

SET ROLE <smith> TO NONE;;
RESET ROLE <smith>

Assigning Ownership of Database Objects

By default, AnzoGraph DB assigns original ownership of database objects such as graphs, views, and queries to the currently logged-in user or user role that created an object. You can change the ownership of an object with the ALTER <object> OWNER command. For example:

ALTER GRAPH <tpch> OWNER TO <msmith>

To remove a role and assign ownership of all the database objects currently owned by that role to a new role, you can use the REASSIGN OWNED BY command. For example:

REASSIGN OWNED BY <obsolete-role> TO <new-successor-role>;;
DROP OWNED BY <obsolete-role> ;;
DROP ROLE <obsolete-role>

Database Object Permissions

The roles that a user is a member of determine the AnzoGraph DB data privileges that a user is granted (or can be revoked) after they log in and are authenticated. When an AnzoGraph DB object is created, for example, a graph, query, or view, the creator of that object is designated as the owner of that object. To allow other roles to access the same object, the owner must grant specific privileges on that object to other roles.

The different privileges that can be granted or revoked for database objects are the following:

SELECT

READ privilege for a named GRAPH, VIEW, or QUERY.

UPDATE

Permission for SELECT, INSERT, DELETE, COPY, MOVE, ADD, or CLEAR operations on a named GRAPH.

DROP

Permission to drop a named GRAPH, VIEW, or QUERY.

Granting and Revoking Object Permissions

Unless ownership has been reassigned, the <owner> of a database object has full privileges to perform operations on that object. Owners can use the GRANT and REVOKE commands to grant or revoke privileges to other roles to perform operations on those same database objects they own. For example, to grant UPDATE privileges on an existing <tpch> graph to the <msmith> role, the owner or other authorized users could run the following command:

GRANT UPDATE on <tpch> TO <msmith>

A special PUBLIC keyword is available to represent all roles, so you could execute the following command to grant privileges to all roles on a database object:

GRANT UPDATE on <tpch> TO PUBLIC

PUBLIC is a special role, which encompasses all roles currently created, as well as any future roles that may be defined in AnzoGraph DB. If PUBLIC has been granted a privilege, then that privilege is available for all current roles, and the same privilege will be extended to future roles that have not been created yet. If PUBLIC has been granted, then revoking that privilege from roles will not have any effect. The PUBLIC role cannot be created, dropped, or altered.

Another special keyword, ALL, is available to specify granting or revoking "all privileges". For example, to grant all privileges on the <tpch> graph to the <msmith> user, you could run the following command:

GRANT ALL on <tpch> TO <msmith>

To revoke privileges from a database object, you can use the REVOKE command. For example, to revoke access to <tpch> from everyone (except for the OWNER and SUPERUSER roles), you could run the following command:

REVOKE ALL on <tpch> FROM PUBLIC

As with the GRANT command, you can also specify privileges with the REVOKE command. For example, to revoke only the UPDATE privilege from the <msmith> role, you could run the following command:

REVOKE UPDATE on <tpch> FROM <msmith>

Access Control Initialization and Updates

When AnzoGraph DB is first started or when you reinitialize AnzoGraph DB, the db.ini initialization file, located in the <installdir>/config directory (by default), is executed. The db.ini file contains various DDL statements, for example, CREATE ROLE, DROP ROLE, ALTER ROLE, and GRANT commands. The db.ini file is treated as "trusted", so statements contained within the file can create any number of roles with any allowed attributes. However, the db.ini file cannot contain any DML statements such as SELECT, CONSTRUCT, ASK, DESCRIBE, etc.

When AnzoGraph DB first starts up, it creates two system roles, @system and @sysadmin. Both are considered superusers, however, by default, you cannot log into AnzoGraph DB with these system roles. In the case of AnzoGraph DB local authentication, you should create other roles that you can login with, by creating those new login roles in the db.ini file. (At least one of the roles should typically be given SUPERUSER privileges.) New user roles may be altered, given passwords, or dropped during the bootstrap initialization process using statements included in the db.ini file.

You need to create the db.ini file before updating enable_acl and enable_external_auth settings in the settings.conf file to enable either local or remote authentication and access control. To reinitialize AnzoGraph DB with new ACL configuration settings, you can run the following command:

/install_path/bin/azgctl -start -init

Alternatively, you could also run the following command:

/install_path/bin/azgctl -start -init data

For more information on starting and stopping, restarting and initializing AnzoGraph DB, see Starting and Stopping AnzoGraph DB.

If AnzoGraph DB fails to successfully execute the db.ini file due to errors, AnzoGraph DB will not start up. To prevent this situation from occurring, an administrator should test and make sure the db.ini file can be executed without errors.

Here is a sample db.ini file that shows some of the statements the file might include:

# group roles
CREATE OR REPLACE ROLE <superadmin> SUPERUSER LOGIN PASSWORD = 'superadmin' ;;
CREATE OR REPLACE ROLE <manager> NOLOGIN NOINHERIT CREATEROLE CREATEGRAPH CREATEVIEW CREATEQUERY ;;
CREATE OR REPLACE ROLE <dev> NOLOGIN NOINHERIT CREATEGRAPH CREATEVIEW CREATEQUERY ;;
# login users (local authentication mode only)
CREATE OR REPLACE ROLE <julio> LOGIN ;;
CREATE OR REPLACE ROLE <john> LOGIN ;;
CREATE OR REPLACE ROLE <mary> LOGIN ;;
# grant privileges to local user roles
GRANT <dev> TO <julio> <john> <mary>;;
GRANT <manager> TO <julio>

Access Control System Graphs

All AnzoGraph DB role and object attributes and privileges are stored in one of two system graphs, <sbxroles> or <sbxaclobj>.

Regardless of whether users are authenticated locally or by a remote directory service, the privileges granted to specific groups or roles is stored locally within the system graph named <sbxroles>.

A second system graph named <sbxaclobj> stores privileges to perform operations such as SELECT, UPDATE, DROP, and EXECUTE on objects such as graphs, views, and queries. When an object is created, its creator is designated as the owner of that object and that information is recorded with the entry of a triple in the <sbxaclobj> system graph. To allow other users to access the same object, the owner can grant privileges on that object to other AnzoGraph DB roles.

The <sbxaclobj> system graph is updated with new triples whenever an object is either created or dropped or if its privileges are altered. Only system administrators assigned the superuser role or belonging to a group with administration privileges have the ability to modify the <sbxaclobj> system graph to update privileges.

The <sbxroles> System Graph

The AnzoGraph DB <sbxroles> system graph is updated whenever a role is created, altered, or dropped. The following triples get inserted, updated, or removed from the <sbxroles> graph, whenever one of these operations is performed.

INSERT DATA {
GRAPH <sbxroles> {
<role1> a <Role>;
<attrs> attrib_list;	              # combined list of attributes
<password> "passwd"^^xsd:string;   # optional triple for local authentication
<rowlimit> NNN;                      # optional triple
<priority> NNN;                      # optional triple
<grants> "member1,member2";          # list of all the roles granted privileges
.
  }
}

The <sbxaclobj> System Graph

A second system graph, named <sbxaclobj>, is updated with new triples whenever an object is created or dropped or if its privileges are altered. The following triples get inserted, updated, or removed from the <sbxroles> system graph whenever one of these operations is performed.

INSERT DATA {
GRAPH <sbxaclobj> {
   <aclobj_uri>		   # <based on objname,objtype,objcontainer
   <objname> name;
   <objtype> <graph | view | query | udx | subject | predicate | triple> ;
   <privileges> acl;         # mandatory: serialized json string for Privileges
   <objid> (graphid | viewid | queryid);  # optional: for graph
   <container> “container” ; # optional: for udx; name of the library
# for subject - name of the graph
# for predicate - name of the graph
# for triple - name of the graph
.
  }
}

Again, only an AnzoGraph DB system administrator, assigned the superuser role or belonging to a group with administration privileges, has the ability to directly modify the <sbxaclobj> system graph.

Monitoring and Auditing Access Control Activity

All AnzoGraph DB data access and access control modifications are logged in a system table named sth_acl. System administrators can monitor the sth_acl system table for various types of access control entries and activities. Those events include:

  • "Init file execution"
  • "Authorization Success"
  • "Authorization Failure"
  • "Create Role"
  • "Drop Role"
  • "Alter Role"
  • "Alter Graph" (changes of ownership)
  • "Alter Owned By"
  • "Grant Membership"
  • "Grant Privilege"
  • "Revoke Membership"
  • "Revoke Privilege"

In addition to monitoring access, an administrator can diagnose failures by examining the entries in the "sth_acl" table. You can query the AnzoGraph DB system table using regular SPARQL queries just like that of any other database source. For example:

azgi -c "select * where {table 'sth_acl'}"

The following provides a sample query of sth_acl table entries following execution of a GRANT statement:

xrowid   | query | time          | user | action_type           | detail
---------+-------+---------------+------+-----------------------+------------------------------------------------
1219813  | 12453 | 2020-11-20... | test | Grant Privilege       | Granted privileges 1 on <testGraph> to <jsmith>
1220751  |     0 | 2020-11-20... |      | Authorization Success | test
1219294  |     0 | 2020-11-20... |      | Authorization Success | test
1212465  | 12370 | 2020-11-20... | test | Grant Membership      | Granted membership of <engineers> to <jsmith>

LDAP/Directory Services Integration

There are various ways to configure integration of LDAP or another directory service system with AnzoGraph DB, depending on the security policy needs and the current IT infrastructure in place within an organization. First, customers can choose from any number of open source or commercially available authenticator applications, for example, from companies such as Apple, Facebook, and Google, or other authentication solutions published on web sites such as GitHub. These applications can provide an interface between client applications and directory servers and can also be configured to provide authentication and delivery of user profile and group/role information to AnzoGraph DB.

For additional security, many customers may also choose to use a reverse proxy web server to isolate their authentication systems and AnzoGraph DB from direct connection to their client applications and exposure to other potential threats. The following diagram shows a configuration in which a reverse proxy web server processes incoming AnzoGraph DB queries and other requests from a client application. A client application directs the user's credentials and the requested operation through the reverse proxy server to an LDAP/Directory Services system for authentication. If the user is validated, the reverse proxy then forwards the user profile, the names of the groups in which the user is a member, and their original operation request, to AnzoGraph DB.

The basic operation common to all these configurations is that a client application first constructs and outputs a formatted request that includes a user's credentials along with the AnzoGraph DB operation the user wants to perform. For example:

azgi -u username:password -c "create graph <abc>"

Many authenticator programs allow client applications to omit password entries from the request, and then prompt users later to enter a password. In addition, authenticator programs will often cache an authentication token once a user's credentials have been validated so that a user's credentials do not need to be re-validated for every request unless the token has expired.

After validating the user, the LDAP or directory service systems looks up whatever group/role membership a user has been assigned. That information is then forwarded to AnzoGraph DB as a base 64 encoded JSON string in the User-Entry header of the HTTP request. For example, a JSON string might look like the following:

{"name":"jsmith","groups":[{"name":"manager"}]}

The JSON blob returned for validated users can also specify multiple assigned groups/roles. It may also include nested groups/roles if your privilege hierarchy is set up to use them. For example:

{
  "name": "jsmith",
  "member_of": [{
      "name": "engineering",
      "member_of": [{ "name": "manager" }]
    },
    { "name": "support" }]
}

LDAP and other directory services use the term group, synonymous to roles in AnzoGraph DB, to reflect a common set of privileges or privileges granted to any members assigned to the same group.

Once AnzoGraph DB receives the User-Entry JSON string, it compares the specified group names with roles of the same name defined in AnzoGraph DB. AnzoGraph DB then checks the Access Control privileges (ACLs) on database objects to verify the user's privileges to perform the requested operation. If the user has the appropriate privileges, AnzoGraph DB processes the request and returns results back to the client application; otherwise it returns a message indicating the request is not allowed.

The names of all groups specified in the User-Entry JSON string must exactly match role names already defined in AnzoGraph DB for the current user to be given the associated role privileges. AnzoGraph DB roles may be defined at startup with entries in the db.ini file or by issuing role creation commands after AnzoGraph DB has started.

Sample LDAP/Directory Services Configuration

Sample files and instructions for configuring an example integration of AnzoGraph DB with an LDAP server is provided on the Cambridge Semantics GitHub web site:

https://github.com/cambridgesemantics/csi-anzograph-ldap-demo

The README.md file on the site describes the series of steps you can perform to install and configure this example setup. The sample configuration of the LDAP/Directory Services integration with AnzoGraph DB includes the following components:

  • NGINX: Free, open source HTTP web server to which client application operation requests are sent.
  • LDAP authentication proxy: Example Python program that processes requests to validate user credentials and pass client operation requests to an LDAP server.
  • OpenLDAP: Open source LDAP implementation that maintains user profile and group/role membership information for AnzoGraph DB privileges.
  • AnzoGraph DB: Cambridge Semantics database engine pre-configured for remote authentication and access control.

After completing the setup steps in the instructions, you can use any HTTP client application to send AnzoGraph DB operation requests to the reverse proxy server. For demonstration purposes, you can also use the AZGI CLI to submit requests.

In addition to the basic setup, you can install and use other third party tools such as Apache Directory Studio to administer changes to OpenLDAP user profiles and group/role membership. You can also use tools such as Postman to submit queries and other requests to AnzoGraph DB.

Related Topics