16.3.5 Graph Sharing Options and Validating Graph Permissions

The graph_sharing_option parameter in the pgx.conf file determines if and how a graph can be shared.

It mainly depends on whether or not the graph is loaded from the database into the graph server (PGX). Graphs that are loaded directly from the database using the session.readGraphByName() API are known as traceable graphs. However, graphs which are created as a result of mutation (through graph alteration APIs) on a loaded graph instance are not traceable graphs.

The graph server (PGX) supports sharing of graphs within sessions of a single user (through the publish API) or across sessions of different users (through the publish and grant permission APIs). This is determined by the graph_sharing_option field in the pgx.conf file.

In addition, the graph server (PGX) will perform periodic checks on all traceable graphs to make sure that the user holding a reference to a traceable graph has all the permissions to access the source graph data in the database. If the permission check fails (for example, the user privileges on the original data source have been revoked) the user session will be destroyed and all sessions of the same user accessing the traceable graph data will be released from memory. The permission_checks_interval field in the pgx.conf file can be used to control the frequency at which the graph server must check the graph permissions.

The following table shows the three graph_sharing_option modes that are supported by the graph server (PGX). The table also provides information on the permission checks and the APIs that are supported on these modes.

Table 16-10 Graph Sharing Options

Graph Sharing Option Description Publish API Allowed Grant Permission API Allowed Permission Checks on Data Source
ALLOW_DATA_SHARING <default> Indicates that all graph types (traceable or not) is allowed across sessions of a single user and across users Yes Yes No
ALLOW_TRACEABLE_DATA_SHARING_WITHIN_SAME_USER Allows only sharing of traceable graphs among sessions of a single user Yes No Yes
DISALLOW_DATA_SHARING Indicates graphs are always session private No No No

For instance, consider the following example in which the graph_sharing_option is set as ALLOW_TRACEABLE_DATA_SHARING_WITHIN_SAME_USER and the permission_checks_interval parameter defaults to 60 seconds in the pgx.conf file. Assume that a graph user's permission to an underlying source table is revoked after the user publishes the graph. If the user attempts to access the graph data, in the current or in another session, the graph gets invalidated and the respective sessions are destroyed.

The following code shows the graph invalidation scenario in the current user session:

opg4j> var graph = session.readGraphByName("HR", "EMP_GRAPH", GraphSource.PG_PGQL)
graph ==> PgxGraph[name=EMP_GRAPH,N=134,E=11,created=1696308375704]
opg4j> session.getGraph("EMP_GRAPH")
$2 ==> graph ==> PgxGraph[name=EMP_GRAPH,N=134,E=11,created=1696402820966]
opg4j> graph.publish()
// Source table permission revoked for the user
opg4j> session.getGraph("EMP_GRAPH") //throws exception and the current session is explicitly destroyed
PgxGraph graph = session.readGraphByName("HR", "EMP_GRAPH", GraphSource.PG_PGQL);
session.getGraph("EMP_GRAPH");
graph.publish();
// Source table permission revoked for the user
session.getGraph("EMP_GRAPH"); //throws exception and the current session is explicitly destroyed
>>> graph = session.read_graph_by_name("EMP_GRAPH", "pg_pgql", schema="HR")
>>> session.get_graph("EMP_GRAPH")
PgxGraph(name: EMP_GRAPH, v: 134, e: 11, directed: True, memory(Mb): 0)
>>> graph.publish()
>>> # Source table permission revoked for the user
>>> session.get_graph("EMP_GRAPH") #throws exception and the current session is explicitly destroyed

The following code shows that the referenced graph also gets invalidated in another session of the given user after permission to the source data table is revoked for the user:

opg4j> //throws exception in another session and the session gets explicitly destroyed
opg4j> graph.queryPgql("SELECT n.* from MATCH (n:employees) LIMIT 5").print()
//throws exception in another session and the session gets explicitly destroyed
graph.queryPgql("SELECT n.* from MATCH (n:employees) LIMIT 5").print();
>>> #throws exception in another session and the session gets explicitly destroyed
>>> graph.query_pgql("SELECT n.* from MATCH (n:employees) LIMIT 5").print()