SOARの情報補完と対応承認
分岐、承認、実行、再試行、復旧の状態を記録とデータの両方から確認します。
説明
SOARは検知を起点に、情報の取得、条件分岐、承認、外部サービスへの操作をつなぎます。検知された端末名だけで措置を決めず、資産の重要度や操作範囲を確かめます。
SQLite内に資産とジョブを持つ対応手順モデルを使います。未知の資産、重要サーバー、一般端末の分岐を比較し、承認前後で資産状態が変わるかを調べます。
分岐、承認、実行、再試行、復旧の状態を記録とデータの両方から確認します。
1資産台帳を確認する
isolatedはこの教材の資産状態、versionは更新世代です。
from sp08 import *
from sp02 import show資産台帳を確認する
lab=Workflow()
show(lab.db,"SELECT * FROM asset ORDER BY id")ws7は一般端末、srv1は重要資産です。ここで使う更新対象はDB内の状態で、実製品の隔離APIとは別の手順モデルです。
2見つからない資産で処理を止める
台帳にないws9を検知した場合です。
print(lab.trigger見つからない資産で処理を止める('j9','ws9'))
show(lab.db,"SELECT id,asset,state FROM job")unknown_assetとして残ります。不明を低重要度へ読み替えて自動対応に進めません。
3重要資産を手動確認へ分岐させる
srv1の処理を作成します。
print(lab.trigger重要資産を手動確認へ分岐させる('j1','srv1'))
print(lab.approve('j1','responder'))manual_review、not_approvableです。この手順では通常の承認経路から重要資産を操作できません。例外対応には別の検討が必要です。
4一般端末の承認待ちを作成する
ws7のジョブを作成して現在状態を確認します。
print(lab.trigger一般端末の承認待ちを作成する('j7','ws7'))
show(lab.db,"SELECT id,asset,expected,state FROM job WHERE id='j7'")承認待ちと資産の世代1を保存します。後で別の操作が資産を変更した場合、古い判断で実行しないためです。
5承認前の実行を試す
実行用主体connectorでも承認が必要です。
print(lab.execute承認前の実行を試す('j7','connector'))
show(lab.db,"SELECT id,isolated,version FROM asset WHERE id='ws7'")not_approvedとなり、状態0、世代1のままです。起動元に実行権限があっても手順の承認条件は省略しません。
6閲覧者と対応者の承認を比較する
同じジョブへ別の主体で承認を試します。
print(lab.approve閲覧者と対応者の承認を比較する('j7','reader'))
print(lab.approve('j7','responder'))
show(lab.db,"SELECT state,approver FROM job WHERE id='j7'")readerは拒否、responderが承認します。承認者を記録し、後の実行主体とは分けて残します。
7実行結果と資産の状態を照合する
承認後に実行し、変更先を読み直します。
print(lab.execute実行結果と資産の状態を照合する('j7','connector'))
show(lab.db,"SELECT id,isolated,version FROM asset WHERE id='ws7'")
show(lab.db,"SELECT job,result FROM audit ORDER BY seq")状態1、世代2となり、appliedの監査が1行残ります。手順の成功表示だけでなく変更先の値も確認します。
まとめ
不足情報を正常や低重要度へ読み替えません。
承認者と実行主体を分けて記録します。
実行後は対象の状態を読み直します。
操作履歴と解説を振り返れます。
Python 3.15 / SQLiteの対応手順モデル
from sp08 import *
from sp02 import show
lab=Workflow()
show(lab.db,"SELECT * FROM asset ORDER BY id")id | critical | owner | isolated | version srv1 | 1 | team-b | 0 | 1 ws7 | 0 | team-a | 0 | 1
print(lab.trigger('j9','ws9'))
show(lab.db,"SELECT id,asset,state FROM job")unknown_asset id | asset | state j9 | ws9 | unknown_asset
print(lab.trigger('j1','srv1'))
print(lab.approve('j1','responder'))manual_review not_approvable
print(lab.trigger('j7','ws7'))
show(lab.db,"SELECT id,asset,expected,state FROM job WHERE id='j7'")awaiting_approval id | asset | expected | state j7 | ws7 | 1 | awaiting_approval
print(lab.execute('j7','connector'))
show(lab.db,"SELECT id,isolated,version FROM asset WHERE id='ws7'")not_approved id | isolated | version ws7 | 0 | 1
print(lab.approve('j7','reader'))
print(lab.approve('j7','responder'))
show(lab.db,"SELECT state,approver FROM job WHERE id='j7'")permission_denied approved state | approver approved | responder
print(lab.execute('j7','connector'))
show(lab.db,"SELECT id,isolated,version FROM asset WHERE id='ws7'")
show(lab.db,"SELECT job,result FROM audit ORDER BY seq")applied id | isolated | version ws7 | 1 | 2 job | result j7 | applied
演習完了