Authentication and Access Control (Preview)

AnzoGraph supports two basic modes of authentication and access control for users submitting requests to access data. The first mode is one in which both user authentication and authorization of privileges are performed entirely by AnzoGraph. In the second mode, a trusted external LDAP or directory service system provides authentication of users to validate their identity before submitting an operation request to AnzoGraph. The particular way in which AnzoGraph operates depends on two switch settings in the settings.conf file, enable_acl and enable_external_auth. (See AnzoGraph Configuration File Settings.)

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

Regardless of the authentication mode selected, AnzoGraph 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 only to read and update certain graphs, but someone in an "admin" role, with additional privileges, may be permitted to also create or drop graphs. When remote authentication is used, an LDAP or directory service system returns the list of groups/roles that a validated user is a member of, and AnzoGraph then checks authorization for the user to perform the requested operation.

The current functionality provided for AnzoGraph Authentication and Access Control is a Preview release. That is, current features are available for trial use, however, they are subject to change or redesign based on feedback from early users.

The following topics provide more information on how AnzoGraph authentication and access control works, instructions for setting it up, and configuring or changing roles and privileges to access data. Topics covered in this section include the following:

Related Topics

Access Control Basics and Terminology

When you configure AnzoGraph to perform its own authentication of users (without using LDAP or another external directory service), AnzoGraph stores both user credentials as well as the privileges that a user has been given to access graph data. 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 on data, AnzoGraph 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. That is, before a user's request to access data is sent to AnzoGraph, a user's identity is first validated based on the credentials they present for LDAP or other directory service authentication. Then, if the user's credentials are validated, the service passes to AnzoGraph the list of groups/roles that the user is a member of. AnzoGraph uses that information to check the user's privileges against the ACLs defined for AnzoGraph database objects. AnzoGraph 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. If a group/role name specified by a directory service does not yet exist as a role defined in AnzoGraph, 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 roles can be specified in the db.ini file used to configure roles and privileges at startup time, or when AnzoGraph is restarted. Roles can also be modified later by a user assigned SUPERUSER role privileges. See AnzoGraph Roles for more information.

AnzoGraph Configuration File Settings

AnzoGraph provides two configuration settings, enable_acl and enable_external_auth, in the AnzoGraph settings.conf file, that specify the methods of authentication and authorization that AnzoGraph will use. The enable_acl setting controls whether any type of access control, local or remote, is enabled to control access of graph data. If access control is first enabled with the enable_acl setting, the enable_external_auth setting specifies whether users are authenticated by an external LDAP or directory service, or uses AnzoGraph itself to authenticate users.

AnzoGraph Roles

Access to AnzoGraph 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 or added to the role. Role and privilege information is itself 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 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 provide user authentication, only user roles that have the LOGIN attribute enabled can connect to AnzoGraph.

Role Attributes

Role attributes define privileges 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 (when using AnzoGraph "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 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 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 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 AnzoGraph Roles

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

CREATE ROLE <rolename> [privilege attributes list]

When you create a role, AnzoGraph 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 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 specified as 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 on AnzoGraph data.

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 individual 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 respectively 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 specify the following command:

GRANT <group_rolename> TO <rolename> ;;  // Add group role to user role or another group role

To remove privileges of a group from a role, you can specify 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 an individual 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>  // <msmith> will no longer inherit <dba> privileges

If a user is logged into AnzoGraph as <msmith>, you can use the SET ROLE command to remove all of <msmith>’s individual 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>
   // <msmith> will lose their individually assigned privileges,
   // but obtain all the privileges granted to the <engineers> group

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 AnzoGraph Database Objects

By default, AnzoGraph 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 data privileges that a user is granted (or can be revoked) after they log in and are authenticated. When an AnzoGraph 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 respectively 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. 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 a privilege, then revoking that privilege from individual 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 individual 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 is first started or when you reinitialize AnzoGraph, 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 first starts up, it creates two system roles, @system and @sysadmin. Both are considered superusers, however, by default, you cannot log into AnzoGraph with these system roles. In the case of AnzoGraph 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 AnzoGraph settings.conf file to enable either local or remote authentication and access control. To reinitialize AnzoGraph 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, see Starting and Stopping AnzoGraph.

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

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

# group roles
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 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 AnzoGraph system graph named <sbxroles>.

A second system graph named <sbxaclobj> stores privileges to perform operations such as SELECT, UPDATE, DROP, and EXECUTE on individual AnzoGraph 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 an RDF 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 roles.

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

The <sbxroles> System Graph

The AnzoGraph <sbxroles> system graph is updated whenever a role is either created, or altered, or dropped. The following triples get inserted, updated, or removed from the <sbxroles> system 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
<niceness> NNN;                      # optional triple
<grants> "member1,member2";          # list of all the roles granted privileges
.
}
};;

Only an AnzoGraph system administrator (in a superuser role, or with administrator privileges) has the ability to directly update the <sbxroles> graph.

The <sbxaclobj> System Graph

A second system graph named <sbxaclobj> is updated with new triples whenever an AnzoGraph object is either 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 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 data access and access control modifications are logged in an AnzoGraph internal 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 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, 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 LDAP or Directory Service systems, and can also be configured to provide authentication and delivery of user profile and group/role information to AnzoGraph.

For additional security, many customers may also choose to use a reverse proxy web server to isolate their authentication, LDAP or directory service systems, and AnzoGraph from direct connection to their client applications and exposure to other potential outside threats. The following diagram shows a configuration in which a reverse proxy web server processes incoming AnzoGraph 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.

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 operation the user want 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 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 AnzoGraphas a base 64 encoded JSON string in the User-Entry header of the HTTP request. For example, an example JSON string might look like the following:

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

The JSON blob string 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, to reflect a common set of privileges or privileges granted to any members assigned to the same group.

Once AnzoGraph receives the User-Entry JSON string, it compares the specified group names with roles of the same name defined in AnzoGraph. AnzoGraph 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 processes the request and returns results back to the client application; otherwise it returns a message indicating the request was not allowed.

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

Sample LDAP/Directory Services Configuration

Sample files and instructions for configuring an example integration of AnzoGraph 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 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 privileges.
  • AnzoGraph — 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 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 operation requests for AnzoGraph to execute.

See Using the Query & Admin Console for information on using the Query & Admin Console to configure access control roles and privilege for AnzoGraph as well as performing other operations using the Console graphical user interface.