Skip to Content
Core Conceptsセキュリティ

Security

Kova は、AI エージェントが暗号資産を安全に扱えるよう、複数のセキュリティ層を提供しています。鍵管理 / OperationKind 分類 / Signer 抽象化 / fail-closed な spending_limit を組み合わせて、誤送金や不正利用を防いでいます。

現行仕様: 本ページは OperationKind 分類 / Signer 抽象化 / spending_limit を中心とした構成を解説します。旧 KOVA_MODE env / config.json mode field による mode 検知設計はすべて廃止されています。

鍵管理

ローカル保存と暗号化

Kova の秘密鍵は、ローカルマシンに暗号化されて保存されます:

保存場所: ~/.kova/wallets/<wallet-id>.json

暗号化仕様:

  • アルゴリズム: AES-256-GCM(Galois/Counter Mode)
  • 鍵派生: PBKDF2(Password-Based Key Derivation Function 2)
  • イテレーション: 100,000 回
  • ソルト: ランダム生成(16 バイト)
  • 認証タグ: 改ざん検出(16 バイト)

秘密鍵は 決して平文で保存されません。ファイルの内容は以下のような形式です:

{ "version": 1, "id": "68cf6dba-e5f1-4c3a-9b2e-1234567890ab", "name": "my-wallet", "encrypted": "...", "salt": "...", "iv": "..." }

パスフレーズの重要性

ウォレットの安全性は、パスフレーズの強度に依存します。強力なパスフレーズを設定してください:

推奨:

  • 12 文字以上
  • 大文字・小文字・数字・記号を含む
  • 辞書に存在する単語を使わない
  • 他のサービスと使い回さない

悪い例: password123 / mywalletpass / Agent2024!

良い例: Xk9$mP2#vQ8@wL5& / T7rZ!pN3*dF6@hB9^

ファイルパーミッション

ウォレットファイルのアクセス権限を制限することで、他のユーザーからの読み取りを防ぎます:

# ウォレットディレクトリのパーミッション設定 chmod 700 ~/.kova/wallets # ウォレットファイルのパーミッション設定 chmod 600 ~/.kova/wallets/*.json

OperationKind 3 分類

Kova は mode を検知する 設計を採用しません。代わりに、すべてのコマンドを OperationKind で 3 分類し、実行 context(TTY 有無)と認証手段(passphrase / OWS API key)の組み合わせで経路が自動決定されます。

OperationKind副作用認証agent から(非 TTY)terminal から(TTY)代表コマンド
read-onlyなし不要✅ そのまま✅ そのままbalance / wallet info / policy list / key list / status
policy-gatedあり(チェーン書込)passphrase または API key✅ OWS API key で server に依頼 → policy で gate✅ passphrase 入力でローカル署名send / call / sign サブコマンド / delegate create / revoke
owner-onlyあり(local state / 鍵生成 / policy 更新)passphrase 必須❌ block (INTERACTIVE_INPUT_REQUIRED)✅ passphrase + readline 確認wallet export/reset-passphrase / policy create/remove/update / key rotate / init / skills install/remove/update / plugin install/uninstall / config set

fail-closed default: 上記いずれにも分類されない操作は owner-only として扱われます。CLI 入口のガードが要件を強制し、agent モードからの owner-only 操作呼び出しは構造的に拒否されます。

補足:KOVA_MODE / config.jsonmode field、および「mode を見て分岐する」コードはすべて削除されています。config set credential '' のみ「agent → owner 復帰」経路として guard より前で処理する例外として保持されます。

詳細リファレンス: Reference: OperationKind 分類 で各分類のコマンド一覧と guard 実装を参照できます。

--owner フラグの意味

--owner flag は passphrase 署名を強制する flag です。credential (OWS API key) が config に設定されていても本 flag を指定すると API key を無視し、ローカル passphrase 署名経路 (PassphraseSigner) を選択します。policy-gated 操作(send / call / sign / delegate 等)で利用します。

context--owner 指定経路
TTY ありありpassphrase 経路(PassphraseSigner
TTY ありなしpassphrase 経路(TTY フォールバック)
非 TTYありエラー(passphrase 入力できない)
非 TTYなし(credential あり)API key 経路(ApiKeySigner

本番環境で AI エージェントに使わせる場合は、--owner を使わずに API key + policy 経路(policy-gated)を使用してください。

Signer 抽象化

すべての署名操作は Signer interface (src/lib/signer/types.ts) 経由で実行されます。command 層は credential の種類を知らず、provider が認証 UX を内部に閉じ込めます(Strategy パターン)。

Signer interface

export interface Signer { readonly kind: 'passphrase' | 'api-key'; readonly humanPresenceRequired: boolean; readonly capabilities: ReadonlySet<Capability>; isAvailable(): Promise<boolean>; enforce(ctx?: SpendContext): Promise<void>; signMessage(walletId, chainId, message): Promise<OWSSignResult>; signTransaction(walletId, chainId, txHex): Promise<OWSSignResult>; signTypedData(walletId, chainId, typedDataJson): Promise<OWSSignResult>; signAndSend(walletId, chainId, txHex, rpcUrl?): Promise<OWSSendResult>; signHash(walletId, chainId, hash): Promise<OWSSignResult>; signAuthorization(walletId, auth): Promise<OWSSignedAuthorization>; getPublicKey(walletId): Promise<`0x${string}`>; }

2 つの実装

実装kindhumanPresenceRequired経路選択条件
PassphraseSignerpassphrasetrueTTY で passphrase 入力 → ローカル復号して署名--owner flag 指定、または TTY 検出
ApiKeySignerapi-keyfalseOWS API key を提示 → server-side 署名非 TTY + credential あり

humanPresenceRequired flag は owner-only 操作の gate で参照され、agent からの owner-only 実行を構造的に拒否します。

resolveSignerKindForWallet

resolveSignerKindForWallet(walletId) は OWS のウォレット metadata(signer.kind)を読んで、ウォレットごとに適切な SignerKind を返します。factory.ts がこの結果と context(API key の有無)から、最終的な Signer インスタンスを組み立てます。

署名の正規化

返却される署名は 常に 0x プレフィックス付き に正規化されます。OWS server / ローカル署名のどちらでも形式が揃うため、command 層・provider 層は分岐なく利用できます。

エージェントセットアップの統合

kova initStep 3/4(AI 接続設定)として、エージェントセットアップが内部実行 されます。これにより「ウォレットだけ作って credential が無い」状態を防ぎます。

設定される credential / apiKeyId

AI 接続設定(Step 3/4)で、~/.kova/config.jsonprofiles[<wallet-name>] に以下が保存されます。

{ "profiles": { "my-wallet": { "credential": "kova_xxx...", "apiKeyId": "key-xxx", "wallets": ["wallet-xxx"] } }, "activeProfile": "my-wallet" }
フィールド意味注入される環境変数
credentialOWS から発行される API key 文字列KOVA_CREDENTIALlaunch が agent に注入)
apiKeyIdAPI key を識別する IDKOVA_API_KEY_ID

kova launch <agent> はこの 2 つの環境変数を子プロセスへ注入することで、agent から呼ばれる Kova が ApiKeySigner 経路を選択できるようにします。エージェントを直接起動した場合も、新しい Kova プロセスが ~/.kova/config.json から credential を直接読み取るため動作します(ADR-036 v2)。

Cancel 時の挙動

kova init の AI 接続設定(Step 3/4)でユーザーがキャンセル(Ctrl+C / Esc)した場合:

  • kova init は completion banner に 警告を表示 します
  • ただし kova init 自体は エラー終了しません(exit 0)
  • 警告が出ているとき、Next Steps からエージェント起動の案内を外します(不完全な状態での誤誘導を防ぐ)

詳細は init リファレンス を参照してください。

dry-run デフォルト(送金)

Kova の送金コマンド(kova send)は、デフォルトで dry-run(シミュレーション) です。

# dry-run(デフォルト) kova send --name my-wallet --to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb --amount 10 --chain base --token USDC

dry-run では、トランザクションの構築・ガス代の見積もり・残高の確認・バリデーションがシミュレーションされ、実際の送金は行われません

実送信するには --broadcast を明示指定します:

kova send --name my-wallet --to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb --amount 10 --chain base --token USDC --broadcast

AI エージェント統合時の推奨フロー

  1. dry-run で確認 — まず dry-run で送金内容を確認
  2. ユーザー承認 — dry-run 結果をユーザーに提示し、承認を得る
  3. broadcast 実行 — 承認後に --broadcast フラグで実送信

ポリシー制御

ポリシーは API key に関連付けて、agent からの送金・決済・署名を制限する仕組みです。AI エージェントに使わせる場合は 必ずポリシーを設定 してください。

ポリシー評価の流れ

ポリシーテンプレート

kova policy で登録できるテンプレート一覧(policy リファレンス も参照):

テンプレート ID説明
allowed_chains操作を許可するチェーンを CAIP-2 形式で列挙
expires_atポリシーの有効期限(ISO 8601 timestamp)
max_valueネイティブトークン送金の上限(wei 単位)
spending_limitchain × token ごとの日次/月次累積上限

ポリシーに違反する操作は POLICY_DENIED で拒否されます:

{ "ok": false, "error": { "code": "POLICY_DENIED", "message": "Transaction exceeds policy maxAmount: 100 USDC" } }

ポリシーの確認・更新は policy リファレンス、API key の管理は key リファレンス を参照してください。

spending_limit fail-closed

spending_limit テンプレートで作成したポリシーは、agent 経路(非 TTY)の send / call 実行前に signer.enforce(ctx) が OWS server 側で事前評価 します。fail-closed なので、評価できない/超過するケースは すべて拒否 されます。

累積記録

累積額は ~/.kova/spend.json にローカル記録されます(chain × token × 日付ごと)。1 日の累積が daily_limit を超えると、後続の操作は POLICY_DENIED で拒否されます。

enforce(ctx) の責務

Signer.enforce(ctx) は実 RPC 呼び出しの に呼ばれる ctx-aware な事前 gate です:

  • ApiKeySigner.enforce(ctx) → OWS server に enforcePolicy(apiKey, ctx) をリクエストし、policy + spending_limit を評価
  • PassphraseSigner.enforce(ctx) → terminal owner mode のため no-op

ctx には entryPoint / chain(CAIP-2)/ token / amount を渡します。sign* メソッド内部の enforcePolicy(apiKey)(ctx 無し)は tamper detection の defense-in-depth として残されています。

異常系: spending_limit 超過

ケース挙動累積記録先
1 日累積が daily_limit 以下通過、記録更新~/.kova/spend.json
1 日累積が daily_limit 超過POLICY_DENIED で fail-closed記録は更新しない
enforce 呼び出し失敗(network / OWS error)fail-closed(拒否)-

現状の制約

ERC-20 calldata 内 amount の累積記録は 未対応 です。現状は ERC-20 transfer の calldata 内 amountspend.json には記録しません。NATIVE シンボル(チェーンのネイティブトークンを表す予約シンボル)の record のみ完全対応しています。

本番環境のベストプラクティス

1. ウォレット管理

  • 本番用と開発用を分離 — 開発環境では絶対に本番ウォレットを使わない
  • 定期的なバックアップ — 週次または月次でバックアップを取る
  • 複数のバックアップ場所 — オフラインストレージ、クラウドストレージ等

2. API key 管理

  • 最小権限の原則 — 必要最低限の権限のみを付与
  • 定期的なローテーション — 3 ヶ月ごとに API key を再生成
  • 使用履歴の監視 — 不審な使用がないか定期的に確認

3. ポリシー設定

  • 送金制限の設定kova init は制限なし(permissive)の状態でセットアップを完了する。実運用では policy update でチェーン制限・送金上限・許可リストを設定する
  • 段階的な権限管理 — まず permissive で動作確認し、運用に合わせて制約を追加していく
  • spending_limit を入れる — agent モードの fail-closed 防衛線として有効

4. AI エージェント運用

  • dry-run の徹底 — 必ず dry-run で確認してから --broadcast
  • ユーザー承認フロー — 高額送金は必ず人間の承認を得る
  • ログの記録 — すべてのトランザクションをログに記録
  • 異常検知 — 異常なトランザクションパターンをアラート

5. プロンプト汚染の防御

AI エージェントは、悪意のあるプロンプト注入攻撃に脆弱です。以下の対策を推奨します:

  • 入力の検証 — ユーザー入力を信頼しない、常にバリデーション
  • 出力の検証 — AI エージェントの出力を盲目的に信頼しない
  • 人間の確認 — 高リスク操作(owner-only)は必ず人間が確認
  • サンドボックス環境 — テスト環境でまず動作確認

6. ハードウェアウォレット・KMS

Kova は現在、ローカル暗号化ウォレットと OWS server-side 署名のみをサポートしていますが、Signer 抽象化により以下の拡張が可能な設計になっています:

  • ハードウェアウォレット — Ledger / Trezor 等(SignerKindhw-ledger 等を追加)
  • OS Keychain — macOS Keychain / Windows Credential Manager
  • KMS (Key Management Service) — AWS KMS / Google Cloud KMS

高額の資産を扱う場合は、これらの統合をお待ちください。

セキュリティインシデント対応

ウォレットが漏洩した場合

  1. すぐに資産を移動 — 新しいウォレットに全資産を転送
  2. API key を無効化 — すべての API key を即座に無効化
  3. ログを確認 — 不正なトランザクションがないか確認
  4. パスフレーズを変更 — 他のサービスで同じパスフレーズを使用している場合は変更
# 緊急時の資産移動 kova send --name my-wallet --to <new-wallet-address> --amount <all-balance> --chain base --token USDC --broadcast # active な API key を新規鍵に置き換える # 注: `kova key rotate` は 1 key 単位の置換 (新規発行 → 旧鍵 revoke) であり、 # 「全 API key の即時無効化」にはなりません。複数 key を保持している場合は # 各 key を個別にローテートするか、OWS ダッシュボードで一括 revoke してください。 kova key rotate --name <active-key-name>

不正なトランザクションを発見した場合

  1. API key を即座に無効化
  2. ログを保存 — トランザクション履歴を記録
  3. 原因を調査 — ポリシー設定、AI エージェントのログ、~/.kova/spend.json を確認
  4. 再発防止策 — ポリシーを強化、spending_limit を厳しめに更新、監視を追加

次のステップ

Last updated on