6.1 トリプルレベル・セキュリティ
トリプルレベル・セキュリティ・オプションでは、ラベル・セキュリティのOracle AI Databaseネイティブ・サポートの上に、RDF固有の機能の薄いレイヤーが実現されます。
トリプルレベル・セキュリティを使用するには、SEM_RDFSA.APPLY_OLS_POLICYプロシージャの実行時に、rdfsa_optionsパラメータ値としてSEM_RDFSA.TRIPLE_LEVEL_ONLYを指定します。たとえば、次のようにします。
EXECUTE sem_rdfsa.apply_ols_policy('defense', SEM_RDFSA.TRIPLE_LEVEL_ONLY, network_owner=>'RDFOWNR', network_name=>'OLS_NET');SEM_RDFSA.APPLY_OLS_POLICYプロシージャには、他の使用可能なパラメータを指定しないでください。
トリプルレベル・セキュリティを使用する場合、ネットワークの各RDFグラフにはOLSが適用されます。つまり、ラベル・セキュリティが、関連する内部表に適用されます。
トリプルレベル・セキュリティでは、異なるラベルを持つ重複トリプルをRDFグラフに挿入できます。たとえば、次のように非常に機密性の高いラベルを持つトリプルがあるとします。
(<urn:X>,<urn:P>,<urn:Y>, "TOPSECRET")
この場合でも、権限の低い(UNCLASSIFIED)ユーザーがトリプル(<urn:X>,<urn:P>,<urn:Y>, "UNCLASSIFIED")を挿入することができます。SPARQLおよびSEM_MATCHはラベル情報を戻さないため、問合せでは両方の行が戻され(ユーザーが適切な権限を持つことが前提)、TOPSECRETトリプルとUNCLASSIFIEDトリプルを区別することは簡単ではなくなります。
RDFグラフを問い合せる際にこのようにセキュリティの低いトリプルをフィルタを使用して除外するには、SEM_MATCHで次のオプションを1つ以上使用します:
-
POLICY_NAME: OLSポリシー名を指定します。 -
MIN_LABEL: 問合せに含めるトリプルの最小限のラベルを指定します。
つまり、MIN_LABELよりも厳密に優位性が下のラベルを含むトリプルはすべて、問合せに含められません。たとえば、UNCLASSIFIEDトリプルをフィルタで除外する場合は、次の問合せを使用できます(OLSポリシー名がDEFENSEであり、問合せユーザーがUNCLASSIFIEDトリプルおよびTOPSECRETトリプルに対する読取り権限を持っていることが前提です):
SELECT s,p,y FROM table(sem_match('{?s ?p ?y}' ,
sem_models(TEST'), null, null, null, null,
'MIN_LABEL=TOPSECRET POLICY_NAME=DEFENSE',
null, null, ‘FGAC_ADMIN’, 'OLS_NET'));
前述の例のフィルタ処理は、ネイティブOLSソフトウェアによって実行されるセキュリティ・チェックに追加して発生します。
トリプルが挿入された後に、RDFグラフのアプリケーション表のCTXT1列を使用してラベル情報を表示および更新できます(ラベルを変更するためのWRITEUPおよびWRITEDOWN権限を持っていることが前提です)。
トリプルレベル・セキュリティで推論またはバルク・ロードを実行できるユーザーの制限はなく、推論またはバルク・ロードされたトリプルは、すべてユーザーのセッション行ラベルで挿入されます。SA_UTLパッケージを使用してセッション・ラベルを変更できることに注意してください。(SA_UTLの詳細は、Oracle Label Security管理者ガイドを参照してください。)
6.1.1 推論データとラダーベース推論(LBI)のファイングレイン・セキュリティ
トリプルレベル・セキュリティをOracle AI Databaseに格納されたRDFデータに対してオンにすると、表明されたファクトに、必須アクセス制御を実施するためのデータ・ラベルがタグ付けされます。また、ユーザーがSEM_APIS.CREATE_INFERRED_GRAPHプロシージャを使用して前方向チェーン・ベースの推論関数を起動すると、新しく推論された関係には現在の行ラベル(SA_UTL.NUMERIC_ROW_LABEL)がタグ付けされます。
これらの新しく推論される関係は、ユーザーがアクセスを許可されている情報のみに基づいて導出されます。ただし、これらの関係では同じデータ・ラベルが共有されます。このことは、SEM_APIS.CREATE_INFERRED_GRAPHコールが、読取り操作、論理推論計算および書込み操作の3つのステップで実行されることからわかります。読取り操作では推論計算のベースとなる情報が収集されますが、これはアクセス権限、ユーザーのラベルおよびデータ・ラベルによって制限されます。論理的推論計算のステップは完全に数学的です。伴意グラフへの推論情報の最終的な書込みは、前のステップで計算されるいくつかの新しいファクトを表明している同じユーザーと同様に行われます。
ユーザーが単一のラベルのみを所有する場合は、すべての推論された表明に単一のラベルをタグ付けすることで十分です。ユーザーが複数のラベルを持つ場合には、1つのラベルのタグ付けでは不十分です。マルチテナント状態でセットアップを行った場合によく見られる状況です。
たとえば、ユーザー・ラベルとデータ・ラベルをTopSecretと設定したユーザーが、SEM_APIS.CREATE_INFERRED_GRAPHを呼び出して、Secretという弱い方のラベルに切り替えてからSPARQL問合せを実行したと仮定します。すべての新しく推論された関係はTopSecretラベルにタグ付けされているため、この問合せを参照することはできません。ただし、ユーザーがTopSecretラベルに切り替えて戻した場合、すべての推論された関係が参照可能になります。推論された関係に関するかぎり、これは「すべてまたはゼロ」の処理です(つまり、すべて参照可能またはすべて参照不可です)。
指定ユーザーが複数のラベルを使用できる場合は、通常、異なる推論された関係に異なるラベルを割り当てます。この目的を実現する方法は2つあります。
この2つの方法のうち、ラダーベース推論(Oracle Database 12cリリース1 (12.1)で有効)の方がより単純で便利です。
SEM_APIS.CREATE_INFERRED_GRAPHの複数回の起動
DEFENSEという名前のセキュリティ・ポリシー、SCOTTという名前のユーザー、およびSCOTTが所有する一連のユーザー・ラベルLabel1、Label2、...、nがあるとします。SCOTTによる次のコールは、ラベルをLabel1として設定し、1回目の推論を実行して、新しく推論されたトリプルにLabel1をタグ付けします。
EXECUTE sa_utl.set_label('defense',char_to_label('defense','Label1'));
EXECUTE sa_utl.set_row_label('defense',char_to_label('defense','Label1'));
EXECUTE sem_apis.create_inferred_graph('inf', sem_models('contracts'), sem_rulebases('owlprime'), SEM_APIS.REACH_CLOSURE, null,'',network_owner=>'RDFOWNR',network_name=>'OLS_NET');
ここで、SCOTTはラベルをLabel2に切り替え、2回目の推論を実行し、新しく推論されたトリプルにLabel2をタグ付けします。明らかに、Label1がLabel2よりも優位である場合、Label2はLabel1が参照可能な内容以外を参照することはできないため、新しいトリプルは推論されません。Label1がLabel2よりも優位ではない場合、推論プロセスの読取りステップでは、異なるトリプル・セットを参照する可能性があるため、推論コールはいくつかの新しいトリプルを生成できます(それはLabel2がタグ付けされます)。
この例の目的上、1 <= i < j <= nという条件がtrueであること(LabeliがLabeljよりも優位ではないこと)を前提としています。
EXECUTE sa_utl.set_label('defense',char_to_label('defense','Label2'));
EXECUTE sa_utl.set_row_label('defense',char_to_label('defense','Label2'));
EXECUTE sem_apis.create_inferred_graph('inf', sem_models('contracts'), sem_rulebases('owlprime'), SEM_APIS.REACH_CLOSURE, null, 'ENTAIL_ANYWAY=T', network_owner=>'RDFOWNR', network_name=>'OLS_NET');
SCOTTは、前のアクションを、Label1、Label2、...、Labelnというラベル順序の残りのラベルで続行します。最後のステップは次のとおりです。
EXECUTE sa_utl.set_label('defense',char_to_label('defense','Labeln'));
EXECUTE sa_utl.set_row_label('defense',char_to_label('defense','Labeln'));
EXECUTE sem_apis.create_inferred_graph('inf', sem_models('contracts'), sem_rulebases('owlprime'), SEM_APIS.REACH_CLOSURE, null, 'ENTAIL_ANYWAY=T', network_owner=>'RDFOWNR', network_name=>'OLS_NET');
これらのすべてのアクションを実行すると、推論グラフは様々なラベルがタグ付けされたトリプルで構成される可能性があります。
ラダーベース推論(LBI)の使用
基本的に、1つのAPI内のラダーベース参照(LBI)ラップは、「SEM_APIS.CREATE_INFERRED_GRAPHの複数回の実行」で説明されているすべてのアクションをコールします。視覚的に、これらのアクションは、はしごを登る様子と似ています。あるラベルから次のラベルに進むと、より多くの表明されたファクトが参照可能またはアクセス可能になるため(前のラベルすべてが新しいラベルよりも優位ではない場合)、新しい関係を推論できます。
次の例に、LBIを起動する構文を示します。
EXECUTE sem_apis.create_inferred_graph('inf',
sem_models('contracts'),
sem_rulebases('owlprime'),
SEM_APIS.REACH_CLOSURE,
null,
null,
ols_ladder_inf_lbl_seq=>'numericLabel1 numericLabel2 numericLabel3 numericLabel4',
network_owner=>'RDFOWNR',
network_name=>'OLS_NET'
);
パラメータols_ladder_inf_lbl_seqでは、ラベル順序が指定されます。この順序は、数値ラベルのスペース区切りリストとして提供されます。LBIを使用する場合は、弱い方のラベルが強い方のラベルより前に配置されるように、ラベル順序を配置することをお薦めします。これは、推論されたグラフのサイズを減らすことになります。(ラベルが互いに優位ではない場合、それらはどのような順序でも指定できます。)
親トピック: トリプルレベル・セキュリティ
6.1.2 拡張例: 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_LEVEL_ONLY)を適用します。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_LEVEL_ONLY,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 1 row 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> 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 from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- urn:john urn:mary urn:spouseOf 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 '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 from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- jasmin#*!@ urn:john urn:mary urn:secretId urn:spouseOf 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 the triple 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 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 jasmin#*!@ 1000 john spouseOf mary 1000 3 rows selected. SQL> select value_name from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- jasmin#*!@ urn:childOf urn:john urn:mary urn:parentOf urn:secretId urn:spouseOf 7 rows selected. SQL> SQL> conn b/<password_for_b> Connected. SQL> -- 5) use default label ('SE::' or 1500) for triple SQL> INSERT INTO rdfownr.NET1#RDFT_PERSON(triple) values (sdo_rdf_triple_s('person', 2 '<urn:spouseOf>','rdf:type','owl:SymmetricProperty', 3 '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 jasmin#*!@ 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 4 rows selected. SQL> select value_name from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- jasmin#*!@ urn:childOf urn:john urn:mary urn:parentOf urn:secretId urn:spouseOf 7 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 from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- jasmin#*!@ urn:bob urn:childOf urn:john urn:mary urn:parentOf urn:secretId urn:spouseOf 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 from rdfownr.values_view order by 1; VALUE_NAME ----------------------------------------------------------------- 1 jasmin#*!@ true urn:bob urn:childOf urn:john urn:mary urn:parentOf urn:secretId urn:spouseOf 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 jasmin#*!@ 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 jasmin#*!@ 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 jasmin#*!@ 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 jasmin#*!@ 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) 1 row 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 jasmin#*!@ 1000 john spouseOf mary 1000, 1500 spouseOf type SymmetricProperty 1500 6 rows selected. SQL> select value_name from rdfownr.values_view group by value_name order by 1; VALUE_NAME ----------------------------------------------------------------- 1 100K Smith jasmin#*!@ true urn:bob urn:childOf urn:john urn:lastName urn:mary urn:parentOf urn:salary urn:secretId urn:spouseOf 14 rows selected.
親トピック: トリプルレベル・セキュリティ