5.6.1 Applying Oracle Label Security (OLS) on Property Graph Data

This topic presents an example illustrating how to apply OLS to property graph data.

Because the property graph is stored in regular relational tables, this example is no different from applying OLS on a regular relational table. The following shows how to configure and enable OLS, create a security policy with security labels, and apply it to a property graph. The code examples are very simplified, and do not necessarily reflect recommended practices regarding user names and passwords.

  1. As SYSDBA, create database users named userP, userP2, userS, userTS, userTS2 and pgAdmin.

    CONNECT / as sysdba;
    
    CREATE USER userP IDENTIFIED BY userPpass;
    GRANT connect, resource, create table, create view, create any index TO userP;
    GRANT unlimited TABLESPACE to userP;
    
    CREATE USER userP2 IDENTIFIED BY userP2pass;
    GRANT connect, resource, create table, create view, create any index TO userP2;
    GRANT unlimited TABLESPACE to userP2;
    
    CREATE USER userS IDENTIFIED BY userSpass;
    GRANT connect, resource, create table, create view, create any index TO userS;
    GRANT unlimited TABLESPACE to userS;
    
    CREATE USER userTS IDENTIFIED BY userTSpass;
    GRANT connect, resource, create table, create view, create any index TO userTS;
    GRANT unlimited TABLESPACE to userTS;
    
    CREATE USER userTS2 IDENTIFIED BY userTS2pass;
    GRANT connect, resource, create table, create view, create any index TO userTS2;
    GRANT unlimited TABLESPACE to userTS2;
    
    CREATE USER pgAdmin IDENTIFIED BY pgAdminpass;
    GRANT connect, resource, create table, create view, create any index TO pgAdmin;
    GRANT unlimited TABLESPACE to pgAdmin;
    
  2. As SYSDBA, configure and enable Oracle Label Security.

    ALTER USER lbacsys IDENTIFIED BY lbacsys ACCOUNT UNLOCK;
    EXEC LBACSYS.CONFIGURE_OLS;
    EXEC LBACSYS.OLS_ENFORCEMENT.ENABLE_OLS;
    
  3. As SYSTEM, grant privileges to sec_admin and hr_sec.

    CONNECT system/<system-password>
    GRANT connect, create any index to sec_admin IDENTIFIED BY password;
    GRANT connect, create user, drop user, create role, drop any role TO hr_sec IDENTIFIED BY password;
    
  4. As LBACSYS, create the security policy.

    CONNECT lbacsys/<lbacsys-password>
    
    BEGIN
    SA_SYSDBA.CREATE_POLICY (
      policy_name => 'DEFENSE',
      column_name => 'SL',
      default_options => 'READ_CONTROL,LABEL_DEFAULT,HIDE');
    END;
    /
    
  5. As LBACSYS , grant DEFENSE_DBA and execute to sec_admin and hr_sec users.

    GRANT DEFENSE_DBA to sec_admin;
    GRANT DEFENSE_DBA to hr_sec;
    
    GRANT execute on SA_COMPONENTS to sec_admin;
    GRANT execute on SA_USER_ADMIN to hr_sec;
    
  6. As SEC_ADMIN, create three security levels (For simplicity, compartments and groups are omitted here.)

    CONNECT sec_admin/<sec_admin-password>;
    
    BEGIN
    SA_COMPONENTS.CREATE_LEVEL ( 
      policy_name => 'DEFENSE', 
      level_num => 1000,
      short_name => 'PUB',
      long_name => 'PUBLIC'); 
    END;
    /
    EXECUTE SA_COMPONENTS.CREATE_LEVEL('DEFENSE',2000,'CONF','CONFIDENTIAL');
    EXECUTE SA_COMPONENTS.CREATE_LEVEL('DEFENSE',3000,'SENS','SENSITIVE');
    
  7. Create three labels.

    EXECUTE SA_LABEL_ADMIN.CREATE_LABEL('DEFENSE',1000,'PUB');
    EXECUTE SA_LABEL_ADMIN.CREATE_LABEL('DEFENSE',2000,'CONF');
    EXECUTE SA_LABEL_ADMIN.CREATE_LABEL('DEFENSE',3000,'SENS');
    
  8. As HR_SEC, assign labels and privileges.

    CONNECT hr_sec/<hr_sec-password>;
    
    BEGIN
    SA_USER_ADMIN.SET_USER_LABELS (
      policy_name => 'DEFENSE',
      user_name => 'UT',
      max_read_label => 'SENS',
      max_write_label => 'SENS',
      min_write_label => 'CONF',
      def_label => 'SENS',
      row_label => 'SENS');
    END;
    /
    
    EXECUTE SA_USER_ADMIN.SET_USER_LABELS('DEFENSE', 'userTS', 'SENS');
    EXECUTE SA_USER_ADMIN.SET_USER_LABELS('DEFENSE','userTS2','SENS');
    EXECUTE SA_USER_ADMIN.SET_USER_LABELS('DEFENSE', 'userS', 'CONF');
    EXECUTE SA_USER_ADMIN.SET_USER_LABELS ('DEFENSE', userP', 'PUB', 'PUB', 'PUB', 'PUB', 'PUB');
    EXECUTE SA_USER_ADMIN.SET_USER_LABELS ('DEFENSE', 'userP2', 'PUB', 'PUB', 'PUB', 'PUB', 'PUB');
    EXECUTE SA_USER_ADMIN.SET_USER_PRIVS ('DEFENSE', 'pgAdmin', 'FULL');
    
  9. As SEC_ADMIN, apply the security policies to the desired property graph. Assume a property graph with the name OLSEXAMPLE with userP as the graph owner. To apply OLS security, execute the following statements.

    CONNECT sec_admin/<password>;
    
    EXECUTE SA_POLICY_ADMIN.APPLY_TABLE_POLICY ('DEFENSE', 'userP', 'OLSEXAMPLEVT$');
    EXECUTE SA_POLICY_ADMIN.APPLY_TABLE_POLICY ('DEFENSE', 'userP', 'OLSEXAMPLEGE$');
    EXECUTE SA_POLICY_ADMIN.APPLY_TABLE_POLICY ('DEFENSE', 'userP', 'OLSEXAMPLEGT$');
    EXECUTE SA_POLICY_ADMIN.APPLY_TABLE_POLICY ('DEFENSE', 'userP', 'OLSEXAMPLESS$');
    

Now Oracle Label Security has sensitivity labels to be associated with individual vertices or edges stored in the property graph.

The following example shows how to create a property graph with name OLSEXAMPLE, and an example flow to demonstrate the behavior when different users with different security labels create, read, and write graph elements.

// Create Oracle Property Graph
String graphName = "OLSEXAMPLE";
Oracle connPub = new Oracle("jdbc:oracle:thin:@host:port:SID",  "userP", "userPpass");
OraclePropertyGraph graphPub = OraclePropertyGraph.getInstance(connPub, graphName, 48);

// Grant access to other users
graphPub.grantAccess("userP2",  "RSIUD"); // Read, Select, Insert, Update, Delete (RSIUD)
graphPub.grantAccess("userS",   "RSIUD");
graphPub.grantAccess("userTS",  "RSIUD");
graphPub.grantAccess("userTS2", "RSIUD");
 
// Load data
OraclePropertyGraphDataLoader opgdl = OraclePropertyGraphDataLoader.getInstance();
String vfile = "../../data/connections.opv";
String efile = "../../data/connections.ope";
graphPub.clearRepository();
opgdl.loadData(graphPub, vfile, efile, 48, 1000, true, null);
System.out.println("Vertices with user userP and PUBLIC LABEL: " + graphPub.countVertices()); // 78
System.out.println("Vertices with user userP and PUBLIC LABEL: " + graphPub.countEdges());  // 164

// Second user with a higher level 
Oracle connTS = new Oracle("jdbc:oracle:thin:@host:port:SID", "userTS", "userTpassS");
OraclePropertyGraph graphTS = OraclePropertyGraph.getInstance(connTS, "USERP", graphName, 8, 48, null, null);
System.out.println("Vertices with user userTS and SENSITIVE LABEL: " + graphTS.countVertices()); // 78
System.out.println("Vertices with user userTS and SENSITIVE LABEL: " + graphTS.countEdges());  // 164

// Add vertices and edges with the second user
long lMaxVertexID = graphTS.getMaxVertexID();
long lMaxEdgeID = graphTS.getMaxEdgeID();
long size = 10;
System.out.println("\nAdd " + size + " vertices and edges with user userTS and SENSITIVE LABEL\n");
for (long idx = 1; idx <= size; idx++) {
  Vertex v = graphTS.addVertex(idx + lMaxVertexID);
  v.setProperty("name", "v_" + (idx + lMaxVertexID));
  Edge e = graphTS.addEdge(idx + lMaxEdgeID, v, graphTS.getVertex(idx), "edge_" + (idx + lMaxEdgeID));
}
graphTS.commit();

// User userP with a lower level only sees the original vertices and edges, user userTS can see more
System.out.println("Vertices with user userP and PUBLIC LABEL: " + graphPub.countVertices()); // 78
System.out.println("Vertices with user userP and PUBLIC LABEL: " + graphPub.countEdges());  // 164
System.out.println("Vertices with user userTS and SENSITIVE LABEL: " + graphTS.countVertices()); // 88
System.out.println("Vertices with user userTS and SENSITIVE LABEL: " + graphTS.countEdges());  // 174

// Third user with a higher level 
Oracle connTS2 = new Oracle("jdbc:oracle:thin:@host:port:SID", "userTS2", "userTS2pass");
OraclePropertyGraph graphTS2 = OraclePropertyGraph.getInstance(connTS2, "USERP", graphName, 8, 48, null, null);
System.out.println("Vertices with user userTS2 and SENSITIVE LABEL: " + graphTS2.countVertices()); // 88
System.out.println("Vertices with user userTS2 and SENSITIVE LABEL: " + graphTS2.countEdges());  // 174

// Fourth user with a intermediate level 
Oracle connS = new Oracle("jdbc:oracle:thin:@host:port:SID", "userS", "userSpass");
OraclePropertyGraph graphS = OraclePropertyGraph.getInstance(connS, "USERP", graphName, 8, 48, null, null);
System.out.println("Vertices with user userS and CONFIDENTIAL LABEL: " + graphS.countVertices()); // 78
System.out.println("Vertices with user userS and CONFIDENTIAL LABEL: " + graphS.countEdges());  // 164
   
// Modify vertices with the fourth user
System.out.println("\nModify " + size + " vertices with user userS and CONFIDENTIAL LABEL\n");
for (long idx = 1; idx <= size; idx++) {
  Vertex v = graphS.getVertex(idx);
  v.setProperty("security_label", "CONFIDENTIAL");
}
graphS.commit();

// User userP with a lower level that userS cannot see the new vertices
// Users userS and userTS can see them
System.out.println("Vertices with user userP with property security_label: " + OraclePropertyGraphUtils.size(graphPub.getVertices("security_label", "CONFIDENTIAL"))); // 0
System.out.println("Vertices with user userS with property security_label: " + OraclePropertyGraphUtils.size(graphS.getVertices("security_label", "CONFIDENTIAL"))); // 10
System.out.println("Vertices with user userTS with property security_label: " + OraclePropertyGraphUtils.size(graphTS.getVertices("security_label", "CONFIDENTIAL"))); // 10
System.out.println("Vertices with user userP and PUBLIC LABEL: " + graphPub.countVertices()); // 68
System.out.println("Vertices with user userTS and SENSITIVE LABEL: " + graphTS.countVertices()); // 88

The preceding example should produce the following output.

Vertices with user userP and PUBLIC LABEL: 78
Vertices with user userP and PUBLIC LABEL: 164
Vertices with user userTS and SENSITIVE LABEL: 78
Vertices with user userTS and SENSITIVE LABEL: 164

Add 10 vertices and edges with user userTS and SENSITIVE LABEL

Vertices with user userP and PUBLIC LABEL: 78
Vertices with user userP and PUBLIC LABEL: 164
Vertices with user userTS and SENSITIVE LABEL: 88
Vertices with user userTS and SENSITIVE LABEL: 174
Vertices with user userTS2 and SENSITIVE LABEL: 88
Vertices with user userTS2 and SENSITIVE LABEL: 174
Vertices with user userS and CONFIDENTIAL LABEL: 78
Vertices with user userS and CONFIDENTIAL LABEL: 164

Modify 10 vertices with user userS and CONFIDENTIAL LABEL

Vertices with user userP with property security_label: 0
Vertices with user userS with property security_label: 10
Vertices with user userTS with property security_label: 10
Vertices with user userP and PUBLIC LABEL: 68
Vertices with user userTS and SENSITIVE LABEL: 88