agentic-wallet-guardian-v3 について
Agentic Wallet Guardianは、AIエージェントの取引を署名またはブロードキャスト前に評価し、理由付きのALLOW、WARN、BLOCKを返すセルフホスト型サービスです。取引ルールとデータを自ら管理したいチーム向けに、ローカルのポリシーとデータソースを利用します。
主な機能
- 01実行前の取引意図評価と理由の提示
- 02ウォレット、コントラクト、トークン情報によるリスク信号の生成
- 03ローカルの脅威リストとポリシールールの利用
- 04取引シミュレーションと一部取引の構築
- 05メモリ、SQLite、PostgreSQLへの保存
活用シーン
- 01オンチェーン取引の署名前にエージェント要求を確認
- 02ローカルルールで取引を制限し、確認対象を指定
- 03ブラウザデモでリスク信号と適用ルールを確認
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| chain | string | はい | |
| amount | any | いいえ | |
| target | any | いいえ | |
| wallet | string | はい | |
| agent_id | string | はい | |
| to_token | any | いいえ | |
| from_token | any | いいえ | |
| action_type | string | はい |
詳細
Agentic Wallet Guardian
デモを見る
プレビューを選択すると、ブラウザーで動画を再生できます。
AI エージェントがウォレットを無制限に操作できるようにせず、オンチェーン取引を可能にします。 Guardian は署名またはブロードキャストの前に提案された各操作を評価し、説明可能な ALLOW / WARN / BLOCK の判定を返します。
POST /decision -> ALLOW / WARN / BLOCK (with a reasoned explanation)
これは独自のインフラストラクチャ上で動作し、独自のポリシールールと 独自の評判データを使用します。その重要性と、ホスト型セキュリティ API を 直接呼び出す方法との違いについては、セルフホスト可能な理由をご覧ください。
Guardian はチェーンやユースケースに依存しません。以下の Arc/USDC は稼働中の デプロイ例の 1 つであり、適用範囲のすべてではありません。この投稿が対象とする トラックとその理由については、docs/hackathons.mdをご覧ください。
Arc Mainnet デモ
ライブデモ: http://77.239.125.37:8765/arc
デモ動画: https://youtu.be/srH0ZLwtwqQ
Agentic Wallet Guardian は Arc mainnet にデプロイされており、USDC 決済用のライブブラウザーデモを備えています。Guardian は実行前に要求された操作を評価してセキュリティポリシーを適用し、承認された操作のみをユーザーのウォレットに渡して署名します。
検証済み Arc mainnet トランザクション: 0xd781e8b04b5ca89c3a34fcec50a6636049f7647d2b0e1b2bb64d5b1ee54daadf
このトランザクションは、Guardian デモを通じて USDC を使用し、Arc mainnet 上で正常に実行されました。
判定をリアルタイムで確認: API をローカルで実行し(GUARDIAN_ENABLE_CORS_FOR_BROWSER_DEMO=true uvicorn api.main:app --reload)、ブラウザーでexamples/browser-demo.htmlを開きます。ビルド手順は不要で、ページ自体を提供するサーバーも必要ありません。各シナリオボタンは、実行中のインスタンスに実際の POST /decision を送信し、実際のレスポンス(リスクスコア、その算出に使われたすべてのシグナル、適用されたすべてのポリシールール)を表示します。ページ内にスクリプト化されたものや偽装されたものはありません。GUARDIAN_ENABLE_CORS_FOR_BROWSER_DEMO はデフォルトでオフになっています(guardian/config.py を参照)。これはこのローカルデモ専用であり、実際のデプロイで有効にしたままにするものではありません。
セルフホストする理由
エージェントのトランザクションセキュリティには、優れたホスト型の代替サービスがあります(GoPlus の AgentGuard、Blockaid、コンプライアンス向けの Chainalysis/TRM など)。リスクスコアだけが必要で、クエリを誰が見るかを気にしないのであれば、これを運用するより、そうしたサービスに直接問い合わせるほうが手間はかかりません。Guardian は、そうしたトレードオフが合わないケースのためにあります。
- エージェントが操作するウォレット、コントラクト、金額に関する情報が、インフラの外に出ることはありません。 脅威インテリジェンスやコントラクトの許可・拒否チェックには、自分で用意するローカルの JSON ファイルを使用します(
data/threat_lists/README.mdを参照)。サードパーティへの照会は行いません。ホスト型 API では、問い合わせるすべてのアドレスと金額が必然的に把握されます。 - ポリシールールはベンダーのダッシュボードではなく、コード内で管理できます。 支出上限、レピュテーションのしきい値、確認が必要なアクションの種類は、
guardian/policy/内の通常の Python コードなので、他社の製品ロードマップを待たずにレビューや変更ができます。 - 他社が設定する呼び出しごとの料金やレート制限はありません。 自分のユーザー向けに設定するもの(
GUARDIAN_RATE_LIMIT_PER_MINUTE)だけです。 - ベンダーロックインはありません。 外部データソース(RPC エンドポイント、Blockscout インスタンス、DexScreener)はすべて、小規模なプロバイダーインターフェースの背後で入れ替えられます。アーキテクチャを参照してください。
逆の選択をする場合のトレードオフも率直にお伝えします。運用とローカルの脅威リストの更新は自分で行う必要があり、ホスト型ベンダーのチェーン対応範囲や専門の脅威調査チームを無料で利用することもできません。これは、データ主権や詳細なポリシーのカスタマイズを特に必要とするチームに適した選択肢であり、あらゆるホスト型サービスを必ず上回る選択肢ではありません。
アーキテクチャ
AI Agent
|
v
Action Intent
{ agent_id, wallet, chain, action_type,
target, amount, metadata }
|
v
┌───────────────────────────────┐
│ Guardian Decision Engine │
├───────────────────────────────┤
│ 1. Hard Rules │ <- chain support, sanity checks
│ 2. Wallet Intelligence │ <- mock | real RPC (web3.py)
│ 3. Token Intelligence │ <- mock | real DexScreener | real GoPlus
│ 4. Contract Intelligence │ <- local lists, then mock | real Blockscout | real GoPlus
│ 5. Simulation │ <- mock | real eth_call dry-run (see below)
│ 6. Threat Intelligence │ <- local JSON allow/deny lists
│ 7. Anomaly Detection │ <- vs. this agent's own history (see below)
│ 8. Policy Engine │ <- spending caps, reputation gates
│ 9. Risk Fusion │ <- signals -> single 0-100 score
│ 10. Reputation Adjustment │
│ 11. Explanation │ <- evidence -> human-readable reasons
└───────────────────────────────┘
|
v
ALLOW / WARN / BLOCK
|
v
Blockchain Execution
手順 2〜4 の各データソースは、小規模なプロバイダーインターフェースで構成されています。モック実装(設定不要、ネットワーク呼び出しなし)と実際の実装があり、環境変数でデータソースごとに選択します。.env.example を参照してください。デモモードから実運用への切り替えは、コードの変更ではなく設定の変更で行えます。
リポジトリの構成
guardian/
config.py GuardianConfig - the one place that reads os.environ
core/ ActionIntent, Signal, Decision, EvaluationContext
(zero external dependencies - no pydantic/FastAPI)
decision/ DecisionEngine (orchestrator), RiskFusionEngine, hard rules
reasoning/ explanation + confidence builders
intelligence/
wallet/ analyzer.py + providers.py (mock | RpcWalletDataProvider)
token/ analyzer.py + providers.py (mock | DexScreenerTokenDataProvider | GoPlusTokenDataProvider)
contract/ analyzer.py + providers.py (mock | BlockscoutContractDataProvider | GoPlusContractDataProvider)
simulation/ pre-execution dry-run (mock | real eth_call) + tx_builder.py (real calldata for transfer/approve)
goplus_client.py shared GoPlus Token Security API client (used by both contract + token)
threat/ blocklist.py (local AddressList) + intelligence.py
policy/ PolicyEngine + policy templates (spending caps, reputation gates)
reputation/ AgentReputation (score derived from decision history)
memory/ storage.py (protocol) + InMemoryStorage + sqlite_storage.py
api/
main.py FastAPI app: /decision, /health, /capabilities, /agents/{id}/history, /demo/{scenario}
security.py API-key auth dependency + rate-limit middleware
schemas.py pydantic request/response models (API boundary only)
mcp_server.py MCP stdio server - same DecisionEngine, no HTTP required
data/threat_lists/ local, operator-maintained allow/deny lists (empty by default - see its README)
scripts/
refresh_ofac_list.py fetch OFAC's public SDN list into the local threat list
tests/ 101 tests covering the engine, policy, reputation, and every provider
guardian/* は意図的に依存関係なし(標準ライブラリのみ。実プロバイダーが httpx または web3 を必要とする場合を除く)としているため、判断コアを単体テストしたり、別のサービスに組み込んだり、FastAPI を持ち込まずに別の Web フレームワークへ移植したりできます。pydantic/FastAPI に触れるのは api/ のみです。
現状についての率直な説明
これは、実際に動作し、テスト済みの判断インフラであり、シグナルソースごとに実データソース(モックではない)も利用できます。ただし、「利用可能」であることは、「スイッチを入れたら、何も考えずに信頼してよい」という意味ではありません。詳細は以下のとおりです。
- ウォレット(RPC プロバイダー):
is_contractとtx_count(ナンスベース)は、どの JSON-RPC エンドポイントでも信頼できます。ウォレットの 経過期間 の確認にはアーカイブ対応ノードが必要で、デフォルトでは無効です(GUARDIAN_RPC_ESTIMATE_AGE=false)。ほとんどの無料の公開 RPC エンドポイントは過去の状態を提供しないため、推測するのではなく「不明」として安全側に処理します。 - コントラクト(Blockscout プロバイダー): 公開 Blockscout インスタンスに対して、検証ステータスを実際に照会します。正確なレスポンススキーマやレート制限は変更される可能性があります。予期しないレスポンスがあれば「不明」にフォールバックし、決して回答を捏造しないよう実装されていますが、本番トラフィックでの負荷テストはまだ実施していません。
- トークン(DexScreener プロバイダー): 実際の流動性データを取得しますが、単独のティッカーシンボルをオンチェーンのペアに対応付けるのは、本質的に曖昧です(無関係な多数のトークンが同じシンボルを共有しており、詐欺師が意図的に似たトークンを発行することもあります)。プロバイダーは、指定されたチェーン上で最も流動性の高いペアを選び、推測を確実なものとして提示するのではなく、その照合自体の信頼度を報告します。この曖昧さが重要なケースでは、シンボルではなくコントラクトアドレスで照合してください。
- コントラクト+トークン(GoPlus プロバイダー): GoPlus の Token Security API から、実際のコントラクトセキュリティ(所有者による資金流出、ミント可能性、自己破壊、隠れた所有者)と取引セキュリティ(ハニーポット、売買税、ブラックリスト、送金の一時停止可能性、保有者の集中度)を取得します。GoPlus 独自の静的解析で両方を一度に確認するため、Blockscout/DexScreener が個別に提供するものより、意味のあるシグナルの種類が多くなります。実際の制限が 2 つあります。データがあるのは実際に解析済みのコントラクトのみ(主にトークンコントラクトで、汎用的な dApp/ルーターのコントラクトは対象外)であり、
GoPlusTokenDataProviderにはコントラクト アドレス が必要です。「PEPE」のような単独のシンボルは解決できないため、推測するのではなく、検証不能であると正直に報告します。 - 制裁対象アドレスリストには実データが登録されています: OFAC の SDN リストに基づく 103 件のアドレス(EVM が 100 件、Solana が 3 件)を、0xB10C/ofac-sanctioned-digital-currency-addresses から取得しています。実際に制裁対象であることが既知のアドレスが、パイプライン全体を通じて正しく
BLOCKを発生させることを確認済みです。また、追加だけでなく削除も正しく反映されることも確認済みです(2025 年 3 月に SDN リストから削除された Tornado Cash のアドレスは、正しくリストに含まれていません)。制裁対象は追加・削除のどちらもあり得るため、定期的にscripts/refresh_ofac_list.pyを再実行してください。 malicious_contracts.json/verified_contracts.jsonは、意図的に空の状態で同梱されています(data/threat_lists/README.mdを参照)。OFAC のリストのように「悪意のあるコントラクト」を示す唯一の権威ある情報源はありません。そのため、これらのリストを登録するかどうかは、このインスタンスの運用者が判断することであり、未検証のエントリーをデフォルトで登録するものではありません。- シミュレーションは実際に機能しますが、条件付きです。
RpcSimulationProvider(GUARDIAN_SIMULATION_PROVIDER=rpc)は、現在のチェーン状態に対してeth_call/eth_estimateGasを使ってトランザクションを実際にドライランします。リバートした場合は推測ではなく実際の理由が返され、ERC-20 のapprove()の金額も推定ではなく実際の calldata からデコードされます。呼び出し元がintent.metadata["data"]経由で生の calldata を渡した場合、または(新機能として)GUARDIAN_TX_BUILDER=rpcも設定されており、インテントが単純なtransferまたはapproveの場合に有効になります(次の箇条書きを参照)。まだトランザクションが構築されていないswapインテントには、ドライランの対象がありません。この場合、Guardian は推測せず、その事実を正直に報告します(simulation_not_attempted)。 - トランザクション構築はこのギャップの一部を意図的に解消しますが、すべてではありません。
RpcTransactionBuilder(GUARDIAN_TX_BUILDER=rpc)は、意味的なtransfer/approveインテントを実際の calldata に変換します。18 と仮定するのではなく、RPC 経由でトークンの実際のdecimals()を取得します(誤った仮定をすると、金額が桁違いになるためです)。また、意図的にトークンアドレスのハードコード済みレジストリを持ちません。「USDC」のような単独のシンボルは、推測せずに拒否します。ここで誤ったアドレスを使うと、リスクシグナルが不正確になるだけでなく、実際のトランザクションに使われる可能性のある成果物が生成されてしまうためです。swapは Uniswap V2 Router02 のみを対象に構築します(不変で広く知られた 1 つのコントラクトです。関数セレクターは記憶に頼って転記するのではなく、Web3.keccakでローカル計算します)。オンチェーンで実際にgetAmountsOut()を使って見積もり、呼び出し元がmax_slippage_bpsを指定する必要があります(デフォルト値は設定しません。前述のdecimalsと同じ理由です)。一般にbridgeは、L2 とブリッジの経路を扱う範囲の広い問題です。プロトコルが数十種類あり、信頼モデルも大きく異なります。ただし、このモジュールでは対象を明確に限定し、宛先チェーン自身が提供する公式 OP Stack ブリッジ経由の L1 → L2 入金を扱います(現在の対象は Base と Optimism です。L1StandardBridgeのdepositETHTo/depositERC20Toを使用します。両方のアドレスはハードコード前に独立して照合済みです。Base は Etherscan のラベルと basehub.org、Optimism は公式の ethereum-optimism/superchain-registry と独立した開発ツール設定で確認しています)。 L2 → L1 の出金は構築しません。入金呼び出しの変種ではなく、証明とチャレンジ期間を要する、まったく異なる、はるかに時間のかかるフローだからです。 それ以外の場所へのブリッジ、または非正規ブリッジ経由の処理は、推測せずNoneを返します。 - インテント検証で、フラグを立てるだけでなく、実際に強制できるようになりました。
decision/intent_verification.pyは、エージェントが申告したapproveの金額と、シミュレーション済み calldata が実際にエンコードしている金額を比較します。ただし、この比較には、人間向けの単位と最小単位を変換するためのトークンのdecimals()が必要です。GUARDIAN_DECIMALS_PROVIDER=rpc(RpcTokenDecimalsProvider。guardian/intelligence/token/decimals.pyを参照)を設定すると、eth_call経由で実際の値を取得します。デプロイ済みコントラクトのdecimals()は変更できないため、(チェーン、トークン)の組み合わせごとに取得結果を無期限にキャッシュします。デフォルトのnullのままの場合、本来であればこのモジュールで検出できる不一致も、正直に「検証できない」という WARN にフォールバックします。これはこのモジュールのほかの箇所と同じ「黙って推測しない」というルールであり、見落とされた制限ではありません。RpcTransactionBuilderとRpcTokenDecimalsProviderの両方を実際のプロバイダーで設定した場合、同じキャッシュを共有します。同じトークンを個別に、キャッシュせずに照会することはありません。 - ストレージ:
InMemoryStorage(デフォルト、設定不要)、SQLiteStorage(GUARDIAN_STORAGE_BACKEND=sqlite。再起動後もデータが保持され、外部インフラは不要)、またはPostgresStorage(GUARDIAN_STORAGE_BACKEND=postgresとGUARDIAN_POSTGRES_DSNを設定。負荷分散装置の背後に複数のレプリカを配置する場合に適しています。その場合、SQLite の単一書き込み元モデルがボトルネックになります。pip install -r requirements-postgres.txt)。モックではなく、実際のローカル Postgres インスタンスでテスト済みです。tests/test_postgres_storage.pyを参照してください。Redis にも引き続き対応できます。2 つのメソッドだけを持つMemoryBackendインターフェースは小さいため、どのようなものに対しても実装できます。 - API 認証/レート制限 は意図的に最小限です。マルチテナントゲートウェイではなく、自分のネットワーク境界の内側でセルフホストする単一インスタンス向けに構築されています。必要であれば、その前段に実際の API ゲートウェイを配置してください。
- セキュリティ監査は未実施です。 ポリシーエンジンとリスク融合ロジックは、このリポジトリの外部の誰からもレビューされていません。レビューが完了するまでは、
BLOCKを強いシグナルとして扱い、保証としては扱わないでください。Signal以降のすべて(フュージョン、ポリシー、レピュテーション、説明、API)は、上記の内容がさらに強化されても変更する必要はありません。この境界が、ここでの実際の設計契約です。
クイックスタート
設定不要のデモモード(モックプロバイダー、インメモリストレージ、認証なし):
pip install -r requirements.txt
uvicorn api.main:app --reload
または Docker を使う場合:
docker compose up --build
用意されているシナリオを試します:
curl http://localhost:8000/demo/safe
curl http://localhost:8000/demo/unknown
curl http://localhost:8000/demo/malicious
または独自のインテントを送信します:
curl -X POST http://localhost:8000/decision \
-H "Content-Type: application/json" \
-d '{
"agent_id": "trading-agent-001",
"wallet": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": "ethereum",
"action_type": "swap",
"from_token": "ETH",
"to_token": "USDC",
"amount": 5
}'
デモから実際のセルフホスト可能なデプロイへの移行
.env.example を .env にコピーして調整します:
cp .env.example .env
実際のデプロイで最低限必要な設定は、GUARDIAN_API_KEY(デフォルトでは認証は無効)、GUARDIAN_STORAGE_BACKEND=sqlite(永続化)、およびモックではなく実際のデータを参照させたい GUARDIAN_*_PROVIDER 変数です。各オプションについては .env.example のコメントを、各プロバイダーから実際に得られる内容については RpcWalletDataProvider/BlockscoutContractDataProvider/DexScreenerTokenDataProvider/GoPlusContractDataProvider/GoPlusTokenDataProvider の docstring を参照してください。
複数のエージェントがこのデプロイを共有する場合は、GUARDIAN_AGENT_API_KEYS も設定してください(形式:agent_id:key,agent_id2:key2)。GUARDIAN_API_KEY だけでは、呼び出し元が有効なキーを持っていることは確認できますが、リクエストが実際にどの agent_id から来たのかは確認できません。agent_id はリクエスト本文のフィールドにすぎないためです。共有キーを持つ人は誰でも任意の agent_id を送信し、その agent_id に蓄積されたレピュテーションや機能付与を引き継ぐことができます。GUARDIAN_AGENT_API_KEYS を設定すると、各 agent_id がそれぞれのキーに紐付けられます。GUARDIAN_API_KEY も設定した場合は、管理やテスト用のマスターキーとして、任意のエージェントに対して引き続き使用できます。実質的に単一エージェントのデプロイであれば、GUARDIAN_API_KEY だけで問題ありません。
MCP(HTTP 不要)
MCP に対応したエージェントフレームワーク(LangChain、CrewAI、Claude Desktop など)では、mcp_server.py が同じ意思決定エンジンを stdio 経由で 2 つのツール(evaluate_action、get_agent_history)として公開します。requirements.txt と併せて requirements-mcp.txt をインストールし(同じ環境にインストールされます。requirements-mcp.txt の先頭にあるコメントを参照してください)、MCP クライアントから python mcp_server.py を指定してください。
Arc メインネット決済デモ
Guardian 3.2 では、自律的な USDC 決済のための、小規模で非カストディアルな Arc メインネット機能が追加されました。
- Arc メインネット、チェーン ID 5042、公式 RPC
https://rpc.mainnet.arc.io - Arc USDC の ERC-20 インターフェース
0x3600000000000000000000000000000000000000(小数点以下 6 桁) - Guardian はトランザクションを解放する前に、通常のハードルール、インテリジェンス、シミュレーション、ポリシー、リスクのパイプラインを実行します
- デモポリシーでは、自律決済の上限を 5 USDC とし、この機能上での approve/swap/bridge/contract-call アクションをブロックします
- 署名可能なトランザクションが生成されるのは
ALLOW判定の場合のみです。署名を行うのは引き続きブラウザーウォレットだけです - 公開デモでは、訪問者のトラフィックによってエージェントごとのメモリーキーが無制限に作成されないよう、履歴 ID を
arc-demo-agent1 つに制限しています - 実行中のインスタンスで
/arcを開くと、ウォレットを接続し、Guardian に依頼して、生成された Arc 決済に署名できます
Arc の手動検証:
python scripts/verify_arc_mainnet.py
このスクリプトは、チェーン ID、最新のブロック高、ガス価格、メインネット上の USDC に対する decimals() 呼び出しを確認します。秘密鍵は不要です。
テストの実行
pip install -r requirements.txt -r requirements-chain.txt -r requirements-mcp.txt
pytest -q
RPC およびオンチェーンアテステーションのテストには requirements-chain.txt(web3)が必要です。requirements-mcp.txt は mcp_server.py が使用する MCP SDK をインストールします。OAA アテステーションでは JWT と Ed25519 署名を使用するため、PyJWT と cryptography はコア依存関係です。CI でのインストールは、この完全なテスト環境と一致しています。
PYTHONPATH=. python3 -m unittest discover -s tests -v
CI(.github/workflows/ci.yml)は、push/PR のたびに Python 3.11 および 3.12 で全テストスイートを実行します。
署名付きの検証可能な判断(OAA)
このサービスが返すすべての判断は、単一のポリシーチェックから パイプライン全体に至るまで、OAA(Open Agent Attestation) トークンとして署名されます。これは、判断、アクション、理由を 内包した Ed25519 署名付き JWT です。
公開鍵を持つ人なら誰でも、判断をオフラインで検証できます。Guardian を 発行したインスタンスに問い合わせる必要はありません。監査担当者や 下流サービスにとって有用であり、後で判断を信頼したい場合にも、 それを生成したサーバーを信頼せずに済みます。
python examples/example_oaa_attestation.py
python examples/example_full_pipeline.py # capability -> intent -> engine -> OAA
リファレンス OAA 実装は約150行(上流の oaa.py/attestation.py)で、
このプロジェクトとagent-guardrailで
共有されており、変更されていません。同じ署名形式、同じ検証経路で、
プロジェクトごとのフォークはありません。
MetaMask Agent Wallet の前段で Guardian を使用する
MetaMask Agent Wallet の Guard Mode/Beast Mode は、すべてのエージェントに
同じ静的な支出上限と許可リストを適用します。Guardian はその前段で、
独立した二次チェックを行います。mm CLI が呼び出される前に、
この特定のアクションは、このエージェントにとって、今この時点で
適切かどうかを確認します。
skills/guardian-check/は標準の
Agent Skillです。MetaMask 自身が mm に使用しているもの
(npx skills add MetaMask/agent-skills)と同じオープン形式です。
Agent Skills 互換のランタイム(Claude Code、Cursor、Codex、OpenClaw)に
MetaMask 独自のスキルと一緒にインストールすると、エージェントは
資金を移動する mm コマンド(mm send、mm swap、mm bridge、mm perps、mm predict trade、mm earn、mm aave、mm pay)を実行する前に、
稼働中の Guardian インスタンスに問い合わせて ALLOW/WARN/BLOCK の判断を
受け取ります。
Guardian は秘密鍵を保持せず、何も実行しません。署名やブロードキャストを
行うのは、引き続き mm だけです。これは、エージェントにまず確認するよう
指示された判断ゲートであり、MetaMask 独自のパイプラインを変更するものでは
ありません(現時点では、そのための公開フックはありません)。
uvicorn api.main:app --reload # run Guardian locally
export GUARDIAN_API_URL="http://localhost:8000"
python skills/guardian-check/scripts/check.py \
--agent-id my-agent --wallet 0x... --chain ethereum \
--action-type transfer --target 0x... --amount 50
助言から強制へ:GuardianValidator
ここまでの内容はすべて助言です。Guardian は ALLOW/WARN/BLOCK を通知しますが、
それを尊重するかどうかは呼び出し側が選ぶ必要があります。onchain/は、
その隔たりを埋める ERC-4337 スマートアカウント向けの実際の ERC-7579
バリデーターモジュールです。インストールすると、信頼された Guardian の署名者が
その正確な UserOperation に対して ALLOW と判断したことを証明しない限り、
アカウントの UserOperation がチェーンに到達することはありません。
エージェントが確認を省略したり、回答を無視したりすることはできません。
OAA と併せて2つ目の EVM ネイティブな署名形式が必要な理由(Ed25519 には
EVM プリコンパイルがなく、純粋な Solidity で検証すると約2,000,000 gas
かかる一方、このモジュールの validateUserOp 全体では27k~59k gas)、
意図的に対象外としている事項(WARN はオンチェーンで決して通過しないこと、
専門家による監査がまだないこと)、ビルド、テスト、デプロイ方法については、
onchain/README.mdを参照してください。また、実際に
稼働する Python(guardian/onchain_attestation.py)が生成した署名を、
互いにしか整合しない2つの実装ではなく、実際の Solidity コントラクトが受け入れることを
検証するテストについても説明しています。
ロードマップ
モックのウォレット/トークン/コントラクトアナライザーを実際のデータソースに置き換える。完了 — 各ソースで「実際のデータ」が現時点でどこまでカバーしているかについては、現在の状態について正直に説明を参照してください。実際の実行前シミュレーションを接続する。transfer/approveはエンドツーエンドで完了(GUARDIAN_SIMULATION_PROVIDER=rpc+GUARDIAN_TX_BUILDER=rpc— 現在の状態について正直に説明を参照)。Uniswap V2 Router02 で完了 — 実際のオンチェーンswapには実際の DEX ルーティングが必要。getAmountsOut()見積もり、呼び出し元が明示的に指定するmax_slippage_bps(デフォルト値は決して設定されません)、実際の見積もりなしには calldata を構築しません。構築中に見つかった実際のバグも修正しました。シミュレーションが、呼び出される実際のコントラクト(from_token)ではなく、intent.target(ERC-20 calldata 内にエンコードされた受取人/使用者)に対してドライランを実行していたため、実際の呼び出しがリバートするかどうかに関係なく、あらゆる EOA 受取人への transfer/approve シミュレーションが黙って「成功」していました。BuiltTransactionに明示的なtoが追加されました。この問題を検出できた回帰テストについては、tests/test_tx_builder.pyを参照してください。Base と Optimism への L1->L2 デポジットについては、公式 OP Stack のbridgeは未対応。L1StandardBridge(depositETHTo/depositERC20To)を使用して完了しています。他の宛先、他のブリッジプロトコル、L2->L1 出金はすべて未対応です。現在の状態について正直に説明を参照してください。脅威インテリジェンス/制裁フィードを用意し、空のセットを同梱するのをやめる。制裁については完了(sanctioned_addresses.json— OFAC SDN の実際のアドレス 103 件。scripts/refresh_ofac_list.pyで更新可能)。malicious_contracts.json/verified_contracts.jsonは、制裁における OFAC リストのように登録元として使える単一の権威ある情報源が存在しないため、意図的に空のままです。InMemoryStorageを永続バックエンドに置き換える。SQLiteStorageを利用できます。マルチレプリカ環境向けの Postgres/Redis バックエンドは未対応。PostgresStorageは完了 — 実際のローカル Postgres インスタンスに対してテスト済み(tests/test_postgres_storage.py)。他のバックエンドと同じ 2 メソッドのMemoryBackendインターフェースを備えています。明確な要望があれば Redis も対応予定です。MCP サーバーのラッパーを追加する。完了(mcp_server.py)。REST API の上に構築する、パッケージ化された Python/TypeScript SDK は未対応です。- OpenAPI 仕様とホスト型デモエンドポイントを公開する。
- 本番環境で誰かがこのサービスの
BLOCKに依存する前に、ポリシーエンジンとリスク統合のレビュー/監査を受ける — セキュリティツールなので、他者に適用するのと同等の厳しい審査が必要です。 エージェントごとの機能制限を追加する(委譲スコープの設定)。完了 —guardian/policy/capabilities.pyを追加し、オプションのcapability_registryコンストラクター引数を通じてDecisionEngine.evaluate()に接続しました(以前は独立したモジュールで、通常のパイプラインの外部から自分で呼び出す必要がありました。現在はDecisionEngineを直接経由するexamples/example_capability_limits.pyを参照してください)。オプトイン方式です。レジストリを渡さなければ(デフォルト)、何も変わりません。オペレーターは、秘密鍵情報を一切使わずに、特定のエージェントにスコープ付きの機能(許可するアクションタイプ、許可するチェーン、アクションごとおよび日ごとの支出上限、有効期限)を付与できます。権限を付与されていないエージェントには影響しません。このモジュールが秘密鍵やセッションキーの発行自体に触れることはありません — それは対象範囲外であり、はるかに重大な問題です。エージェントが決定を尊重するかどうかに依存しない、決定の実際の強制は、意図的に対象範囲外です。部分的に完了 —onchain/のGuardianValidatorは ERC-7579 モジュールです。これをインストールした ERC-4337 スマートアカウントでは、Guardian が鍵を保持することなく、決定を実際に回避不可能にします。セッションキーの管理、カストディ、アカウント作成は行いません — アテステーションを通じて実行を制御するだけです。そのため、これは「アカウント抽象化」の実際に重要な構成要素ですが、全体ではありません。宣言されたインテントをデコード済みのシミュレーション結果と照合する。完了 —guardian/decision/intent_verification.pyは、エージェントが申告した金額と、実際に渡された calldata にエンコードされた、意味のある差がある(ただし有限の)金額が異なるケースを検出します。また、DecisionEngine.evaluate()から実際に呼び出すようになりました(以前はそうなっていませんでした — モジュールとサンプルスクリプトは存在していましたが、実際の意思決定パイプラインでは何も呼び出していませんでした)。ただし、これ単独ではまだ有効なガードレールではありません。最小単位を比較するにはトークンのdecimals()が必要ですが、decimals プロバイダーはまだありません。GUARDIAN_DECIMALS_PROVIDER=rpc(RpcTokenDecimalsProvider、guardian/intelligence/token/decimals.pyを参照)で解決します。トークン自身のdecimals()を実際にeth_callし、その値はコントラクトのデプロイ後に変更できないため、(チェーン、トークン)の組み合わせごとに無期限でキャッシュします。デフォルトのnullのままの場合、シミュレーションが成功し、有限の金額が設定されているapproveはすべて、偽の BLOCK を返すことも黙って確認をスキップすることもなく、「decimals がないため検証できません」という正直な WARN になります。実際のプロバイダーを設定すると、本当の不一致に対して実際に BLOCK するようになります。実際の不一致をブロックするチェックについてはexamples/example_intent_verification.pyを参照してください。また、手動で渡したtoken_decimals引数ではなく、実際の(RPC をモックした)decimals の参照を通じてエンドツーエンドで接続する例については、tests/test_decision_engine.pyのTestIntentVerificationWithRealDecimalsProviderを参照してください。エージェント自身の過去のパターンから逸脱するアクションにフラグを立てる。完了 —guardian/intelligence/anomaly/analyzer.py。単一の信頼スコアであるレピュテーションや、オペレーターが設定する静的な制限であるポリシーとは異なり、現在のインテントをこの特定のエージェント自身が記録した履歴と比較します。新しいアクションタイプ、新しいチェーン、またはこのエージェントが過去に行ったアクションと比較して統計的に外れた金額を検出します。ポリシー制限内で、エージェントのレピュテーションに問題がなくても検出されます。過去のデータが 5 件未満の場合は基準を推測せず、「履歴が不十分」と正直に報告します。tests/test_anomaly_detection.pyを参照してください。汎用 API 呼び出し元からインテントを受け付けるだけでなく、実際のエージェントウォレットの前段に配置する。MetaMask Agent Wallet 向けに完了 —skills/guardian-check/は、エージェントが MetaMask 独自のmmスキルと一緒にインストールする標準 Agent Skill です。エージェントは資金を移動するmmコマンドを実行する前にこれを呼び出し、ALLOW の場合にのみ続行します。稼働中のuvicornインスタンスを使ったエンドツーエンドテストも実施済みです(ALLOW/WARN/BLOCK/設定エラーを、単にアサーションするのではなく実際にすべて確認しました)。上記の「MetaMask Agent Wallet の前段で Guardian を使う」セクションを参照してください。MetaMask 自身のパイプライン内で動作する公開フックは(まだ)ありません。代わりに、エージェントオーケストレーション層で動作します。
関連プロジェクト
同じ作者が、同じ原則を別の領域に適用しています。
- agent-guardrail - AI エージェントのツール呼び出しを対象とする汎用ポリシーファイアウォール(ブロックチェーンに特化していません)。 PyPI で公開されており、MIT ライセンスで、46 件のテストがあります。
- x402-attest - エージェント間の決済ポリシーに関する判断のための、暗号署名(Ed25519)付きで独立して検証可能な アテステーションです。初期段階の概念実証です。
- open-agent-attestation - 誰でも検証できる、エージェントのポリシー判断に署名するためのベンダー中立なオープン仕様(JWT+EdDSA)です。 上記の x402-attest は独自形式を使用していますが、こちらは汎用化したものです。ドラフト v0.1 です。
ライセンス
MIT - LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。
