ガイド
監査ログが書き換えを見つける仕組み
追記専用の記録・ハッシュの連鎖・検査では分からないこと
株主名簿には、氏名・住所・持株数が入ります。だれが見て、だれが変えたのかを、あとから確かめられなければ、台帳として信用できません。OpenStock Japan は、すべての変更を監査ログに残し、その記録が書き換えられていないことを検査できるようにしています。この記事では、その仕組みと、仕組みだけでは防げないことを説明します。

この記事の要点
- 監査ログは追記専用です。更新と削除は、データベースが拒否します
- 記録は 1 件ごとに、直前の記録のハッシュを含めて計算した SHA-256 のハッシュを持ちます。途中の書き換え・抜き取りは、検査で見つかります
- 末尾の記録を消された場合は、検査だけでは分かりません。最新の連番とハッシュを、システムの外に控えておきます
- データベースの管理者は、仕組みそのものを外せます。それを防ぐのは、データベースへのアクセスの管理です
01残るもの
何が残るか
監査ログには、3 つの経路で記録が入ります。データの変更は、データベースのトリガーが、変更と同じトランザクションの中で残します。アプリのコードの書き忘れで、記録が抜けることがありません。
| 記録元 | 残るもの | 残し方 |
|---|---|---|
| データの変更 | すべての業務・設定のテーブルの、行の追加・更新・削除。変更前と変更後の値つき | データベースのトリガー |
| 認証 | ログイン(接続元の IP アドレスとブラウザつき)、ログアウト、パスワードの再設定の要求、二要素認証の登録・解除など | 認証サービス(Supabase Auth)のテーブルに付けたトリガー |
| アプリの操作 | ログインの失敗、権限の無い操作の試み、文書のダウンロード、Excel への出力、監査ログの閲覧・出力・検査、AI への送信など | サーバが記録 |

1 件の記録には、次のものが入ります。
- 連番: 組織ごとに 1 から、データベースが振ります。
- 日時: データベースのサーバーの時刻です。呼び出し側が渡した時刻は使いません。
- 操作した人: アカウントの id と、その時点のメールアドレス・ロール。あとでアカウントが消えても、だれだったかが残ります。
- 変更前・変更後の値: 追加は行の全体、削除は消えた行の全体、更新は変わった項目だけ。
- 結果と接続元: 成功・失敗・拒否と、IP アドレス・ブラウザ・リクエストの番号。
- ハッシュ: この記録と、直前の記録のハッシュから計算した値。
02追記専用
書き換えも削除もできないようにする
- 監査ログの更新・削除・全消去は、データベースのトリガーが拒否します。
- アプリが使う権限(
service_role)からも、更新・削除の権限を外しています。 - ブラウザからは、読むことも書くこともできません。
- 操作した人は、サーバがセッションを確かめて決めます。ブラウザが送ってきた値は使いません。
本番に入れたら、実際に書き換えを試して、拒否されることを確かめておきます。
set role service_role;
update system_audit_logs set detail = 'x' where seq = 1; -- permission denied になること
reset role;03連鎖
記録をハッシュでつなぐ
追記専用にしても、データベースに直接つなげる人なら、記録を書き換えられるかもしれません。そこで、書き換えられたことを、あとから見つけられるようにします。記録のたびに、「直前の記録のハッシュ + この記録の内容」から SHA-256 のハッシュを計算して、一緒に残します。
正しくつながっている記録
- 連番 542お知らせを公開
- 前のハッシュ
- 7be2…41d0
- ハッシュ
- a41c…9e07
- 連番 543株主名簿を出力
- 前のハッシュ
- a41c…9e07
- ハッシュ
- 5d2b…c310
- 連番 544改ざんの検査
- 前のハッシュ
- 5d2b…c310
- ハッシュ
- 8c09…b722
連番 543 の内容を書き換えたとき
- 連番 542お知らせを公開
- 前のハッシュ
- 7be2…41d0
- ハッシュ
- a41c…9e07
- 連番 543(内容を書き換え)
- 前のハッシュ
- a41c…9e07
- ハッシュ
- 5d2b…c310
- 連番 544改ざんの検査
- 前のハッシュ
- 5d2b…c310
- ハッシュ
- 8c09…b722
ハッシュは、内容が 1 文字でも変わると、まったく違う値になります。途中の 1 件を書き換えたり抜いたりすると、その記録から先のハッシュが、計算し直した値と合わなくなります。
04検査
検査する
- 「改ざんの検査」を開く
サイドバーの「監査ログ」を開き、「改ざんの検査」のタブを選びます。
- 「検査する」を押す
最初の記録から順に計算し直して、連番の飛びと、ハッシュの食い違いが無いかを確かめます。記録が多いと、時間がかかることがあります。
- 結果を控える
検査のあとに表示される「最新の連番」と「最新のハッシュ」を、月次の記録など、このシステムの外に控えます。

計算が合わないときは、最初に合わなくなった連番と、その理由(連番の飛び・前の記録とのつながり・記録の内容)が分かります。検査をしたことと、その結果も、監査ログに残ります。
05限界
検査では分からないこと
この仕組みには、限界があります。監査の説明では、正直に伝える必要がある点です。
- 末尾の記録を消された場合。 連鎖が見つけるのは、途中の変更です。いちばん新しい側が消えても、残った記録どうしの計算は合ったままです。
- データベースの管理者は、何でもできます。 データベースに管理者としてつなげる人は、トリガーを外して、すべてを作り直せます。ツールが防げるのは、アプリ経由の書き換えまでです。
- 画面で見たことは、記録しません。 記録するのは、変更・ダウンロード・出力・ログインです。「だれがどの株主の画面を開いたか」までは残りません。
- 承認の流れはありません。 登録した人と別の人が承認する仕組みは無いので、重要な登録は、あとから監査ログで確かめる運用になります。
ほかの限界(ログインのロック、接続元の IP アドレス、Cookie の扱いなど)は、文書「システム監査への対応」の「このツールだけでは担保できないこと」に、すべて書いています。
06運用
定期的に行うこと
仕組みは、使って初めて役に立ちます。運用する会社が行うことを、間隔ごとにまとめます。
| 間隔 | 行うこと |
|---|---|
| 毎月 | 改ざんの検査をし(前回の控えと照合する)、最新の連番とハッシュを別の場所に控える |
| 毎月 | 権限エラーとログインの失敗が増えていないかを、監査ログで見る |
| 四半期ごと | アカウントの棚卸し(退職・異動した人のアカウント、ロールの範囲、二要素認証の有無) |
| 人の出入りのつど | 退職・異動した人のアカウントを消す、ロールを変える |
| 年 1 回 | バックアップからの復元を試す |
手元で試すには、ガイド「デモの会社を、手元で動かす」の手順でデモの環境を用意し、監査人のアカウント(audit@example.com)で入ってください。