ファイングレイン監査(FGA: Fine Grained Auditing)は、Oracleで「特定の表にアクセスしたか」だけでなく、特定の列を参照したか、特定条件に合う行へアクセスしたかまで絞って監査できる仕組みです。通常の監査よりもログを目的に合わせて絞り込めるため、個人情報、給与、契約金額、機密フラグなどのアクセス証跡を残したい場面で役立ちます。
この記事では、DBMS_FGA.ADD_POLICY を使ったFGAポリシー作成、DBA_FGA_AUDIT_TRAIL / UNIFIED_AUDIT_TRAIL の確認、PL/SQLハンドラ連携、有効化・無効化・削除までを実務向けにまとめます。Oracle監査全体の設計は Oracleの監査(AUDIT)機能の設定方法、統合監査中心の整理は 統合監査(Unified Audit)完全ガイド も参考にしてください。
- DBMS_FGAで監査ポリシーを作成する基本形
- SELECT / UPDATE / DELETE を対象にする指定方法
- audit_column と audit_column_opts の使い分け
- 監査ログを確認するSQL
- PL/SQLハンドラで独自ログへ記録する方法
- ポリシーの無効化・再有効化・削除
- 実務で避けたい設計ミス
FGAでできること
FGAは、表やビューに対して条件付きの監査ポリシーを設定します。たとえば、給与列を参照したSELECTだけ記録する、高額取引に対するUPDATEだけ記録する、といった使い方ができます。
| 対象 | 例 | 使いどころ |
|---|---|---|
| 列 | SALARY を参照したとき |
給与・個人情報・機密列の監査 |
| 行条件 | amount >= 1000000 |
高額取引や重要データだけ監査 |
| SQL種別 | SELECT,UPDATE,DELETE |
参照だけでなく変更操作も追跡 |
| ハンドラ | PL/SQLプロシージャを呼び出す | 独自ログ・通知・アラート連携 |
必要な権限
FGAポリシーを管理するユーザーには、監査管理用の権限と DBMS_FGA の実行権限が必要です。権限設計は環境方針に合わせますが、専用の管理ユーザーで実行するのが扱いやすいです。
-- 例: FGAを管理するユーザーに必要な権限を付与 GRANT AUDIT_ADMIN TO SEC_ADMIN; GRANT EXECUTE ON DBMS_FGA TO SEC_ADMIN; -- 監査対象表に対する権限も必要 GRANT SELECT, UPDATE, DELETE ON HR.EMPLOYEES TO SEC_ADMIN;
DBMS_FGA.ADD_POLICYの基本形
FGAポリシーは DBMS_FGA.ADD_POLICY で作成します。以下は、HR.EMPLOYEES の SALARY 列を参照し、かつ給与が10000以上の行にアクセスした場合に監査する例です。
BEGIN
DBMS_FGA.ADD_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY',
audit_condition => 'SALARY >= 10000',
audit_column => 'SALARY',
handler_schema => NULL,
handler_module => NULL,
enable => TRUE,
statement_types => 'SELECT',
audit_column_opts => DBMS_FGA.ANY_COLUMNS
);
END;
/
audit_condition は行条件、audit_column は監査対象列です。audit_column を指定しない場合は、対象オブジェクトへのアクセス全体が監査対象になります。
audit_condition は行ごとに評価される条件式です。複雑な副問合せ、シーケンス、ROWNUM などは使えません。Oracleのバージョンや構成によっては、AND / OR を含む複雑な条件も避ける必要があります。まずは単純な条件から作り、複雑な判定が必要ならビューや別設計で吸収するのが安全です。条件を指定しない場合は TRUE と同じ扱いになります。SELECT以外も監査する
FGAはSELECTだけでなく、INSERT、UPDATE、DELETEも対象にできます。給与列の参照・変更を追いたい場合は、statement_types に複数のSQL種別を指定します。
BEGIN
DBMS_FGA.ADD_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY_DML',
audit_condition => 'SALARY >= 10000',
audit_column => 'SALARY',
statement_types => 'SELECT,UPDATE,DELETE',
audit_column_opts => DBMS_FGA.ANY_COLUMNS,
enable => TRUE
);
END;
/
監査範囲を広げるほどログ量と確認コストも増えます。最初から全操作を監査するより、実際に追跡したい操作に絞るほうが運用しやすくなります。
audit_column_optsの違い
audit_column に複数列を指定する場合、audit_column_opts で「どれか1列でも参照されたら監査する」のか、「指定列すべてが参照されたら監査する」のかを選びます。
| 指定 | 監査される条件 | 向いている場面 |
|---|---|---|
DBMS_FGA.ANY_COLUMNS |
指定列のいずれかを参照 | 1列でも機密なら記録したい |
DBMS_FGA.ALL_COLUMNS |
指定列すべてを参照 | 列の組み合わせが危険なときだけ記録したい |
-- どちらかの列を参照したら監査 audit_column => 'SALARY,COMMISSION_PCT', audit_column_opts => DBMS_FGA.ANY_COLUMNS -- 両方の列を参照したら監査 audit_column => 'SALARY,COMMISSION_PCT', audit_column_opts => DBMS_FGA.ALL_COLUMNS
監査ログを確認する
FGAの監査ログは、環境によって DBA_FGA_AUDIT_TRAIL や UNIFIED_AUDIT_TRAIL から確認します。既存環境では両方のどちらを見ればよいか、監査方式を先に確認しておきましょう。データディクショナリの調べ方は Oracleデータディクショナリ完全ガイド にもまとめています。
SELECT
db_user,
os_user,
userhost,
object_schema,
object_name,
policy_name,
statement_type,
timestamp,
sql_text
FROM dba_fga_audit_trail
WHERE policy_name = 'FGA_EMP_SALARY'
ORDER BY timestamp DESC;
SELECT
dbusername,
os_username,
userhost,
object_schema,
object_name,
fga_policy_name,
action_name,
event_timestamp,
sql_text
FROM unified_audit_trail
WHERE fga_policy_name = 'FGA_EMP_SALARY'
ORDER BY event_timestamp DESC;
SQL_TEXT を見ると、どのSQLで監査が発生したか追跡できます。バインド変数を多用するアプリでは、SQL本文だけでは意図が読みづらいことがあります。バインド変数の考え方は Oracleバインド変数完全ガイド も参考になります。
PL/SQLハンドラで独自ログに記録する
FGAでは監査イベント発生時にPL/SQLハンドラを呼び出せます。標準監査ログとは別に、アプリ運用向けの軽量ログへ書きたい場合に使えます。
CREATE TABLE sec_admin.fga_alert_log ( id NUMBER GENERATED BY DEFAULT AS IDENTITY, object_schema VARCHAR2(128), object_name VARCHAR2(128), policy_name VARCHAR2(128), db_user VARCHAR2(128), host_name VARCHAR2(256), log_time TIMESTAMP DEFAULT SYSTIMESTAMP, CONSTRAINT pk_fga_alert_log PRIMARY KEY (id) );
CREATE OR REPLACE PROCEDURE sec_admin.fga_alert_handler(
object_schema IN VARCHAR2,
object_name IN VARCHAR2,
policy_name IN VARCHAR2
) AUTHID DEFINER
IS
BEGIN
INSERT INTO sec_admin.fga_alert_log (
object_schema,
object_name,
policy_name,
db_user,
host_name
) VALUES (
object_schema,
object_name,
policy_name,
SYS_CONTEXT('USERENV', 'SESSION_USER'),
SYS_CONTEXT('USERENV', 'HOST')
);
END;
/
ハンドラを登録する場合は、handler_schema と handler_module を指定します。
BEGIN
DBMS_FGA.ADD_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY_ALERT',
audit_condition => 'SALARY >= 10000',
audit_column => 'SALARY',
handler_schema => 'SEC_ADMIN',
handler_module => 'FGA_ALERT_HANDLER',
statement_types => 'SELECT,UPDATE',
audit_column_opts => DBMS_FGA.ANY_COLUMNS,
enable => TRUE
);
END;
/
独自ログやトレーサビリティ設計は PL/SQLのロギングとトレーサビリティを両立する監査設計 と相性が良いです。
ポリシーを確認・無効化・有効化・削除する
設定したFGAポリシーは、後から確認・停止・再開・削除できます。調査中だけ一時的に監査したい場合は、削除ではなく無効化を使うと戻しやすくなります。
-- FGAポリシー一覧を確認
SELECT object_schema, object_name, policy_name, enabled, sel, ins, upd, del
FROM dba_audit_policies
WHERE object_schema = 'HR'
AND object_name = 'EMPLOYEES'
ORDER BY policy_name;
-- 無効化
BEGIN
DBMS_FGA.DISABLE_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY'
);
END;
/
-- 再有効化
BEGIN
DBMS_FGA.ENABLE_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY'
);
END;
/
-- 削除
BEGIN
DBMS_FGA.DROP_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'FGA_EMP_SALARY'
);
END;
/
動作確認用SQL
ポリシー作成後は、監査されるSQLと監査されないSQLを分けてテストします。監査条件と監査列の両方を満たすかがポイントです。
-- SALARY列を参照し、条件に合う可能性があるため監査対象 SELECT employee_id, last_name, salary FROM hr.employees WHERE salary >= 10000; -- SALARY列を参照しないため、audit_column指定によっては監査されない SELECT employee_id, last_name FROM hr.employees WHERE department_id = 10; -- UPDATEもstatement_typesに含めていれば監査対象 UPDATE hr.employees SET salary = salary WHERE salary >= 10000;
実務での設計ポイント
| 観点 | 推奨 | 理由 |
|---|---|---|
| 監査範囲 | 対象表・列・条件を絞る | ログ量と性能影響を抑える |
| ポリシー名 | 対象と目的が分かる名前にする | 調査時に検索しやすい |
| ハンドラ | 軽量処理だけにする | 例外や再帰監査の影響を避ける |
| ログ保存 | 保存期間とアーカイブ方針を決める | 監査ログが増え続けるため |
| 権限 | 監査管理者を限定する | ポリシー改ざんを防ぐ |
よくある質問
statement_types に INSERT,UPDATE,DELETE,SELECT を指定できます。ただし、必要な操作に絞らないとログが増えます。UNIFIED_AUDIT_TRAIL を確認します。古い構成や移行前の環境では DBA_FGA_AUDIT_TRAIL も確認対象になります。まとめ
FGAは、Oracleで機密データへのアクセスを条件付きで監査したい場合に強力です。DBMS_FGA.ADD_POLICY で対象表、条件、列、SQL種別を指定し、DBA_FGA_AUDIT_TRAIL や UNIFIED_AUDIT_TRAIL で監査結果を確認します。
PL/SQLハンドラを使うと独自ログや通知に発展できますが、重い処理や再帰監査は避ける必要があります。まずは対象を絞ったポリシーを作り、ログ量・性能・運用フローを確認しながら本番適用するのが安全です。
参考: Oracle Database PL/SQL Packages and Types Reference – DBMS_FGA

