前回は、Oracle Label Security(OLS)の仕組みと、データ・ラベルとユーザー側の認可情報を比較して行単位のアクセスを制御する考え方を紹介しました。

本記事では、Oracle Label Security を実際に構成してその動作を確認してみます。


0. はじめに

本記事で実施する内容は以下のとおりです。

実施内容Oracle Label Security の設定と動作確認
・OLS の構成状態の確認と有効化
・ポリシー、レベル、データ・ラベルの作成
・HR と SALES_APP へのレベル認可
HR.JOB_HISTORY_4OLS 表へのポリシー適用
・行へのデータ・ラベル設定
・接続ユーザーによる表示行の違いの確認
・作成した設定の削除
作業時間の目安環境構築済みの状態で 約 30 分
実行環境・Oracle AI Database 26ai FREE
・PDB 名: freepdb1
・HR サンプルスキーマ
・クライアントツール: SQLcl または SQL*Plus

本記事では、見やすさのために実行結果の一部を省略または整形しています。そのため、実際の出力と異なる場合があります。SQL のキーワードやオブジェクト名は、読みやすさのために大文字で記載します。

また、本手順は検証環境で Oracle Label Security の動作を理解することを目的としています。本番環境で利用する場合は、ポリシー管理者、ラベル体系、データへのラベル付与方法、アプリケーションへの影響、監査方法をあらかじめ設計してください。

なお、ここで行うデモラベルの基本動作に焦点を当てるため、ラベルの構成要素のうち必須となる「レベル」のみを使用します。


1. 環境の準備

1-1. Oracle Database とサンプルスキーマの準備

この手順では、次の環境を前提にします。

  • Oracle AI Database 26ai FREE が起動している
  • PDB 名が freepdb1 である
  • HR サンプルスキーマがインストールされ、HR.JOB_HISTORY 表に 10 行のデータがある
  • HR ユーザーのアカウントが使用可能で、パスワードがわかる
  • SYSDBA 権限を持つ管理者ユーザーで接続できる
  • SQLcl または SQL*Plus から freepdb1 に接続できる

Oracle Label Security の構成とポリシー管理には専用の管理ユーザーを使用することが推奨されます。このハンズオンでは、ローカル検証環境で手順を追いやすくするため、管理操作を SYS ユーザーで実行します。

PDB に直接接続する場合は、次のように実行します。パスワードはコマンドラインに含めず、表示されるプロンプトで入力します。

$ sql sys@localhost:1521/freepdb1 AS SYSDBA

CDB にローカル接続してから PDB に切り替える場合は、次のように実行します。

$ sql / AS SYSDBA
ALTER SESSION SET CONTAINER = freepdb1;

1-2. クライアントツールの用意

SQLcl、SQL*Plus、SQL Developer、VS Code の SQL Developer 拡張機能など、任意のツールで freepdb1 に接続できる環境を準備してください。本記事では SQLcl の形式でコマンドを記載します。

接続に必要なサービス名やリスナーの状態は、DB サーバーで次のコマンドを実行することで確認できます。

$ lsnrctl status

1-3. SALES_APP ユーザーの準備

動作確認では、HR よりも低い認可レベルを持つ SALES_APP ユーザーを使用します。未作成の場合は、SYS ユーザーで freepdb1 に接続して作成します。

CREATE USER sales_app IDENTIFIED BY "<password>";
GRANT CREATE SESSION TO sales_app;

すでに SALES_APP ユーザーが存在する場合は、作成処理を省略してください。対象表への参照権限は、表を作成したあとで付与します。


2. デモ構成の概要

このハンズオンでは、サンプルスキーマのうち HR.JOB_HISTORY 表を複製した HR.JOB_HISTORY_4OLS 表を保護します。機密度を表す 3 つのレベルを作り、JOB_ID に応じて各行へラベルを設定します。

レベル長い名前レベル番号ラベル・タグ対象となる JOB_ID意味
SENSSENSITIVE4000400AC_MGR, SA_MAN機微情報
CONFCONFIDENTIAL3000300AC_ACCOUNT, MK_REP, SA_REP機密情報
INTLINTERNAL2000200IT_PROG, ST_CLERK, AD_ASST社内情報

レベル番号が大きいほど、上位の機密レベルとして扱われます。表のラベル列には SENS などの文字列ではなく、対応する数値のラベル・タグが格納されます。

ユーザーには、次の範囲を認可します。

ユーザー最大レベル最小レベル(書き込み)期待する結果
HRSENSINTLSENSCONFINTL の全 10 行を参照できる
SALES_APPCONFINTLCONFINTL の 8 行を参照できる。SENS の 2 行は表示されない

表へ適用する制御は READ_CONTROL のみです。そのため、このハンズオンで確認するのは SELECT 時の行フィルタリングのみであり、挿入、更新、削除の制御は対象にしません。


3. 事前確認

3-1. 接続先と OLS の構成状態を確認する

SYS ユーザーで freepdb1 に接続し、現在のユーザーと接続先を確認します。

SHOW USER
SHOW CON_NAME

実行例です。

USER is "SYS"

CON_NAME
------------------------------
FREEPDB1

続いて、DBA_OLS_STATUS データ・ディクショナリ・ビューで Oracle Label Security の状態を確認します。

select * from dba_ols_status;

まだ構成していない環境では、次のように表示されます。

NAME                    STATUS    DESCRIPTION
_______________________ _________ __________________________________
OLS_CONFIGURE_STATUS    FALSE     Determines if OLS is configured
OLS_ENABLE_STATUS       FALSE     Determines if OLS is enabled

各ステータスの意味は次のとおりとなります。

  • OLS_CONFIGURE_STATUS: Oracle Label Security が PDB に登録、構成されているか
  • OLS_ENABLE_STATUS: Oracle Label Security の施行が有効になっているか

両方が TRUE の場合は、このあとの手順「4-1. OLS を構成して有効化する」を省略してください。

なお、CDB 全体の状態を確認する場合は、CDB ルートで CDB_OLS_STATUS を参照します。

select con_id, name, status from cdb_ols_status

3-2. 元データと既存オブジェクトを確認する

デモで使用する HR.JOB_HISTORY 表のデータを確認します。

select * from hr.job_history order by employee_id, start_date;

このハンズオンでは、次の 10 行を使用します。

   EMPLOYEE_ID START_DATE    END_DATE     JOB_ID           DEPARTMENT_ID
______________ _____________ ____________ _____________ ________________
           101 21-SEP-07     27-OCT-11    AC_ACCOUNT                 110
           101 28-OCT-11     15-MAR-15    AC_MGR                     110
           102 13-JAN-11     24-JUL-16    IT_PROG                     60
           114 24-MAR-16     31-DEC-17    ST_CLERK                    50
           122 01-JAN-17     31-DEC-17    ST_CLERK                    50
           176 24-MAR-16     31-DEC-16    SA_REP                      80
           176 01-JAN-17     31-DEC-17    SA_MAN                      80
           200 17-SEP-05     17-JUN-11    AD_ASST                     90
           200 01-JUL-12     31-DEC-16    AC_ACCOUNT                  90
           201 17-FEB-14     19-DEC-17    MK_REP                      20

10 rows selected.

このあと作成する、同名のデモ表やポリシーがないことも確認します。

select owner, table_name 
  from dba_tables
  where owner = 'HR' 
    and table_name = 'JOB_HISTORY_4OLS';

select policy_name, status 
  from all_sa_policies
  where policy_name = 'OLS_POL_DEMO';

次のように表示され、どちらも存在しないことを確認します。

no rows selected

すでに存在する場合は、別の名前を使用するか、手順「7. 後片付け」の手順で以前のデモ設定を削除してから進めてください。


4. Oracle Label Security の設定

4-1. OLS を構成して有効化する

DBA_OLS_STATUS の両方のステータスが TRUE であれば、この手順は省略してください

FALSE の場合は、SYS ユーザーで freepdb1 に接続した状態で次の処理を実行します。

EXEC LBACSYS.CONFIGURE_OLS;
EXEC LBACSYS.OLS_ENFORCEMENT.ENABLE_OLS;

LBACSYS.CONFIGURE_OLS を実行すると、保留中のトランザクションはコミットされ、ロールバックできませんので、実行前に同じセッションに未コミットの変更がないことを確認してください。

設定を反映するため CDB ルートへ SYSDBA として接続し直し、freepdb1 を再起動します。

connect / as sysdba

alter pluggable database freepdb1 close immediate;
alter pluggable database freepdb1 open;

再度 freepdb1 に接続し、状態を確認します。

alter session set container = freepdb1;

select * from dba_ols_status;
NAME                    STATUS    DESCRIPTION
_______________________ _________ __________________________________
OLS_CONFIGURE_STATUS    TRUE      Determines if OLS is configured
OLS_ENABLE_STATUS       TRUE      Determines if OLS is enabled

両方が TRUE になっていれば、Oracle Label Security の構成と有効化は完了です。

4-2. SYS ユーザーで管理パッケージを実行するための権限を確認する

このハンズオンでは、SYS ユーザーで OLS の管理パッケージを実行します。まず、LBAC_DBA ロールが付与されていることを確認します。

select grantee, granted_role, admin_option
  from dba_role_privs
  where grantee = 'SYS'
    and granted_role = 'LBAC_DBA';

続いて、このあと実行するSA_SYSDBAパッケージ等の実行時にエラー が発生しないよう、SYS の権限を LBACSYS が継承できるようにしておきます。

GRANT INHERIT PRIVILEGES ON USER SYS TO LBACSYS;

この付与は SYS ユーザーで OLS 管理パッケージを実行するためのものです。そのため、本番環境では SYS を日常的なポリシー管理に使用せず、専用の OLS 管理ユーザーなど用意されたユーザーへ必要なロールとパッケージの実行権限を付与するようにしてください。

4-3. OLS ポリシーを作成する

OLS_POL_DEMO ポリシーを作成します。column_name には、保護対象の表へ追加するラベル列の名前を指定します。

BEGIN
  SA_SYSDBA.CREATE_POLICY(
    policy_name => 'OLS_POL_DEMO',
    column_name => 'OLS_LABEL_DEMO'
  );
END;
/

作成したポリシーを確認します。

select * from all_sa_policies
  where policy_name = 'OLS_POL_DEMO';
POLICY_NAME     COLUMN_NAME       STATUS     POLICY_OPTIONS
_______________ _________________ __________ _________________
OLS_POL_DEMO    OLS_LABEL_DEMO    ENABLED

なお、有効化するコマンドとしてSA_SYSDBA.ENABLE_POLICY がありますが、ポリシーは作成時に自動的に有効化されるためここで実行する必要はありません。

4-4. レベルを作成する

ラベルを構成するレベルとして、SENSCONFINTL の 3 つを作成します。今回はレベルによる上下関係だけを確認するため、区分とグループは作成しません。

BEGIN
  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'OLS_POL_DEMO',
    level_num   => 4000,
    short_name  => 'SENS',
    long_name   => 'SENSITIVE'
  );

  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'OLS_POL_DEMO',
    level_num   => 3000,
    short_name  => 'CONF',
    long_name   => 'CONFIDENTIAL'
  );

  SA_COMPONENTS.CREATE_LEVEL(
    policy_name => 'OLS_POL_DEMO',
    level_num   => 2000,
    short_name  => 'INTL',
    long_name   => 'INTERNAL'
  );
END;
/

作成したレベルを確認します。

select * from all_sa_levels
  where policy_name = 'OLS_POL_DEMO';
POLICY_NAME        LEVEL_NUM SHORT_NAME    LONG_NAME
_______________ ____________ _____________ _______________
OLS_POL_DEMO            3000 CONF          CONFIDENTIAL
OLS_POL_DEMO            2000 INTL          INTERNAL
OLS_POL_DEMO            4000 SENS          SENSITIVE

4-5. データ・ラベルを作成する

作成したレベルを使って、行に設定するデータ・ラベルを作成します。label_tag は、保護対象の表のラベル列に実際に格納される数値となります。

BEGIN
  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'OLS_POL_DEMO',
    label_tag   => 400,
    label_value => 'SENS',
    data_label  => TRUE
  );

  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'OLS_POL_DEMO',
    label_tag   => 300,
    label_value => 'CONF',
    data_label  => TRUE
  );

  SA_LABEL_ADMIN.CREATE_LABEL(
    policy_name => 'OLS_POL_DEMO',
    label_tag   => 200,
    label_value => 'INTL',
    data_label  => TRUE
  );
END;
/

作成したデータ・ラベルを確認します。

select * from all_sa_labels
	where policy_name = 'OLS_POL_DEMO';
POLICY_NAME     LABEL       LABEL_TAG LABEL_TYPE
_______________ ________ ____________ __________________
OLS_POL_DEMO    SENS              400 USER/DATA LABEL
OLS_POL_DEMO    CONF              300 USER/DATA LABEL
OLS_POL_DEMO    INTL              200 USER/DATA LABEL

4-6. ユーザーへレベルを認可する

HR ユーザーには SENS まで、SALES_APP ユーザーには CONF までのレベルを認可します。最小レベルはいずれも INTL とします。

max_level は読み取りと書き込みが可能な最上位レベル、min_level は書き込みが可能な最下位レベルです。今回は READ_CONTROL だけを使用するため、動作確認で表示される行の範囲は主に max_level によって決まります。

BEGIN
  SA_USER_ADMIN.SET_LEVELS(
    policy_name => 'OLS_POL_DEMO',
    user_name   => 'HR',
    max_level   => 'SENS',
    min_level   => 'INTL'
  );

  SA_USER_ADMIN.SET_LEVELS(
    policy_name => 'OLS_POL_DEMO',
    user_name   => 'SALES_APP',
    max_level   => 'CONF',
    min_level   => 'INTL'
  );
END;
/

保護表の所有者である HR へはOLS ポリシーの FULL 権限を付与します。

BEGIN
  SA_USER_ADMIN.SET_USER_PRIVS(
    policy_name => 'OLS_POL_DEMO',
    user_name   => 'HR',
    privileges  => 'FULL'
  );
END;
/

ユーザーへ設定したレベルを確認します。

select * from dba_sa_user_levels
  where policy_name = 'OLS_POL_DEMO';
POLICY_NAME     USER_NAME    MAX_LEVEL    MIN_LEVEL    DEF_LEVEL    ROW_LEVEL
_______________ ____________ ____________ ____________ ____________ ____________
OLS_POL_DEMO    HR           SENS         INTL         SENS         SENS
OLS_POL_DEMO    SALES_APP    CONF         INTL         CONF         CONF

5. 保護対象の表へポリシーとラベルを設定する

5-1. 表の準備

JOB_HISTORY 表をコピーし、ラベルを設定する表を HR.JOB_HISTORY_4OLS として別途用意します。

create table hr.job_history_4ols as
  select * from hr.job_history where 1=0;

insert into hr.job_history_4ols
  select * from hr.job_history;

作成した表を確認します。

SELECT * FROM hr.job_history_4ols;
   EMPLOYEE_ID START_DATE    END_DATE     JOB_ID           DEPARTMENT_ID
______________ _____________ ____________ _____________ ________________
           102 13-JAN-11     24-JUL-16    IT_PROG                     60
           101 21-SEP-07     27-OCT-11    AC_ACCOUNT                 110
           101 28-OCT-11     15-MAR-15    AC_MGR                     110
           201 17-FEB-14     19-DEC-17    MK_REP                      20
           114 24-MAR-16     31-DEC-17    ST_CLERK                    50
           122 01-JAN-17     31-DEC-17    ST_CLERK                    50
           200 17-SEP-05     17-JUN-11    AD_ASST                     90
           176 24-MAR-16     31-DEC-16    SA_REP                      80
           176 01-JAN-17     31-DEC-17    SA_MAN                      80
           200 01-JUL-12     31-DEC-16    AC_ACCOUNT                  90

10 rows selected.

続いて、SALES_APP ユーザーへ表の参照権限を付与します。

grant select on hr.job_history_4ols to sales_app;

5-2. 表へ OLS ポリシーを適用する

HR.JOB_HISTORY_4OLS 表へ OLS_POL_DEMO ポリシーを適用します。この際、optionにREAD_CONTROL を指定し、問い合わせ時の行アクセスを制御します。

BEGIN
  SA_POLICY_ADMIN.APPLY_TABLE_POLICY(
    policy_name   => 'OLS_POL_DEMO',
    schema_name   => 'HR',
    table_name    => 'JOB_HISTORY_4OLS',
    table_options => 'READ_CONTROL'
  );
END;
/

ポリシーを表へ適用すると、その表にはポリシー作成時に指定した OLS_LABEL_DEMO 列が追加されます。また、表に対するポリシーは自動的に有効化されます。

DESC hr.job_history_4ols
Name              Null?       Type
_________________ ___________ _______________
EMPLOYEE_ID       NOT NULL    NUMBER(6)
START_DATE        NOT NULL    DATE
END_DATE          NOT NULL    DATE
JOB_ID            NOT NULL    VARCHAR2(10)
DEPARTMENT_ID                 NUMBER(4)
OLS_LABEL_DEMO                NUMBER(10)

ディクショナリビューでも適用状態を確認します。

select policy_name, schema_name, table_name, status, table_options
  from all_sa_table_policies
  where policy_name = 'OLS_POL_DEMO';
POLICY_NAME     SCHEMA_NAME    TABLE_NAME          STATUS     TABLE_OPTIONS
_______________ ______________ ___________________ __________ ________________
OLS_POL_DEMO    HR             JOB_HISTORY_4OLS    ENABLED    READ_CONTROL

5-3. 各行へデータ・ラベルを設定する

追加された OLS_LABEL_DEMO 列へ、JOB_ID に応じたデータ・ラベルを設定します。ここで使用するCHAR_TO_LABEL 関数は、SENS などのラベル文字列を、表に格納される数値のラベル・タグへ変換するものです。

まず、管理職の行へ SENS を設定します。(2行更新されます)

update hr.job_history_4ols
  set ols_label_demo = CHAR_TO_LABEL('OLS_POL_DEMO', 'SENS')
  where job_id in ('AC_MGR', 'SA_MAN');

AC_ACCOUNT と営業・マーケティング担当の行へ CONF を設定します。(4行更新されます)

update hr.job_history_4ols
  set ols_label_demo = CHAR_TO_LABEL('OLS_POL_DEMO', 'CONF')
  where job_id in ('AC_ACCOUNT', 'MK_REP', 'SA_REP');

残りの行へ INTL を設定します。(4行更新されます)

update hr.job_history_4ols
  set ols_label_demo = CHAR_TO_LABEL('OLS_POL_DEMO', 'INTL')
  where job_id in ('IT_PROG', 'ST_CLERK', 'AD_ASST');

commit;

それぞれ 2 rows updated.4 rows updated.4 rows updated. と表示されれば、10 行すべてにラベルが設定されています。

数値のラベル・タグと、人が読めるラベル文字列の両方を確認します。ラベル列は数字として格納されているため、ここでLABEL_TO_CHAR 関数を使用することで、ラベル・タグをラベル文字列へ変換して表示がされます。

select employee_id,
       job_id,
       ols_label_demo AS label_tag,
       LABEL_TO_CHAR(ols_label_demo) AS label
  from hr.job_history_4ols;
   EMPLOYEE_ID JOB_ID           LABEL_TAG LABEL
______________ _____________ ____________ ________
           102 IT_PROG                200 INTL
           101 AC_ACCOUNT             300 CONF
           101 AC_MGR                 400 SENS
           201 MK_REP                 300 CONF
           114 ST_CLERK               200 INTL
           122 ST_CLERK               200 INTL
           200 AD_ASST                200 INTL
           176 SA_REP                 300 CONF
           176 SA_MAN                 400 SENS
           200 AC_ACCOUNT             300 CONF

10 rows selected.
ラベル列は数字として表示されます
SQL> select * from hr.job_history_4ols;

   EMPLOYEE_ID START_DATE    END_DATE     JOB_ID           DEPARTMENT_ID    OLS_LABEL_DEMO
______________ _____________ ____________ _____________ ________________ _________________
           102 13-JAN-11     24-JUL-16    IT_PROG                     60               200
           101 21-SEP-07     27-OCT-11    AC_ACCOUNT                 110               300
           101 28-OCT-11     15-MAR-15    AC_MGR                     110               400
           201 17-FEB-14     19-DEC-17    MK_REP                      20               300
           114 24-MAR-16     31-DEC-17    ST_CLERK                    50               200
           122 01-JAN-17     31-DEC-17    ST_CLERK                    50               200
           200 17-SEP-05     17-JUN-11    AD_ASST                     90               200
           176 24-MAR-16     31-DEC-16    SA_REP                      80               300
           176 01-JAN-17     31-DEC-17    SA_MAN                      80               400
           200 01-JUL-12     31-DEC-16    AC_ACCOUNT                  90               300

10 rows selected.

6. 動作確認

6-1. HR ユーザーでは全行が表示されることを確認する

新しいセッションで HR ユーザーとして接続します。ユーザーの認可情報はセッション開始時に反映されるため、レベルを設定する前から接続していた場合は接続し直します。

$ sql hr@localhost:1521/freepdb1

接続先とユーザーを確認後、保護対象の表を参照します。

SHOW USER
SHOW CON_NAME

select employee_id,
       job_id,
       LABEL_TO_CHAR(ols_label_demo) AS label
  from hr.job_history_4ols;
USER is "HR"

CON_NAME
------------------------------
FREEPDB1

   EMPLOYEE_ID JOB_ID        LABEL
______________ _____________ ________
           102 IT_PROG       INTL
           101 AC_ACCOUNT    CONF
           101 AC_MGR        SENS
           201 MK_REP        CONF
           114 ST_CLERK      INTL
           122 ST_CLERK      INTL
           200 AD_ASST       INTL
           176 SA_REP        CONF
           176 SA_MAN        SENS
           200 AC_ACCOUNT    CONF

10 rows selected.

HR ユーザーの最大レベルは SENS です。そのため、SENSCONFINTL の全 10 行が表示されます。

6-2. SALES_APP ユーザーでは SENS の行が表示されないことを確認する

続いて、新しいセッションで SALES_APP ユーザーとして接続します。

$ sql sales_app@localhost:1521/freepdb1

同じ問い合わせを実行します。

SHOW USER
SHOW CON_NAME

select employee_id,
       job_id,
       LABEL_TO_CHAR(ols_label_demo) AS label
  from hr.job_history_4ols;
USER is "SALES_APP"

CON_NAME
------------------------------
FREEPDB1

   EMPLOYEE_ID JOB_ID        LABEL
______________ _____________ ________
           102 IT_PROG       INTL
           101 AC_ACCOUNT    CONF
           201 MK_REP        CONF
           114 ST_CLERK      INTL
           122 ST_CLERK      INTL
           200 AD_ASST       INTL
           176 SA_REP        CONF
           200 AC_ACCOUNT    CONF

8 rows selected.

SALES_APP ユーザーの最大レベルは CONF です。そのため、先程のHRユーザーで実行したSQLは同じにもかかわらず、上位の SENS ラベルを持つ AC_MGRSA_MAN の 2 行は、問い合わせ結果に含まれないため8行が返ります。

このようにアプリケーションの SQL に WHERE 条件を追加していなくても、データベース側で接続ユーザーの認可情報と行のラベルが比較され、参照できる行だけが返されることを確認できました。


7. 後片付け

7-1. デモ用の表とポリシーを削除する

検証が終わったら、SYS ユーザーで freepdb1 に接続し、作成した設定を削除します。本番環境や共有環境では、削除対象を事前に確認してから実行してください。

$ sql sys@localhost:1521/freepdb1 AS SYSDBA

まず、HR.JOB_HISTORY_4OLS 表からポリシーを削除します。drop_column => TRUE を指定し、ポリシーのラベル列も削除します。

BEGIN
  SA_POLICY_ADMIN.REMOVE_TABLE_POLICY(
    policy_name => 'OLS_POL_DEMO',
    schema_name => 'HR',
    table_name  => 'JOB_HISTORY_4OLS',
    drop_column => TRUE
  );
END;
/

続いて、デモ用の表を削除します。

DROP TABLE hr.job_history_4ols PURGE;

最後に、OLS ポリシーを削除します。SA_SYSDBA.DROP_POLICY を実行すると、このポリシーに関連付けたユーザー認可とデータ・ラベルも削除されます。そのため、ユーザー認可、ラベル、レベルを個別に削除する必要はありません。

BEGIN
  SA_SYSDBA.DROP_POLICY(
    policy_name => 'OLS_POL_DEMO',
    drop_column => TRUE
  );
END;
/

ポリシーと表が残っていないことを確認します。

select policy_name
  from all_sa_policies
  where policy_name = 'OLS_POL_DEMO';

select owner, table_name
  from dba_tables
  where owner = 'HR'
    and table_name = 'JOB_HISTORY_4OLS';

また、 SALES_APP ユーザーを作成した場合は、必要に応じて削除します。

DROP USER sales_app CASCADE;

7-2. OLS を無効化する

ほかの OLS ポリシーで使用している環境では、OLS 自体を無効化しないでください。また、Oracle Database Vault を使用している場合、内部的に Oracle Label Security に依存しているため、Database Vault が有効な PDB でも無効化はしないでおきます。

念のため、Database Vault の状態を確認します。

select name, status from dba_dv_status;

Database Vault(DV_ENABLE_STATUS)が構成、有効化されていないことを確認したうえで、OLS を無効化します。

EXEC LBACSYS.OLS_ENFORCEMENT.DISABLE_OLS;

CDB ルートへ接続し、PDB を再起動します。

CONNECT / AS SYSDBA

alter pluggable database freepdb1 close immediate;
alter pluggable database freepdb1 open;

再度 freepdb1 で状態を確認します。

ALTER SESSION SET CONTAINER = freepdb1;

select name, status from dba_ols_status;
NAME                    STATUS
----------------------- --------
OLS_CONFIGURE_STATUS    TRUE
OLS_ENABLE_STATUS       FALSE

OLS_ENABLE_STATUSFALSE であれば、OLS の施行は無効になっています。OLS_CONFIGURE_STATUSTRUE のままなのため、必要になった場合は再度有効化できます。


8. まとめ

本記事では、Oracle Label Security のポリシーと 3 段階のラベルを作成し、HR.JOB_HISTORY_4OLS 表へ適用しました。

確認できたポイントは次の 3 つです。

  • 表の各行には数値のラベルタグが格納され、その値をもとにデータベース側でアクセス可否が判定される
  • HR ユーザーは最大レベルが SENS のため全 10 行を参照できる
  • SALES_APP ユーザーは最大レベルが CONF のため、SENS の 2 行を除く 8 行だけを参照できる

Oracle Label Security を使うと、アプリケーションの問い合わせに個別の条件を追加しない同一のSQLであったとしても、データに付与した分類ラベルとユーザーの認可範囲に基づく行アクセス制御をデータベース側で一貫して施行できます。一方で、実際の導入では、ラベルを作ること以上に、誰がどの基準でラベルと認可を維持するかという運用設計が重要となります。

次回はこの Oracle Label Security の基盤となっている、より汎用的な行レベル・アクセス制御技術である Virtual Private Database(VPD)を取り上げます。

参考資料