6.2 トリプルと値のセキュリティ
トリプルと値のセキュリティ・オプションでは、トリプルレベルのセキュリティ・オプションで提供されるラベル・セキュリティのサポートが拡張されて、字句値のセキュリティも包含されています。
このセキュリティ・オプションによって、Oracle AI Databaseによるラベル・セキュリティのネイティブ・サポートの上に、RDF固有の機能の薄いレイヤーが実現されます。トリプルレベル・オプションでサポートされている機能だけでなく、RDFの字句値を一意の数値識別子にマッピングするために使用する内部(values)表にラベル・セキュリティを適用する追加機能もサポートされています。
トリプルと値セキュリティを使用するには、SEM_RDFSA.APPLY_OLS_POLICYプロシージャの実行時に、rdfsa_optionsパラメータ値としてSEM_RDFSA.TRIPLE_AND_VALUESを指定します。たとえば、次のようにします。
EXECUTE sem_rdfsa.apply_ols_policy('defense', SEM_RDFSA.TRIPLE_AND_VALUES,
network_owner=>‘RDFOWNR’, network_name=>'OLS_NET');ラベル・セキュリティをRDFトリプルに関連付けるメソッドは、トリプルレベル・セキュリティの項で説明したメソッドと同じであるため、RDFトリプルの(主語、述語、オブジェクト、およびオプションの名前付きグラフ)コンポーネントの字句値にラベル・セキュリティを関連付けるメソッドの概要のみを説明します。
トリプルの個々のコンポーネントに付けるラベルは、互いに独立したもの、およびそのトリプルに付けたラベルとは独立したものにできます。したがって、1つのトリプルに最大5つの異なるラベル(トリプルの個々のコンポーネントに最大4つのラベル、トリプル自体に1つのラベル)を付けることができます。
トリプルと値のセキュリティでは、ラベルが異なる、重複した字句値をvalues表に挿入できます。たとえば、字句値(<urn:Y>など)が、非常に機密性の高いラベル(TOPSECRET)で格納されているとします。ここで、権限が低い(UNCLASSIFIED)ユーザーが次のトリプルを挿入するとします:
<urn:X> <urn:P> <urn:Y> .TOPSECRETの<urn:Y>という字句の値はすでに格納されていますが、権限が低いユーザーには表示されないため、今回はUNCLASSIFIEDのラベルが付いた<urn:Y>が再度格納されます。TOPSECRETのラベルを付けた権限の高いユーザーによる後続の問合せでは、<urn:Y>という字句値の両方のインスタンスが表示されるため、<urn:Y>という字句値の2つのインスタンスが存在することになり、重複した結果行が返されます。字句値の重複に関連する問題を軽減する方法をいくつか次に示します:
- 重複する字句値の発生の防止または最小化: トリプルを挿入する際に、様々な権限レベルのユーザーが使用すると予想される字句値には最下位のラベルを関連付けます。
- 問合せ結果からの重複した結果行の排除: 問合せのSELECT句でDISTINCTを使用すると、重複した結果を排除できます。こうすると、重複した字句値の存在に起因していない可能性がある行も含めて、すべての重複した結果行が排除されることに注意してください。
6.2.1 拡張例: RDFデータへのOLSのトリプルと値のセキュリティの適用
この項では、トリプルと値のOracle Label Security (OLS)をRDFデータに適用する方法を説明する拡張例を示します。この例は非常に単純化されており、推奨のプラクティスで使用しているユーザー名およびパスワードをそのまま使用しないでください。
- ポリシーおよび関連する管理ユーザーを作成します。
このステップのコード例は、同じ順序またはわずかに異なる順序で次のアクションを実行します:
- データベースでOLSを有効にします。
SYSDBAとして接続し、セキュリティ管理ユーザーfgac_adminおよびdefense_adminを作成します。LBAC_DBAロールをfgac_adminに付与して、DEFENSE_DBAロールを作成する新しいOLSDEFENSEポリシーを作成できるようにします。DEFENSE_DBAロールをdefense_adminに付与して、ユーザーがDEFENSEポリシーにラベルを設定できるようにします。DEFENSEポリシーが適用される可能性があるデータベース・オブジェクトの対象ユーザーに適切なラベルを割り当てます。
SQL> conn sys/<password_for_sys> as sysdba Connected. SQL> -- enable OLS in the database SQL> exec LBACSYS.configure_ols; PL/SQL procedure successfully completed. SQL> exec LBACSYS.OLS_ENFORCEMENT.enable_ols; PL/SQL procedure successfully completed. SQL> SQL> -- create user for security admin, grant LBAC_DBA role SQL> create user fgac_admin identified by <password_for_fgac_admin>; User created. SQL> grant connect, unlimited tablespace to fgac_admin; Grant succeeded. SQL> grant LBAC_DBA to fgac_admin; Grant succeeded. SQL> grant execute on sa_sysdba to fgac_admin; Grant succeeded. SQL> SQL> conn fgac_admin/<password_for_fgac_admin> Connected. SQL> -- create policy DEFENSE, which creates the DEFENSE_DBA role SQL> EXECUTE SA_SYSDBA.CREATE_POLICY('DEFENSE','def_label'); PL/SQL procedure successfully completed. SQL> select column_name from lbacsys.all_sa_policies where policy_name='DEFENSE'; COLUMN_NAME --------------- DEF_LABEL 1 row selected. SQL> SQL> conn sys/<password_for_sys> Connected. SQL> -- create user for policy admin of the DEFENSE policy SQL> -- create policy admin user for the DEFENSE policy (created above) SQL> create user defense_admin identified by <password_for_defense_admin>; User created. SQL> grant connect, unlimited tablespace to defense_admin; Grant succeeded. SQL> grant DEFENSE_DBA to defense_admin; Grant succeeded. SQL> grant execute on sa_components to defense_admin; Grant succeeded. SQL> grant execute on sa_user_admin to defense_admin; Grant succeeded. SQL> grant execute on sa_label_admin to defense_admin; Grant succeeded. SQL> grant execute on sa_policy_admin to defense_admin; Grant succeeded. SQL> SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> SQL> BEGIN 2 ------- create levels ------- 3 SA_COMPONENTS.CREATE_LEVEL('defense',3000,'TS','TOP SECRET'); 4 SA_COMPONENTS.CREATE_LEVEL('defense',2000,'SE','SECRET'); 5 SA_COMPONENTS.CREATE_LEVEL('defense',1000,'UN','UNCLASSIFIED'); 6 7 ------ create labels (using the components defined above) ------- 8 SA_LABEL_ADMIN.CREATE_LABEL('defense',1000,'UN'); 9 SA_LABEL_ADMIN.CREATE_LABEL('defense',1500,'SE'); 10 SA_LABEL_ADMIN.CREATE_LABEL('defense',3100,'TS'); 11 12 ------ assign default labels to users ------- 13 SA_USER_ADMIN.SET_USER_LABELS('defense', 'RDFOWNR', 'SE'); 14 SA_USER_ADMIN.SET_USER_LABELS('defense', 'A', 'UN'); 15 SA_USER_ADMIN.SET_USER_LABELS('defense', 'B', 'SE'); 16 SA_USER_ADMIN.SET_USER_LABELS('defense', 'C', 'TS'); 17 SA_USER_ADMIN.SET_USER_LABELS('defense', 'Q', 'SE'); 18 END; 19 / PL/SQL procedure successfully completed. - RDFネットワーク、RDFグラフを作成し、様々なモードでユーザーと共有します。
このステップのコード例は、同じ順序またはわずかに異なる順序で次のアクションを実行します:
SYSDBAとして接続し、rdfownrユーザー、およびa、b、c、qなど、他の複数のユーザーを作成します。rdfownrとして接続し、NET1RDFネットワークを作成します。- RDFネットワーク上の共有アクセス権を
a、b、cおよびq(問合せ専用)ユーザーに付与します。 - RDFネットワーク上の
SA_ONLYアクセス権をdefense_adminユーザーに付与して、このネットワーク上でのみOLSのセキュリティ関連の操作を実行できるようにします。こうしても、RDFネットワークに格納されているデータへのアクセス権は付与されません。 defense_adminとして接続し、RDFネットワークにDEFENSEOLSポリシー(TRIPLE_AND_VALUES)を適用します。rdfownrとして接続して、PERSONという名前のRDFグラフを作成し、グラフに関するDMLおよび問合せアクセス権をユーザーa、b、cに付与し、問合せ専用アクセス権をユーザーqに付与します。
SQL> conn sys/<password_for_sys> Connected. SQL> -- create user that can be owner of RDF networks SQL> create user rdfownr identified by <password_for_rdfownr>; User created. SQL> grant CREATE JOB, connect, resource, unlimited tablespace to rdfownr; Grant succeeded. SQL> SQL> --- create general users SQL> create user a identified by <password_for_a>; User created. SQL> grant connect, unlimited tablespace to a; Grant succeeded. SQL> create user b identified by <password_for_b>; User created. SQL> grant connect, unlimited tablespace to b; Grant succeeded. SQL> create user c identified by <password_for_c>; User created. SQL> grant connect, unlimited tablespace to c; Grant succeeded. SQL> create user q identified by <password_for_q>; User created. SQL> grant connect, unlimited tablespace to q; Grant succeeded. SQL> SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> SQL> -- create an RDF network and enable it for sharing with other users SQL> exec sem_apis.create_rdf_network('<tablespace_name>',null,network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> exec sem_apis.enable_network_sharing(network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> -- grant network access to a few users: full-access (they can create their own graphs) or query-only access SQL> EXECUTE sem_apis.enable_network_sharing('RDFOWNR', 'NET1'); PL/SQL procedure successfully completed. SQL> BEGIN 2 sem_apis.grant_network_access_privs('RDFOWNR', 'NET1', 'A'); 3 sem_apis.grant_network_access_privs('RDFOWNR', 'NET1', 'B'); 4 sem_apis.grant_network_access_privs('RDFOWNR', 'NET1', 'C'); 5 sem_apis.grant_network_access_privs('RDFOWNR', 'NET1', 'Q', options=>' QUERY_ONLY=T '); 6 END; 7 / PL/SQL procedure successfully completed. SQL> SQL> -- share in SA_ONLY=T mode with policy admin user (note: this sharing mode provides no visibility to RDF data) SQL> exec sem_apis.grant_network_access_privs('rdfownr', 'NET1', 'DEFENSE_ADMIN', options=>' SA_ONLY=T '); PL/SQL procedure successfully completed. SQL> SQL> -- tables in RDF network are not visible to security and policy admin users (EXCEPT when managing security policies on them) SQL> conn fgac_admin/<password_for_fgac_admin> Connected. SQL> select table_name from SYS.all_tables where table_name LIKE 'NET1#RDF%' order by 1; no rows selected SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> select table_name from SYS.all_tables where table_name LIKE 'NET1#RDF%' order by 1; no rows selected SQL> SQL> -- APPLY_OLS_POLICY on the RDF network SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> exec sem_rdfsa.apply_ols_policy('DEFENSE', sem_rdfsa.TRIPLE_AND_VALUES,network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> -- after APPLY_OLS_POLICY: a new column gets added to RDF_VALUE$ table and to RDF_LINK$ table SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> select table_name, column_name, data_type from sys.user_tab_columns where table_name IN ('NET1#RDF_VALUE$', 'NET1#RDF_LINK$') and column_name='DEF_LABEL' order by 1; TABLE_NAME COLUMN_NAME DATA_TYPE ------------------------------ --------------- ---------- NET1#RDF_LINK$ DEF_LABEL NUMBER NET1#RDF_VALUE$ DEF_LABEL NUMBER 2 rows selected. SQL> SQL> -- disable the OLS policy and set the label for all the pre-existing values to the lowest label SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> exec sem_rdfsa.disable_ols_policy(network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> -- re-enable the OLS policy and verify that the values are visible to all (EXCEPT security and policy admin users) SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> exec sem_rdfsa.enable_ols_policy(network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> -- create an RDF graph (owned by rdfownr) SQL> exec sem_apis.create_rdf_graph('PERSON',null,null,network_owner=>'rdfownr',network_name=>'NET1'); PL/SQL procedure successfully completed. SQL> -- the corr. RDFT view, used as target for DML operations for this graph, has the extra label column SQL> desc NET1#RDFT_PERSON Name Null? Type ----------------------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------------------- TRIPLE MDSYS.SDO_RDF_TRIPLE_S DEF_LABEL NUMBER SQL> -- the corr. RDFM view, used as source for query processing for this graph, has the extra column SQL> desc NET1#RDFM_PERSON Name Null? Type ----------------------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------------------- P_VALUE_ID NOT NULL NUMBER START_NODE_ID NUMBER CANON_END_NODE_ID NUMBER END_NODE_ID NUMBER MODEL_ID NUMBER COST NUMBER DEF_LABEL NUMBER CTXT2 VARCHAR2(4000) DISTANCE NUMBER EXPLAIN VARCHAR2(4000) PATH VARCHAR2(4000) G_ID NUMBER LINK_ID VARCHAR2(89) SQL> SQL> -- share access to the above graph with users who already have shared access to network (Note: user Q is given query-only access) SQL> BEGIN 2 sem_apis.grant_model_access_privs('PERSON','a',sys.odcivarchar2list('INSERT','UPDATE','DELETE','SELECT','QUERY'),network_owner=>'rdfownr',network_name=>'NET1'); 3 sem_apis.grant_model_access_privs('PERSON','b',sys.odcivarchar2list('INSERT','UPDATE','DELETE','SELECT','QUERY'),network_owner=>'rdfownr',network_name=>'NET1'); 4 sem_apis.grant_model_access_privs('PERSON','c',sys.odcivarchar2list('INSERT','UPDATE','DELETE','SELECT','QUERY'),network_owner=>'rdfownr',network_name=>'NET1'); 5 sem_apis.grant_model_access_privs('PERSON','q',sys.odcivarchar2list('QUERY'),network_owner=>'rdfownr',network_name=>'NET1'); 6 END; 7 / PL/SQL procedure successfully completed. - 例に使用するユーティリティ関数とビューを設定します。
次のコードで、ユーティリティ・ビュー
TRIPLES_VIEWおよびVALUES_VIEWを作成します。これらは、ユーザーが表示できるトリプルと値の簡易ビューを、関連するOLSのラベルとともに返します。特定のidの値が見つからない場合は、id自体が返されますが、先頭にアスタリスクが付きます。SQL> -- set up for reporting visibility of triples and values SQL> column visible_to_users format a30 SQL> column subj format a22 SQL> column pred format a22 SQL> column obj format a22 SQL> column labels format a30 SQL> -- SQL> create or replace function shortval (val_id number) return varchar2 as 2 shval varchar2(100); 3 begin 4 select NVL(vname_suffix, vname_prefix) into shval from rdfownr.net1#rdf_value$ where value_id = val_id and rownum < 2; 5 return substr(shval,1,20); 6 exception 7 when no_data_found then 8 return '*' || val_id; 9 end; 10 / Function created. SQL> grant execute on shortval to public; Grant succeeded. SQL> create or replace view triples_view as 2 select rdfownr.shortval(t.triple.rdf_s_id) subj, rdfownr.shortval(t.triple.rdf_p_id) pred, rdfownr.shortval(t.triple.rdf_c_id) obj, def_label 3 from rdfownr.NET1#RDFT_PERSON t; View created. SQL> grant read on triples_view to public; Grant succeeded. SQL> create or replace view values_view as 2 select value_id, value_name 3 from rdfownr.net1#rdf_value$ 4 where (value_name NOT LIKE '%rdf%' and value_name NOT LIKE '%owl%' and canon_id is NULL); View created. SQL> grant read on values_view to public; Grant succeeded. - RDFグラフに対してSQLのinsertを使用する際には、ファイングレイン・アクセス制御(FGAC)を設定します。
ユーザーに割り当てられたラベルによって、ユーザーが挿入したデータに関連付けることができるラベルが決まります。これは、ユーザーに割り当てられたラベル、またはユーザーのラベルよりも優位性が下の任意のラベルになります。また、割り当てられたラベルによって、このような表のどのデータがユーザーに表示されるかが決まります。
SQL> -- SQL> -- INSERT using SQL Insert statement SQL> -- SQL> SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> SQL> -- 1) use default label, which is 'SE::' or 1500 for rdfownr, for the triple as well as the values SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:john>','<urn:spouseOf>','<urn:mary>', 3 'rdfownr','NET1')); 1 row created. SQL> COMMIT; Commit complete. SQL> SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ john spouseOf mary 1500 1 row selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ urn:john 1500 urn:mary 1500 urn:spouseOf 1500 3 rows selected. SQL> SQL> conn c/<password_for_c> Connected. SQL> -- 2) use default explicit label 'UN::' (1000) for the triple SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple, def_label) values (sdo_rdf_triple_s('person', 2 '<urn:john>','<urn:secretId>','"jasmin#*!@"', 3 sys.odcinumberlist(char_to_label('DEFENSE', 'UN::'), char_to_label('DEFENSE', 'UN::'), char_to_label('DEFENSE', 'TS::')), 4 'rdfownr','NET1'), char_to_label('DEFENSE', 'UN::')); 1 row created. SQL> COMMIT; Commit complete. SQL> SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ john secretId jasmin#*!@ 1000 john spouseOf mary 1500 2 rows selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ jasmin#*!@ 3100 urn:john 1500 urn:mary 1500 urn:secretId 1000 urn:spouseOf 1500 5 rows selected. SQL> SQL> conn a/<password_for_a>1 Connected. SQL> -- 3) use default label, which is 'UN::' or 1000 for user A, for both the triple as well as the values SQL> -- this triple already exists, but with a higher label (1500) and hence not visible to the current user: so, a duplicate triple gets inserted SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:john>','<urn:spouseOf>','<urn:mary>', 3 'rdfownr','NET1')); 1 row created. SQL> SQL> -- 4) use default label ('UN::' or 1000) for the triple and all its values SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:childOf>','owl:inverseOf','<urn:parentOf>', 3 'rdfownr','NET1')); 1 row created. SQL> COMMIT; Commit complete. SQL> SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000 3 rows selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ urn:childOf 1000 urn:john 1000 urn:mary 1000 urn:parentOf 1000 urn:secretId 1000 urn:spouseOf 1000 6 rows selected. SQL> SQL> conn b/<password_for_b> Connected. SQL> -- 5) use default label ('SE::' or 1500) for triple, but lowest label ('UN' or 1000) for values SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:spouseOf>','rdf:type','owl:SymmetricProperty', 3 sys.odcinumberlist(char_to_label('DEFENSE', 'UN::'), char_to_label('DEFENSE', 'UN::'), char_to_label('DEFENSE', 'UN::')), 4 'rdfownr','NET1')); 1 row created. SQL> SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 4 rows selected.. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ urn:childOf 1000 urn:john 1000, 1500 urn:mary 1000, 1500 urn:parentOf 1000 urn:secretId 1000 urn:spouseOf 1000, 1500 6 rows selected. SQL> SQL> conn c/<password_for_c> Connected. SQL> -- 6) use default label ('TS::' or 3100) for the triple SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:john>','<urn:childOf>','<urn:bob>', 3 'rdfownr','NET1')); 1 row created. SQL> COMMIT; Commit complete. SQL> SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john childOf bob 3100 john secretId jasmin#*!@ 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 5 rows selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ jasmin#*!@ 3100 urn:bob 3100 urn:childOf 1000 urn:john 1000, 1500 urn:mary 1000, 1500 urn:parentOf 1000 urn:secretId 1000 urn:spouseOf 1000, 1500 8 rows selected. - 指定されたラベル・シーケンスに対して繰り返し反復処理を実行することにより、ラベルベースの推論を実行します。
次のコードは、ラベル・シーケンス
<1000, 1500, 3100>のラベルベースの推論を示しています。導出されたトリプルは、それなしでは導出できない最初期の(minimum)ラベルでマークされます。たとえば、導出されたトリプルbob parentOf johnには3100 ('TS::')というラベルが付きます。これは、ユーザーに少なくとも3100のラベルがある場合にのみjohn childOf bobが表示されるため、3100より下位のラベルでは導出できないからです。SQL> conn sys/<password_for_sys> as sysdba Connected. SQL> -- allow "exchange partition" operations used during inference SQL> grant EXEMPT ACCESS POLICY on schema rdfownr to rdfownr; Grant succeeded. SQL> conn c/<password_for_c> Connected. SQL> BEGIN 2 sem_apis.create_inferred_graph('inf', 3 sem_models('PERSON'), 4 sem_rulebases('OWL2RL'), 5 SEM_APIS.REACH_CLOSURE, 6 null, 7 null, 8 ols_ladder_inf_lbl_seq=>'1000 1500 3100', 9 network_owner=>'RDFOWNR', 10 network_name=>'NET1' 11 ); 12 END; 13 / PL/SQL procedure successfully completed. SQL> conn sys/<password_for_sys> as sysdba Connected. SQL> -- "exchange partition" operations not needed any more SQL> revoke EXEMPT ACCESS POLICY on schema rdfownr from rdfownr; Revoke succeeded. SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> create or replace view inf_triples_view as 2 select rdfownr.shortval(t.start_node_id) subj, rdfownr.shortval(t.p_value_id) pred, rdfownr.shortval(canon_end_node_id) obj, def_label 3 from rdfownr.NET1#RDFI_INF t; View created. SQL> grant read on inf_triples_view to public; Grant succeeded. SQL> conn c/<password_for_c> Connected. SQL> -- check labels for the visible triples and values SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ bob parentOf john 3100 mary spouseOf john 1500 parentOf inverseOf childOf 1000 spouseOf inverseOf spouseOf 1500 4 rows selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ 1 3100 jasmin#*!@ 3100 true 3100 urn:bob 3100 urn:childOf 1000 urn:john 1000, 1500 urn:mary 1000, 1500 urn:parentOf 1000 urn:secretId 1000 urn:spouseOf 1000, 1500 10 rows selected SQL> SQL> -- visibility note: users with lower label may sometimes be able to see a triple but not the higher-labeled values used in that triple SQL> conn a/<password_for_a> Connected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000 3 rows selected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ parentOf inverseOf childOf 1000 1 row selected. SQL> conn b/<password_for_b> Connected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 4 rows selected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ mary spouseOf john 1500 parentOf inverseOf childOf 1000 spouseOf inverseOf spouseOf 1500 3 rows selected. SQL> conn c/<password_for_c> Connected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john childOf bob 3100 john secretId jasmin#*!@ 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 5 rows selected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ bob parentOf john 3100 mary spouseOf john 1500 parentOf inverseOf childOf 1000 spouseOf inverseOf spouseOf 1500 4 rows selected. SQL> conn q/<password_for_q> Connected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 4 rows selected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ mary spouseOf john 1500 parentOf inverseOf childOf 1000 spouseOf inverseOf spouseOf 1500 3 rows selected. SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john secretId *7305832552150903811 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 4 rows selected. SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.inf_triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ mary spouseOf john 1500 parentOf inverseOf childOf 1000 spouseOf inverseOf spouseOf 1500 3 rows selected. - ラベル関数を定義して使用します。
次のコードは、述語が
<urn:salary>の場合に上位ラベル('SE::')をトリプルに関連付け、それ以外の場合は下位ラベル('UN::')を関連付けるラベル関数を、バルクロード時に使用する例を示しています。SQL> -- use of label functions and its use during bulk-load SQL> conn sys/<password_for_sys> Connected. SQL> grant execute on to_lbac_data_label to rdfownr; Grant succeeded. SQL> SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> SQL> CREATE TABLE stage_table ( 2 RDF$STC_sub varchar2(4000) not null, 3 RDF$STC_pred varchar2(4000) not null, 4 RDF$STC_obj varchar2(4000) not null 5 ); Table created. SQL> SQL> insert into stage_table values ('<urn:john>','<urn:lastName>','"Smith"'); 1 row created. SQL> insert into stage_table values ('<urn:john>','<urn:salary>','"100K"'); 1 row created. SQL> commit; Commit complete. SQL> SQL> -- define a label function for generating label for a given triple SQL> -- label function for generating labels for triples (in RDF_LINK$) SQL> CREATE OR REPLACE FUNCTION gen_triple_label_on_pid (p_value_id number) Return LBACSYS.LBAC_LABEL 2 as 3 i_label varchar2(80); 4 vty varchar2(10); 5 vnm varchar2(100); 6 BEGIN 7 select value_type, value_name into vty, vnm from rdfownr.net1#rdf_value$ where value_id=p_value_id; 8 if (vty = 'UR' and vnm = 'urn:salary') then 9 i_label := 'SE::'; 10 else 11 i_label := 'UN::'; 12 end if; 13 RETURN TO_LBAC_DATA_LABEL('DEFENSE',i_label); 14 END; 15 / Function created. SQL> SQL> grant execute on gen_triple_label_on_pid to LBAC_TRIGGER; Grant succeeded. SQL> SQL> -- ALTER_OLS_TABLE_POLICY to include use of label function for triples SQL> conn defense_admin/<password_for_defense_admin> Connected. SQL> exec sem_rdfsa.alter_ols_table_policy('triple', 'label_function', 'rdfownr.gen_triple_label_on_pid(:new.p_value_id)', network_owner=>'rdfownr',network_name=>'net1'); PL/SQL procedure successfully completed. SQL> select * from lbacsys.all_sa_table_policies where schema_name='RDFOWNR' order by policy_name, table_name; POLICY_NAM SCHEMA_NAME TABLE_NAME STATUS ---------- -------------------------------------------------------------------------------------------------------------------------------- ------------------------------ -------- TABLE_OPTIONS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- FUNCTION -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- PREDICATE -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DEFENSE RDFOWNR NET1#RDF_LINK$ ENABLED READ_CONTROL, INSERT_CONTROL, UPDATE_CONTROL, DELETE_CONTROL, LABEL_DEFAULT, LABEL_UPDATE, CHECK_CONTROL rdfownr.gen_triple_label_on_pid(:new.p_value_id) DEFENSE RDFOWNR NET1#RDF_VALUE$ ENABLED READ_CONTROL, INSERT_CONTROL, UPDATE_CONTROL, DELETE_CONTROL, LABEL_DEFAULT, LABEL_UPDATE, CHECK_CONTROL 2 rows selected. SQL> SQL> -- bulk-load uses designated label function to mark the salary triple as 'SE::' (1500) while marking the "lastName" triples as 'UN::' (1000) SQL> conn rdfownr/<password_for_rdfownr> Connected. SQL> exec sem_apis.bulk_load_from_staging_table('person','rdfownr','stage_table',network_owner=>'rdfownr',network_name=>'net1'); PL/SQL procedure successfully completed. SQL> SQL> select subj, pred, obj, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.triples_view group by subj, pred, obj order by 1,2,3; SUBJ PRED OBJ LABELS ---------------------- ---------------------- ---------------------- ------------------------------ childOf inverseOf parentOf 1000 john lastName Smith 1000 john salary 100K 1500 john secretId *7305832552150903811 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 6 rows selected. SQL> select value_name, listagg(def_label,', ') within group (order by def_label) labels from rdfownr.values_view group by value_name order by 1; VALUE_NAME LABELS ----------------------------------------------------------------- ------------------------------ 100K 1500 Smith 1500 urn:childOf 1000 urn:john 1000, 1500 urn:lastName 1500 urn:mary 1000, 1500 urn:parentOf 1000 urn:salary 1500 urn:secretId 1000 urn:spouseOf 1000, 1500 10 rows selected
親トピック: トリプルと値のセキュリティ