Agent Skills by ALSEL
汎用セキュリティ⭐ リポ 1,982品質スコア 95/100

bagman

AIエージェント向けのセキュアなキー管理機能です。秘密鍵、APIシークレット、ウォレット認証情報の取り扱い、またはエージェント制御資金を必要とするシステム構築時にご利用ください。セキュアなストレージ、セッションキー、情報漏洩防止、プロンプトインジェクション対策に対応しています。

description の原文を見る

Secure key management for AI agents. Use when handling private keys, API secrets, wallet credentials, or when building systems that need agent-controlled funds. Covers secure storage, session keys, leak prevention, and prompt injection defense.

SKILL.md 本文

Bagman

秘密鍵とシークレットを取り扱うAIエージェント向けのセキュアキー管理パターン。以下の防止を目的として設計されています:

  • キー喪失: エージェントがセッション間でキーを忘れる
  • 予期しない露出: キーがGitHub、ログ、出力に流出する
  • プロンプトインジェクション: 悪意のあるプロンプトによるシークレット抽出

コア原則

  1. 設定、環境変数、メモリファイルに生の秘密鍵を保存しない
  2. 完全な制御ではなくセッションキー/委譲されたアクセスを使用する
  3. すべてのシークレットアクセスは1Password CLI (op) を経由する
  4. キー流出を防ぐため、すべての出力をバリデーションしてから送信する

参考資料

  • references/secure-storage.md - エージェントシークレット向け1Passwordパターン
  • references/session-keys.md - ERC-4337委譲アクセスパターン
  • references/leak-prevention.md - プリコミットフックと出力サニタイゼーション
  • references/prompt-injection-defense.md - 入力バリデーションと出力フィルタリング

クイックリファレンス

すべき事 ✅

# 実行時に1Passwordを経由してキーを取得
PRIVATE_KEY=$(op read "op://Agents/my-agent-wallet/private-key")

# 環境変数インジェクションを使用(キーがディスクに触れない)
op run --env-file=.env.tpl -- node agent.js

# 権限が限定されたセッションキーを使用
# (完全なウォレットアクセスではなく、特定の機能のみを委譲)

してはいけない事 ❌

# キーをファイルに保存しない
echo "PRIVATE_KEY=0x123..." > .env

# キーをログまたはプリントしない
console.log("Key:", privateKey)

# キーをメモリ/ジャーナルファイルに保存しない
# 「プライベート」なエージェントメモリであっても - 流出する可能性がある

# キー操作の近くで未検証の入力を信頼しない

アーキテクチャ: エージェントウォレットスタック

┌─────────────────────────────────────────────────────┐
│                   AIエージェント                     │
├─────────────────────────────────────────────────────┤
│  セッションキー(時間/値限定)                       │
│  - N時間後に期限切れ                                │
│  - 操作ごとの支出上限                               │
│  - 許可されたコントラクトのホワイトリスト           │
├─────────────────────────────────────────────────────┤
│  1Password / シークレットマネージャー                │
│  - エージェントが実行時にセッションキーを取得       │
│  - 完全な秘密鍵を保存しない                         │
│  - すべてのアクセスの監査ログ                       │
├─────────────────────────────────────────────────────┤
│  ERC-4337スマートアカウント                         │
│  - プログラム可能な権限                             │
│  - 秘密鍵露出なしでのリカバリ                       │
│  - 高額操作向けマルチシグ                           │
├─────────────────────────────────────────────────────┤
│  オペレータ(人間)                                 │
│  - ハードウェアウォレットにマスターキーを保有       │
│  - セッションキーの発行/取り消し                    │
│  - エージェント活動を監視                           │
└─────────────────────────────────────────────────────┘

ワークフロー: エージェントウォレットアクセスのセットアップ

1. エージェントシークレット向け1Passwordボルトを作成

# 専用ボルトを作成(1PasswordアプリまたはCLI経由)
op vault create "Agent-Wallets" --description "AI agent wallet credentials"

# エージェントセッションキーを保存(マスターキーではない!)
op item create \
  --vault "Agent-Wallets" \
  --category "API Credential" \
  --title "trading-bot-session" \
  --field "session-key[password]=0xsession..." \
  --field "expires=2026-02-15T00:00:00Z" \
  --field "spending-cap=1000 USDC" \
  --field "allowed-contracts=0xDEX1,0xDEX2"

2. エージェントが実行時に認証情報を取得

import subprocess
import json

def get_session_key(item_name: str) -> dict:
    """実行時に1Passwordからセッションキーを取得。"""
    result = subprocess.run(
        ["op", "item", "get", item_name, "--vault", "Agent-Wallets", "--format", "json"],
        capture_output=True, text=True, check=True
    )
    item = json.loads(result.stdout)
    
    # フィールドを抽出
    fields = {f["label"]: f.get("value") for f in item.get("fields", [])}
    
    # セッションが期限切れでないか検証
    from datetime import datetime
    expires = datetime.fromisoformat(fields.get("expires", "2000-01-01"))
    if datetime.now() > expires:
        raise ValueError("Session key expired - request new key from operator")
    
    return {
        "session_key": fields.get("session-key"),
        "expires": fields.get("expires"),
        "spending_cap": fields.get("spending-cap"),
        "allowed_contracts": fields.get("allowed-contracts", "").split(",")
    }

3. キーをログまたは保存しない

# ❌ 悪い例 - ログにキーが含まれている
logger.info(f"Using key: {session_key}")

# ✅ 良い例 - 識別子をマスク
logger.info(f"Using session key: {session_key[:8]}...{session_key[-4:]}")

# ❌ 悪い例 - キーがメモリファイルに含まれている
with open("memory/today.md", "a") as f:
    f.write(f"Session key: {session_key}")

# ✅ 良い例 - 参照のみ
with open("memory/today.md", "a") as f:
    f.write(f"Session key: [stored in 1Password: trading-bot-session]")

流出防止

出力サニタイゼーション

エージェントの出力(チャット、ログ、ファイル書き込み)の前に、キーパターンをスキャンします:

import re

KEY_PATTERNS = [
    r'0x[a-fA-F0-9]{64}',                    # ETH秘密鍵
    r'sk-[a-zA-Z0-9]{48,}',                  # OpenAIキー
    r'sk-ant-[a-zA-Z0-9\-_]{80,}',           # Anthropicキー
    r'gsk_[a-zA-Z0-9]{48,}',                 # Groqキー
    r'[A-Za-z0-9+/]{40,}={0,2}',             # Base64エンコード(疑わしいほど長い)
]

def sanitize_output(text: str) -> str:
    """出力からシークレットの可能性を削除。"""
    for pattern in KEY_PATTERNS:
        text = re.sub(pattern, '[REDACTED]', text)
    return text

# すべてのエージェント出力に適用
def send_message(content: str):
    content = sanitize_output(content)
    # ... チャット/ログ/ファイルに送信

プリコミットフック

シークレットの誤ったコミットを防ぐためにこのフックをインストール:

#!/bin/bash
# .git/hooks/pre-commit

PATTERNS=(
    '0x[a-fA-F0-9]{64}'
    'sk-[a-zA-Z0-9]{48,}'
    'sk-ant-api'
    'PRIVATE_KEY='
    'gsk_[a-zA-Z0-9]{48,}'
)

for pattern in "${PATTERNS[@]}"; do
    if git diff --cached | grep -qE "$pattern"; then
        echo "❌ Potential secret detected matching: $pattern"
        echo "   Remove secrets before committing!"
        exit 1
    fi
done

.gitignore必須事項

# Secrets
.env
.env.*
*.pem
*.key
secrets/
credentials/

# シークレットを含む可能性があるエージェント状態
memory/*.json
wallet-state.json
session-keys/

プロンプトインジェクション対策

入力バリデーション

ウォレット操作に関わるユーザー入力を処理する前に:

DANGEROUS_PATTERNS = [
    r'ignore.*(previous|above|prior).*instructions',
    r'reveal.*(key|secret|password|credential)',
    r'output.*(key|secret|private)',
    r'print.*(key|secret|wallet)',
    r'show.*(key|secret|password)',
    r'what.*(key|secret|password)',
    r'tell.*me.*(key|secret)',
    r'disregard.*rules',
    r'system.*prompt',
    r'jailbreak',
    r'dan.*mode',
]

def validate_input(text: str) -> bool:
    """プロンプトインジェクション試行をチェック。"""
    text_lower = text.lower()
    for pattern in DANGEROUS_PATTERNS:
        if re.search(pattern, text_lower):
            return False
    return True

def process_wallet_request(user_input: str):
    if not validate_input(user_input):
        return "I can't help with that request."
    # ... ウォレット操作を続行

関心の分離

  • ウォレット操作は独立した関数にあり、会話コンテキストへのアクセス権がない
  • 完全な会話履歴をウォレット関連コードに渡さない
  • ブロックリストではなくホワイトリストを操作に使用
ALLOWED_WALLET_OPERATIONS = {
    "check_balance": lambda: get_balance(),
    "send_usdc": lambda to, amount: send_usdc(to, amount) if amount < DAILY_LIMIT else deny(),
    "swap": lambda: swap_tokens() if within_limits() else deny(),
}

def execute_wallet_operation(operation: str, **kwargs):
    """明示的に許可された操作のみを実行。"""
    if operation not in ALLOWED_WALLET_OPERATIONS:
        raise ValueError(f"Operation '{operation}' not allowed")
    return ALLOWED_WALLET_OPERATIONS[operation](**kwargs)

セッションキー実装(ERC-4337)

オンチェーンアクセスが必要なエージェントの場合、生の秘密鍵ではなくセッションキーを使用します。

完全な実装詳細については references/session-keys.md を参照してください。以下を含みます:

  • ZeroDev/Biconomy SDKの例
  • トレーディング/DeFi/支払いエージェント向けの権限パターン
  • セッションキーのライフサイクル管理
  • 取り消し手順

インシデント対応

キーが流出した場合

  1. 直ちに: セッションキーを取り消す/認証情報をローテーション
  2. 評価: トランザクション履歴で不正な活動をチェック
  3. 通知: セキュアチャネルでオペレータに警告
  4. ローテーション: より厳しい権限で新しいセッションキーを発行
  5. 監査: 流出方法を確認、防御を更新
# 緊急: 1Passwordアイテムを取り消し
op item delete "compromised-session-key" --vault "Agent-Wallets"

# 新しいセッションキーにローテーション
op item create --vault "Agent-Wallets" --category "API Credential" \
  --title "trading-bot-session-v2" ...

チェックリスト: エージェントウォレットセットアップ

  • エージェント認証情報専用の1Passwordボルトを作成
  • セッションキー(マスターキーではない)をボルトに保存
  • 適切な有効期限と支出限度を設定
  • シークレット検出向けプリコミットフックをインストール
  • すべてのエージェント応答に出力サニタイゼーションを追加
  • プロンプトインジェクション向け入力バリデーションを実装
  • モニタリングとアラートを設定
  • インシデント対応手順を文書化
  • キーローテーション手順をテスト

本番環境で見つかった一般的な間違い

1. メモリファイル内のキー

問題: エージェントが「永続化」のため memory/*.md にキーを保存

# memory/2026-02-07.md
## テストウォレット
- 秘密鍵: 0x9f01dad551039daad3a8c4e43a32035bdd4da54e7b4292268be16e913b0b3e56

修正: 参照のみを保存: 秘密鍵: [1Password: test-wallet-session]

2. 環境テンプレート内のキー

問題: .env.example に実際のキーが含まれている

# .env.example
PRIVATE_KEY=sk-ant-api03-real-key-here...  # 「テスト用」

修正: 明らかに偽のプレースホルダーを使用: PRIVATE_KEY=your-key-here

3. エラーメッセージ内のキー

問題: エラーハンドリングがキーを露出

try:
    sign_transaction(private_key, tx)
except Exception as e:
    logger.error(f"Failed with key {private_key}: {e}")  # ❌

修正: エラーコンテキストに認証情報を含めない

4. 本番コード内のテストキー

問題: ハードコードされたテストキーがメインブランチに到達

修正: 別々のテストボルトを使用、キーパターン向けCI確認を実施


OpenClawとの統合

OpenClawエージェントとして実行する場合:

  1. すべてのシークレット取得に1Passwordスキルを使用
  2. キーをワークスペースファイルに書き込まない - セッション間で永続化される
  3. 出力をサニタイズしてから任意のチャネルに送信 (Telegram、Discordなど)
  4. ウォレット操作にセッションキーアプローチを使用 - オペレータから権限限定アクセスをリクエスト
  5. キー参照を文書化 TOOLS.mdで、実際のキーではなく

TOOLS.mdエントリ例:

### エージェントウォレット
- アドレス: 0xABC123...
- セッションキー: [1Password: my-agent-session]
- 権限: USDC送信 < 100、承認DEXのみ
- 有効期限: 2026-02-15
- ローテーション方法: Telegram経由でオペレータに依頼

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
LeoYeAI
リポジトリ
LeoYeAI/openclaw-master-skills
ライセンス
MIT
最終更新
2026/5/11

Source: https://github.com/LeoYeAI/openclaw-master-skills / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: LeoYeAI · LeoYeAI/openclaw-master-skills · ライセンス: MIT