一口座の凍結と、銀行全体の書込停止
どこまで止めるのか、何を残すのか、どう再開を判断するのかを区別する。
本文の説明・図・掲載コードだけで読み進められます。出典リンクは、権限のある人向け(非公開GitHub)です。GitHubで閲覧権限がある方だけ開けます。
この記事でわかること
- 口座凍結は対象口座、fence は業務更新の広い境界を守る
- 停止中も調査・監査・一部の診断記録は残せる
- 復元後の再開には外部証跡と別人確認が必要
この記事の目次
同じ「止める」でも、守る対象が違う
架空の山田さんの口座に確認すべき問題が見つかった場面と、銀行の DB 全体を復旧する場面を比べます。前者では、その口座の状態を frozen に変える凍結が対象になります。後者で必要なのは、多数の取引や契約の状態が復旧中に動き続けないよう、広い書込境界を止める仕組みです。
一口座を凍結しても、銀行全体の復元作業を安全にする停止にはなりません。逆に、全体を止めたからといって、各口座の frozen という業務状態を全部書き換えるわけでもありません。まず何を守るための停止かを決めると、再開時に何を確かめるべきかも変わります。
凍結は、取引の記録を消すことではない
口座凍結 API は、有効な操作キーと対象 ID、管理者セッションなどを確かめ、DB の管理操作へ進みます。DB は操作者の有効状態を確認してから口座状態を更新し、操作の結果を記録します。同じ依頼の再送を識別するため、応答を見失っても別の変更として積み重ねない構造になっています。
振込では出金元だけでなく入金先の状態も条件になります。凍結は取引を断る理由になりますが、既存の取引、残高、仕訳を消すことではありません。解除も「問題が解決した気がする」だけで履歴を消す操作ではなく、対象口座を再び利用可能な状態へ移す管理判断です。全体の復旧が続いていれば、その口座だけ解除しても全体の停止を越えられません。
全体停止でも、すべての記録を止めない
v17 の fence は、復旧状態が RUNNING または OPEN 以外なら、対象となる書込みを RY001 で拒否します。後の強化では、金額が動かない KYC の承認、融資の審査、価格や模型の設定変更なども境界へ含めました。復元時に契約や権限が動いてしまうと、残高が同じでも安全な基準を失うからです。
一方、復旧の制御、監査、インシデント、必要な調査をすべて止めると、何が起きたかを残せません。risk や Twin の観測用の capture・run による記録も、業務状態を読む診断として許す一方、モデルやシナリオなどの設定変更は止めます。「全体の書込停止」は DB の全表を読取り専用にする意味ではなく、明示した境界を持つ統制です。
たとえば停止中に Twin で既存のシナリオを実行し、復旧前後の観測を比較することには意味があります。しかし、都合のよい予測が出るようモデルの仮定を変更することは、同じ診断ではありません。観測の基準そのものを変えてしまうため、設定側の停止に当たります。KYC でも同様に、現在の審査状態を読むことと、承認へ変えることは別です。全表の更新を一律に拒否すれば説明は簡単になりますが、復旧の理由や検証結果も保存できなくなります。逆に金額が直接動く処理だけを止めると、契約や権限の変更が基準を変えてしまいます。この間に明示的な線を引き、例外を列挙してテストするのが停止境界の設計です。例外を「管理者なら自由」と広げないことが重要になります。
復元した DB 自身を、正解の物差しにしない
障害前に百件あった取引が、古いバックアップの復元で九十件へ戻ったとします。その DB の中で新しく記録を取り、同じ DB と比べれば一致してしまいます。そこで復元宣言には、外に控えた manifest の digest と方式の版、過去に発行した最大の書込世代を使います。復元前の外部証拠を物差しにするためです。
manifestは、復旧時に比べる状態の要約をまとめた記録です。digestは、その対象データから計算した内容照合用の値です。対象範囲や計算方法が変われば値の意味も変わるため、方式の版と組にして比べます。書込世代は、復旧をまたいで新旧の書き手を区別する番号です。これらを障害前にDBの外へ控え、復元したDBの状態と照合します。
さらに運用者の権限は digest に含まれず、外に保存した一覧との比較が必要です。未申告なら検証欄が ok でも declared:false、つまり検査していない状態です。一覧が古い、全員が載っていない、控えた digest 自体が古い場合も限界が残ります。緑色だけを見ず、何を根拠に何を検査したかを読む必要があります。
止めた人だけで、再開まで完結させない
復元後は照合し、検証結果を提出し、提出者とは別の管理責任者が再開します。再開では書込世代を更新し、復元を経た場合は Open Banking の発行済みアクセストークンを失効させます。世代の強制が有効なら、古い設定のアプリを拒否できます。ただし、そのヘッダーはアプリの自己申告であり、悪意ある利用者を認可する仕組みではありません。
停止中に運用者の権限を直す場合も注意が必要です。許される例外は無効化であり、役割の降格ではありません。管理責任者を無効化しても別の二人が残る条件があるため、外部一覧の検査で問題を解消する運用には、事実上三人以上の有効な責任者が必要です。誤った復元宣言はやり直せますが、検証や二者確認を飛ばす道ではありません。
復旧を読む:停止から再開まで
次は状態の関係を示す擬似コードです。復元や設定変更を実行する手順ではありません。
書込停止 → 外部記録から復元を宣言
復元・照合 → 検査済みの根拠を確認
必要なやり直し → 停止状態へ戻って再宣言
検証を提出 → 別の責任者が再開を判断
世代更新 → 古い書き手とトークンを扱う復旧できたことと、失わなかったことは別
バックアップから戻せたとしても、取得後に確定した書込みが失われる可能性はあります。元の冪等キーを使った再現を扱う演習はありますが、失われた事実を調べず新しい依頼として送り直せばよいわけではありません。部分的な表だけを古くする復元は、元帳と支払状態の継ぎ接ぎになり、二重払いの危険があります。
この仕組みが扱うのは、隔離環境での復旧を学び、判定を残す範囲です。実クラウドの自動切替、高可用構成、本番の復旧時間を保証しません。人が外部記録を更新し、異なる二人で手順を通せるかも別の検証です。口座凍結と全体停止を区別する最後の理由は、それぞれが解決していない問題を見失わないためです。
出典と、確認できた範囲
以下のリンクは非公開GitHubへの出典で、閲覧権限が必要です。本文はリンク先を開かなくても読める構成です。固定コード・設計資料を参照していますが、今回、この読み物のために銀行の取引やDB操作、本番試験は実行していません。実装や資料にある検査と、こちらで実施した検証を混同しないようにしています。
- 管理操作の権限とロック ↗(非公開GitHub・要権限)
口座凍結・KYC・管理者変更の権限再確認 - v17 復旧契約 ↗(非公開GitHub・要権限)
状態遷移・外部証跡・再開と書込世代の限界 - 口座凍結 API ↗(非公開GitHub・要権限)
管理者セッションと冪等キーを用いる入口 - v2 の認可・整合性強化 ↗(非公開GitHub・要権限)
所有者・本人確認・口座状態を確認する歴史的な強化点 - 停止境界の強化コード ↗(非公開GitHub・要権限)
業務変更の停止と診断・無効化の例外 - 復旧検証の最終追加 SQL ↗(非公開GitHub・要権限)
digest 版3と外部運用者一覧を扱う実装 - ロールバックと復旧 ↗(非公開GitHub・要権限)
アプリ差戻し・復元・前方修正の使い分け
MiniBankは学習・検証用の銀行アプリです。架空の金額や人物は、仕組みを説明するための例です。
つながる読み物
ここまで読んだ記録を、ひとつ。
自分のペースで。あとから取り消すこともできます。