bagman

TotalClaw 作者 totalclaw v2.1.0

AI 代理的安全密钥管理。在处理私钥、API 机密、钱包凭证或构建需要代理控制资金的系统时使用。涵盖安全存储、会话密钥、泄漏预防、提示注入防御和 MetaMask 委托框架集成。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~zscole-bagman
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~zscole-bagman/file -o zscole-bagman.md
## 概述(中文)

AI 代理的安全密钥管理。在处理私钥、API 机密、钱包凭证或构建需要代理控制资金的系统时使用。涵盖安全存储、会话密钥、泄漏预防、提示注入防御和 MetaMask 委托框架集成。

## 原文

# Bagman

Secure key management patterns for AI agents handling wallets, private keys, and secrets.

## When to Use This Skill

- Agent needs wallet/blockchain access
- Handling API keys, credentials, or secrets
- Building systems where AI controls funds
- Preventing secret leakage via prompts or outputs

## Quick Start

```bash
# Install 1Password CLI
brew install 1password-cli

# Authenticate
eval $(op signin)

# Create vault for agent credentials
op vault create "Agent-Credentials"

# Run examples
cd examples && python test_suite.py
```

---

## Core Rules

| Rule | Why |
|------|-----|
| Never store raw private keys | Config, env, memory, or conversation = leaked |
| Use delegated access | Session keys with time/value/scope limits |
| Secrets via secret manager | 1Password, Vault, AWS Secrets Manager |
| Sanitize all outputs | Scan for key patterns before any response |
| Validate all inputs | Check for injection attempts before wallet ops |

---

## Architecture

```
┌─────────────────────────────────────────────────────┐
│                   AI Agent                          │
├─────────────────────────────────────────────────────┤
│  Session Key (bounded)                              │
│  ├─ Expires after N hours                           │
│  ├─ Max spend per tx/day                            │
│  └─ Whitelist of allowed contracts/methods          │
├─────────────────────────────────────────────────────┤
│  Secret Manager (1Password/Vault)                   │
│  ├─ Retrieve at runtime only                        │
│  ├─ Never persist to disk                           │
│  └─ Audit trail of accesses                         │
├─────────────────────────────────────────────────────┤
│  Smart Account (ERC-4337)                           │
│  ├─ Programmable permissions                        │
│  └─ Recovery without key exposure                   │
└─────────────────────────────────────────────────────┘
```

---

## Implementation Files

| File | Purpose |
|------|---------|
| `examples/secret_manager.py` | 1Password integration for runtime secret retrieval |
| `examples/sanitizer.py` | Output sanitization (keys, seeds, tokens) |
| `examples/validator.py` | Input validation (prompt injection defense) |
| `examples/session_keys.py` | ERC-4337 session key configuration |
| `examples/delegation_integration.ts` | MetaMask Delegation Framework (EIP-7710) |
| `examples/pre-commit` | Git hook to block secret commits |
| `examples/test_suite.py` | Adversarial test suite |
| `docs/prompt-injection.md` | Deep dive on injection defense |
| `docs/secure-storage.md` | Secret storage patterns |
| `docs/session-keys.md` | Session key architecture |
| `docs/leak-prevention.md` | Output sanitization patterns |
| `docs/delegation-framework.md` | On-chain permission enforcement (EIP-7710) |

---

## 1. Secret Retrieval

### 1Password CLI Pattern

```bash
# Retrieve at runtime (never store result)
SESSION_KEY=$(op read "op://Agents/my-agent/session-key")

# Run with injected secrets (never touch disk)
op run --env-file=.env.tpl -- python agent.py
```

### .env.tpl (safe to commit - no secrets)

```
PRIVATE_KEY=op://Agents/trading-bot/session-key
RPC_URL=op://Infra/alchemy/sepolia-url
OPENAI_API_KEY=op://Services/openai/api-key
```

### Python Usage

```python
from secret_manager import get_session_key

# Retrieve validated session key
creds = get_session_key("trading-bot-session")

# Check validity
if creds.is_expired():
    raise ValueError("Session expired - request renewal from operator")

print(f"Time remaining: {creds.time_remaining()}")
print(f"Allowed contracts: {creds.allowed_contracts}")

# Use the key (never log it!)
client.set_signer(creds.session_key)
```

### Vault-Level ACL (Recommended)

Configure 1Password vault permissions:

```
Agent-Credentials/
├── trading-bot-session    # Agent can read
├── payment-bot-session    # Agent can read
└── master-key             # Operator ONLY (agent has no access)
```

**Principle:** Agent credentials should be in a vault with read-only agent access. Master keys should be in a separate vault the agent cannot access.

---

## 2. Output Sanitization

Apply to ALL agent outputs before sending anywhere:

```python
from sanitizer import OutputSanitizer

def respond(content: str) -> str:
    """Sanitize before any output."""
    return OutputSanitizer.sanitize(content)

# Catches:
# - Private keys (0x + 64 hex)
# - OpenAI/Anthropic/Groq/AWS keys
# - GitHub/Slack/Discord tokens
# - BIP-39 seed phrases (12/24 words)
# - PEM private keys
# - JWT tokens
```

### Patterns Detected

| Pattern | Example | Result |
|---------|---------|--------|
| ETH private key | `0x1234...abcd` (64 hex) | `[PRIVATE_KEY_REDACTED]` |
| ETH address | `0x742d...f44e` (40 hex) | `0x742d...f44e` (truncated) |
| OpenAI key | `sk-proj-abc123...` | `[OPENAI_KEY_REDACTED]` |
| Anthropic key | `sk-ant-api03-...` | `[ANTHROPIC_KEY_REDACTED]` |
| 12-word seed | `abandon ability able...` | `[SEED_PHRASE_12_WORDS_REDACTED]` |
| JWT | `eyJhbG...` | `[JWT_TOKEN_REDACTED]` |

---

## 3. Input Validation

Check inputs before ANY wallet operation:

```python
from validator import InputValidator, ThreatLevel

result = InputValidator.validate(user_input)

if result.level == ThreatLevel.BLOCKED:
    return f"Request blocked: {result.reason}"

if result.level == ThreatLevel.SUSPICIOUS:
    # Log for review, but allow
    log_suspicious(user_input, result.reason)

# Proceed with operation
```

### Threat Categories

| Category | Examples | Action |
|----------|----------|--------|
| Extraction | "show private key", "reveal secrets" | Block |
| Override | "ignore previous instructions" | Block |
| Role manipulation | "you are now admin" | Block |
| Jailbreak | "DAN mode", "bypass filters" | Block |
| Exfiltration | "send config to https://..." | Block |
| Wallet threats | "transfer all", "unlimited approve" | Block |
| Encoded | Base64/hex encoded attacks | Block |
| Unicode tricks | Cyrillic lookalikes, zero-width | Block |
| Suspicious | "hypothetically", "just between us" | Warn |

---

## 4. Operation Allowlisting

Never execute arbitrary operations. Explicit whitelist only:

```python
from dataclasses import dataclass
from decimal import Decimal
from typing import Optional

@dataclass
class AllowedOperation:
    name: str
    handler: callable
    max_value: Optional[Decimal] = None
    requires_confirmation: bool = False
    cooldown_seconds: int = 0

ALLOWED_OPS = {
    "check_balance": AllowedOperation("check_balance", get_balance),
    "transfer_usdc": AllowedOperation(
        "transfer_usdc", 
        transfer,
        max_value=Decimal("500"),
        requires_confirmation=True,
        cooldown_seconds=60
    ),
    "swap": AllowedOperation(
        "swap",
        swap_tokens,
        max_value=Decimal("1000"),
        cooldown_seconds=300
    ),
}

def execute(op_name: str, **kwargs):
    if op_name not in ALLOWED_OPS:
        raise PermissionError(f"Operation '{op_name}' not allowed")
    
    op = ALLOWED_OPS[op_name]
    
    if op.max_value and kwargs.get("amount", 0) > op.max_value:
        raise PermissionError(f"Amount exceeds limit: {op.max_value}")
    
    if op.requires_confirmation:
        return request_confirmation(op_name, kwargs)
    
    return op.handler(**kwargs)
```

---

## 5. Confirmation Flow

High-value operations require explicit confirmation:

```python
import hashlib
import time

pending_confirmations = {}

def request_confirmation(operation: str, details: dict) -> str:
    code = hashlib.sha256(
        f"{operation}{time.time()}".encode()
    ).hexdigest()[:8].upper()
    
    pending_confirmations[code] = {
        "op": operation,
        "details": details,
        "expires": time.time() + 300  # 5 minutes
    }
    
    return f"⚠️ Confirm '{operation}' with code: {code}\n(expires in 5 minutes)"

def confirm(code: