AIツールの引数と実行権限の検証
承認を一つのフラグにせず、主体と具体的な操作へ対応付けます。
説明
モデルが提案したツール要求は、実行してよいという承認ではありません。操作名、引数の型、利用者の権限、承認した内容との一致を、実行する直前に確認します。
文書更新ツールの固定要求を使います。承認後に対象・本文・版を変えた要求、期限切れ、再利用を試し、DBの更新件数と記録を照合します。
承認を一つのフラグにせず、主体と具体的な操作へ対応付けます。
1対象と認証主体を用意する
aliceの文書7とbobの文書8があります。主体名は認証結果から渡す条件です。
from sd15 import *
lab = Tools()
args =具体的なツール要求を用意する {"operation":"update","id":7,"body":"v2","version":1}
print(lab.db.execute("SELECT * FROM docs ORDER BY id").fetchall())文書7だけがaliceの更新対象です。モデルの引数にownerを追加して主体を上書きさせる設計にはしません。
2型と操作名を実行前に検査する
余分なownerと未定義のdeleteを比較します。
print(lab.execute("alice",dict(args,owner=主体を上書きする余分な項目を試す"bob"),0))
print(lab.execute("alice",dict(args,operation="delete"),0))どちらもschema_rejectedです。必要なキーと操作だけを受け付けます。
3承認前の要求と別主体の承認を拒否する
正しい形式でも未承認なら更新しません。
print(lab.execute承認を持たない実行を試す("alice",args,0))
print(lab.approve("bob"別主体で対象を承認しようとする,args,30))approval_rejectedとpermission_rejectedです。形式が正しいこと、操作権限があること、承認があることは別の条件です。
4主体と全引数を含む承認を保存する
aliceがこの要求を時刻30まで承認します。
approval = lab.approve("alice",args,30)具体的な内容と期限を承認へ保存する
print(len(approval))
print(lab.db.execute("SELECT subject,expires,used FROM approvals").fetchall())64桁のハッシュへ主体と全引数を結び付け、未使用として保存しています。承認情報は信頼するサーバー側で保持します。
5承認後の対象と本文の差替えを拒否する
文書8への変更と、本文v3への変更を試します。
print(lab.execute("alice",dict(args,id=8)承認済み対象を変える,10))
print(lab.execute("alice",dict(args,body="v3")承認済み本文を変える,10))
print(lab.db.execute("SELECT id,body FROM docs ORDER BY id").fetchall())両方approval_rejectedで元の本文を保ちます。承認した更新と、実際に渡された引数が一致していません。
6期限境界で拒否し、期限内に一度だけ更新する
まず時刻30の要求を拒否し、固定時刻29の独立した要求条件を評価します。
print(lab.execute("alice",args,30期限ちょうどを比較する))
print(lab.execute("alice",args,29期限内と使用済みの条件を比較する))
print(lab.execute("alice",args,29))期限ちょうどは拒否、29はupdated、その再利用は拒否です。時刻を巻き戻す運用ではなく、同じ保存試料へ期限条件を個別に与える比較です。
7成功した変更と対象外の状態を照合する
更新された文書とイベント、消費済み承認を読みます。
print(lab.db.execute("SELECT * FROM docs ORDER BY id").fetchall())
print(lab.db.execute("SELECT * FROM events確定した実行の件数を調べる").fetchall())
print(lab.db.execute("SELECT used FROM approvals").fetchone())文書7はv2・版2、文書8は元のまま、更新記録は1件です。承認消費と更新を同じトランザクションで確定しました。
まとめ
モデルの提案へschema・認可・承認の検査を適用します。
承認を主体と全引数へ結び付けます。
更新と承認の消費を一体で確定します。
操作履歴と解説を振り返れます。
Python 3.15 / 固定の公開試料
from sd15 import *
lab = Tools()
args = {"operation":"update","id":7,"body":"v2","version":1}
print(lab.db.execute("SELECT * FROM docs ORDER BY id").fetchall())[(7, 'alice', 'v1', 1), (8, 'bob', 'private', 1)]
print(lab.execute("alice",dict(args,owner="bob"),0))
print(lab.execute("alice",dict(args,operation="delete"),0))schema_rejected schema_rejected
print(lab.execute("alice",args,0))
print(lab.approve("bob",args,30))approval_rejected permission_rejected
approval = lab.approve("alice",args,30)
print(len(approval))
print(lab.db.execute("SELECT subject,expires,used FROM approvals").fetchall())64
[('alice', 30, 0)]print(lab.execute("alice",dict(args,id=8),10))
print(lab.execute("alice",dict(args,body="v3"),10))
print(lab.db.execute("SELECT id,body FROM docs ORDER BY id").fetchall())approval_rejected approval_rejected [(7, 'v1'), (8, 'private')]
print(lab.execute("alice",args,30))
print(lab.execute("alice",args,29))
print(lab.execute("alice",args,29))approval_rejected updated approval_rejected
print(lab.db.execute("SELECT * FROM docs ORDER BY id").fetchall())
print(lab.db.execute("SELECT * FROM events").fetchall())
print(lab.db.execute("SELECT used FROM approvals").fetchone())[(7, 'alice', 'v2', 2), (8, 'bob', 'private', 1)]
[('updated', 7)]
(1,)演習完了