監査ログはデータベースのセキュリティとコンプライアンスの礎です。誰が何を変えたかを追う、異常を調査する、監査に備える、いずれの目的でも、PostgreSQL は粒度の異なる複数の方法で活動を記録できます。
本ガイドでは、組み込みのログから pgAudit、Bytebase のような高度なツールまで、最も実用的なアプローチを順に整理します。
1. ネイティブ PostgreSQL ログ
PostgreSQL はログサブシステムを最初から備えます。監査証跡を組む第一歩になることが多いです。
主な設定
postgresql.conf でログを有効化・設定できます。
logging_collector = on
log_statement = 'all' # 選択肢: none, ddl, mod, all
log_line_prefix = '%m [%p] %u@%d ' # タイムスタンプ、プロセス ID、ユーザー、DB
log_duration = on
log_destination = 'csvlog'これで PostgreSQL は、実行されたすべての SQL を収集し、誰がいつ実行したかを含め、クエリ時間も記録します。
長所
- 有効化が簡単で、組み込み。拡張不要。
- 性能分析や基本的な監査可視性に有用。
短所
- 非構造のテキストログ — 自動パースが難しい。
- 量が急増しやすい。
- 機微なクエリパラメータを含み得る。
pgBadger のようなツールでこれらのログを解析し、誰がいつ何を実行したかの視覚的なレポートを生成できます。
2. トリガーベースの監査
行レベルの変更 — 例えば UPDATE 前後の値 — を記録したいなら、トリガーが使えます。
例
変更履歴を保存するテーブルを作る:
CREATE TABLE audit_log (
id serial PRIMARY KEY,
table_name text,
action text,
changed_by text,
changed_at timestamptz DEFAULT now(),
old_data jsonb,
new_data jsonb
);トリガーを定義する:
CREATE OR REPLACE FUNCTION audit_trigger() RETURNS trigger AS $$
BEGIN
INSERT INTO audit_log (table_name, action, changed_by, old_data, new_data)
VALUES (TG_TABLE_NAME, TG_OP, current_user, row_to_json(OLD), row_to_json(NEW));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_user_table
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION audit_trigger();users テーブルへのすべての DML 操作 (INSERT、UPDATE、DELETE) を、変更内容と実施者と一緒に記録します。
長所
- 変更前後のデータを捕捉。
- スキーマを完全にカスタマイズ可能。
短所
- テーブルごとに定義が必要。
- 書き込みの多いワークロードで性能影響あり。
リアルタイムの変更通知には、PostgreSQL の tcn モジュール (Triggered Change Notification) が使えます。データ変更時にリスナへ NOTIFY を送れます。
3. 論理レプリケーションベースの監査
PostgreSQL の論理レプリケーションは、Write-Ahead Log (WAL) から変更をデコードし、構造化フォーマットでストリーミングします。トリガーやアプリ変更無しで、すべてのデータ変更を捕捉できます。
仕組み
論理レプリケーションは レプリケーションスロット と 出力プラグイン (wal2json や pgoutput) を使い、WAL エントリを JSON などに変換します。Debezium のようなツールがこれを消費し、Kafka、Elasticsearch、S3 などの監査ストレージへ転送します。
セットアップ例
postgresql.conf で論理レプリケーションを有効化:
wal_level = logical
max_replication_slots = 4
max_wal_senders = 4レプリケーションスロットを作成:
SELECT * FROM pg_create_logical_replication_slot('audit_slot', 'wal2json');変更を読む:
SELECT * FROM pg_logical_slot_get_changes('audit_slot', NULL, NULL);このような JSON が得られます:
{
"change": [
{
"kind": "update",
"schema": "public",
"table": "users",
"columnnames": ["id", "email", "updated_at"],
"columnvalues": [42, "user@example.com", "2025-11-10 10:30:00"],
"oldkeys": { "keynames": ["id"], "keyvalues": [42] }
}
]
}長所
- すべてのデータ変更を自動捕捉、テーブルごとのセットアップ不要。
- 性能影響は最小 — 既存の WAL 基盤を読む。
- Debezium のような既存ツールで外部システムへストリーム可能。
- アプリコードの変更不要。
短所
SELECTクエリは捕捉しない (データ変更のみ)。- レプリケーションスロットが追いつかないと、WAL 保持でストレージが増える。
このアプローチは、監査、分析、イベント駆動アーキテクチャ向けのニアリアルタイムな変更データ取得 (CDC) が必要なときに最適です。
4. pgAudit 拡張
構造化されたコンプライアンスグレードの監査ログには、PostgreSQL の pgAudit 拡張が標準的な選択肢です。 ネイティブログを拡張し、読み書きを中心により多くの文脈と粒度を提供します。
インストール
拡張を有効化:
CREATE EXTENSION pgaudit;設定を更新:
shared_preload_libraries = 'pgaudit'
pgaudit.log = 'READ, WRITE'
pgaudit.log_catalog = offPostgreSQL を再起動すると、次のような監査ログが出るようになります:
AUDIT: SESSION,1,READ,SELECT,,,,"SELECT * FROM customers WHERE id=42;",<none>メリット
- 誰がどのセッションでどの文を実行したかを記録。
- DDL と DML の両方の活動を捕捉。
- PostgreSQL の標準ログコレクタと統合 — 新しいストレージモデルは不要。
考慮点
- ログが冗長になり得る —
pgaudit.log_parameter = offでノイズを減らせる。 - 適切なログローテーションと分析戦略が必要。
5. Bytebase
Bytebase は、PostgreSQL 環境にまたがる中央集約の監査証跡を提供するデータベース DevSecOps プラットフォームです。 誰が、何を、いつ、なぜ — を記録し、SQL 操作を Issue、承認、デプロイの文脈に紐付けつつ、機微データの安全性を保ちます。
Bytebase が監査するもの
- クエリアクセス: SQL Editor、Admin Query、Data Export での「誰が、いつ、どのデータを照会したか」をログ。
- スキーマ・データ変更: 「誰が、どの変更を、いつ承認され、どのワークフローや Git コミットを通じて」適用したかを追跡。
- ガバナンス統制: 組み込みの SQL レビュールール、承認フロー、ロールベースアクセスで不正操作を防ぐ。
- DB ユーザーではなく実エンドユーザー: 重要な利点は、Bytebase が共有 DB ユーザー問題を解くことです。多くのアプリは全クエリで同じ DB 接続ユーザー (
app_userなど) を使うため、伝統的な DB 監査では個人にまで遡れません。ユーザーが Bytebase 経由で操作するため、すべての操作が汎用 DB アカウントではなく実エンドユーザーに帰属します。
なぜ重要か
- 読み書き双方にわたる完全な可視性。
- 機微データの露出なしのプライバシー安全な監査。
- SOC 2、ISO 27001、GDPR に整合するコンプライアンス対応ログ。
API を呼び出して、中央集約のログシンクに監査ログを送れます。レコードフォーマット、Bytebase がエンジンネイティブログに対して閉じる 3 つのギャップ、カラム単位のマスキング詳細は Bytebase の監査ログの扱い を参照。
結論
PostgreSQL は複数層の監査を提供します — 基本のテキストログから完全なガバナンスソリューションまで。
比較表
| アプローチ | 性能影響 | SELECT を捕捉 | 実施者を捕捉 | 行レベル詳細 | 適する用途 |
|---|---|---|---|---|---|
| ネイティブログ | 低〜中 | ✅ | ⚠️ DB ユーザーのみ | ❌ | 開発、デバッグ、基本的な監査証跡 |
| トリガー | 中〜高 | ❌ | ⚠️ DB ユーザーのみ | ✅ (前後) | 完全な変更履歴が必要な重要テーブル |
| 論理レプリケーション | 低 | ❌ | ❌ | ✅ | リアルタイム CDC、イベント駆動、分析 |
| pgAudit | 中 | ✅ | ⚠️ DB ユーザーのみ | ❌ | コンプライアンス要件、構造化ログ |
| Bytebase | 該当無し (アプリ層) | ✅ | ✅ エンドユーザー | ✅ | 中央集約のガバナンス、承認ワークフロー、チーム協働 |
-
ベースラインの活動追跡にはネイティブログ (DB ユーザーのみ捕捉)。
-
重要テーブルの細粒度な行レベル監査にはトリガー (DB ユーザーのみ捕捉)。
-
アプリ変更なしのニアリアルタイム CDC には論理レプリケーション。
-
構造化されたコンプライアンスグレードの文ログには pgAudit (DB ユーザーのみ捕捉)。
-
実エンドユーザー (DB ユーザーではなく) を追跡し、すべての操作を承認とワークフローの完全な文脈で人物に紐付ける中央集約の監査には Bytebase を追加。
これらの層を組み合わせることで、安全・準拠・統制されたデータベース運用に必要な可視性と統制を両立できます。
関連記事:
- データベース監査ログ: 2 つのレイヤー、1 本の証跡 — ハブ: インフラ vs ワークフロー、フレームワーク別・エンジン別ガイド
- Bytebase の監査ログの扱い — ワークフロー層のレコードフォーマット、3 つのギャップ、マスキングのメタデータ、エクスポート経路
- SOC 2 監査ログ要件 — 監査官が実際に求めるもの、4 フィールドのフレームワーク、Admin 活動の 6 カテゴリ