監査ログ — 「誰がやったか」を、あとから言えるか
顧客データが 3 万件持ち出された。管理画面のログはあった。しかし誰がどのデータを見たかは、どこにも残っていなかった。
この記事の進み方
What — 監査ログは、普通のログとは目的が違う
同じ「ログ」でも、目的が違えば残すものが変わります。
不具合を調べるための記録。開発者が読む。
ERROR 決済に失敗 order_id=7741 stack: PaymentError at ...
- 読む人
- 開発者
- 保持
- 数日〜数週間
- 改ざん対策
- 不要
- 個人情報
- できるだけ入れない
- –量が多く、形式も自由。開発が読めればよい。
- –障害が直れば用済みになるので、保持は短くてよい。
アプリのログは開発者のため、アクセスログは運用のため、監査ログは「あとから説明する」ため。混ぜて1つにすると、どれにも足りなくなる。
- 監査ログ
- 誰が・いつ・何に・何をしたかを、あとから説明するために残す記録。
- 追跡可能性
- ある結果から、それを起こした操作と主体をたどれること。
- actor
- 操作した主体。人だけでなく、バッチや API キーも含む。
- 改ざん耐性
- 記録を後から書き換えられないこと。追記のみの保存や署名で担保する。
- 保持期間
- 記録を残す期間。短すぎると調査できず、長すぎると管理の負担と漏洩時の被害が増える。
残すのは「5W」を復元できる最小限
監査ログの1行に入れるものは、おおむね次です。
| 項目 | 例 | 無いとどうなるか |
|---|---|---|
| いつ | 2026-09-19T14:32:08Z | 時系列が組めない |
| 誰が | user42(個人が特定できる ID) | 共有アカウントだと意味を失う |
| 何に | customer:3102 または 全件 | 影響範囲が言えない |
| 何をした | export / update / view | 操作の種類が分からない |
| 結果 | 成功 / 失敗(権限不足で弾いた、も残す) | 試みたこと自体が消える |
| どこから | IP、セッション ID | 不審なアクセス元を追えない |
**「失敗も残す」**のが見落とされがちです。権限が無くて弾かれた試みは、攻撃や内部不正の最初の兆候になります。成功だけ残すと、探っていた痕跡が消えます。
Why — 「あとから説明する」には、普通のログでは足りない
URL は操作を表さない
アクセスログに GET /admin/customers?page=3 が残っていても、3ページ目の中身は再現できません。並び順が変われば、同じ URL が別のデータを指します。
監査で答えたいのは「どの顧客のデータが見られたか」です。URL ではなく、操作の意味と対象を記録する必要があります。
共有アカウントは、記録を無意味にする
admin を5人で使っていれば、どれだけ丁寧に記録しても 「admin がやった」としか言えません。
これは技術の問題ではなく運用の問題ですが、監査ログの価値を根こそぎ奪います。記録を整える前に、まず1人1アカウントにするほうが効きます。
保持期間は、気づくまでの時間から決める
冒頭の事故では、疑いが出たのが2か月後で、ログは14日で消えていました。
内部不正や情報漏洩は、発覚までに時間がかかります。 数か月、場合によっては1年以上。保持期間を「ディスクが安いから」で決めると、必要なときに無い。
同時に、長く持つほど管理の負担と、漏れたときの被害が増えます。監査ログには「誰が」が必ず入るので、それ自体が個人情報です。
消せる記録は、証拠にならない
操作した本人が消せる場所に監査ログを置けば、都合の悪い記録は消されます。
- アプリと同じ DB に置き、アプリが削除権限を持つ
- 管理者が管理画面から消せる
- 本番から書き込めるバケットに置き、上書きできる
これらはどれも、「あとから説明する」という目的を満たしません。追記のみにする、別の権限領域に送る、といった分離が要ります。
演習 — まず自分で判断する
管理画面で「顧客一覧を CSV 出力」した操作を監査ログに残します。最も重要な項目はどれですか?
権限が無くて弾かれた操作(403)を監査ログに残すべきですか?
読み終わりましたか?
読了にすると、これを前提とする記事がロードマップで開放されます。