🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Openclaw

by @zscole

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, prompt injection defense, and MetaMask Delegation Framework integration.

Versionv2.1.0
Downloads2,385
Stars⭐ 2
TERMINAL
clawhub install bagman

πŸ“– About This Skill


name: bagman version: 2.1.0 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, prompt injection defense, and MetaMask Delegation Framework integration. homepage: https://github.com/zscole/bagman-skill metadata: { "openclaw": { "emoji": "πŸ”", "requires": { "bins": ["op"] }, "tags": ["security", "wallet", "keys", "crypto", "secrets", "delegation"] } }

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

    # 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

    # 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

    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:

    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:

    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:

    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:

    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: str): if code not in pending_confirmations: return "Invalid confirmation code" req = pending_confirmations.pop(code) if time.time() > req["expires"]: return "Confirmation code expired" return execute_confirmed(req["op"], req["details"])


    6. Session Keys (ERC-4337)

    Instead of giving agents master keys, issue bounded session keys:

    from session_keys import SessionKeyManager

    Operator creates trading session for agent

    config = SessionKeyManager.create_trading_session( agent_name="alpha-trader", operator_address="0x742d...", duration_hours=24, max_trade_usdc=1000, daily_limit_usdc=5000, )

    Export for storage in 1Password

    export_data = SessionKeyManager.export_for_1password( config, session_key_hex="0x..." # Generated session key )

    op item create ... (store in 1Password)

    Session Key Benefits

    | Feature | Master Key | Session Key | |---------|------------|-------------| | Expiration | Never | Configurable (hours/days) | | Spending limits | None | Per-tx and daily caps | | Contract restrictions | Full access | Whitelist only | | Revocation | Requires key rotation | Instant, no key change | | Audit | None | Full operation log |


    7. Pre-commit Hook

    Block commits containing secrets:

    # Install
    cp examples/pre-commit .git/hooks/
    chmod +x .git/hooks/pre-commit
    

    Detected patterns:

  • ETH private keys (64 hex chars)
  • OpenAI/Anthropic/Groq keys
  • AWS access keys
  • GitHub/GitLab tokens
  • Slack/Discord tokens
  • PEM private keys
  • Generic PASSWORD/SECRET assignments
  • BIP-39 seed phrases

  • 8. Defense Layers

    USER INPUT
        β”‚
        β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Layer 1: Input Validation  β”‚  ← Regex + encoding + unicode checks
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Layer 2: Op Allowlisting   β”‚  ← Explicit whitelist only
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Layer 3: Value Limits      β”‚  ← Max per-tx and per-day
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Layer 4: Confirmation      β”‚  ← Time-limited codes for $$$
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Layer 5: Isolated Exec     β”‚  ← Wallet ops != conversation
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
    OUTPUT SANITIZATION
    


    Common Mistakes

    ❌ Keys in memory files

    # memory/2026-02-07.md
    Private key: 0x9f01dad551039daad...
    
    Fix: Store reference only: Private key: [stored in 1Password: test-wallet]

    ❌ Keys in error messages

    except Exception as e:
        log(f"Failed with key {private_key}: {e}")
    
    Fix: Never include credentials in error context

    ❌ Keys in .env.example

    PRIVATE_KEY=sk-ant-api03-real-key...  # "for testing"
    
    Fix: Use obviously fake: PRIVATE_KEY=your-key-here

    ❌ "All" in transfer requests

    User: "Transfer all my USDC"
    Agent: *executes unlimited transfer*
    
    Fix: Block "all/everything/max" patterns, require explicit amounts

    ❌ Trusting conversation context

    # Wallet has access to conversation history
    self.wallet.execute(conversation[-1]["content"])
    
    Fix: Wallet operations must be isolated from conversation context


    Testing

    cd examples

    Run full test suite

    python test_suite.py

    Test individual components

    python sanitizer.py # Output sanitization demo python validator.py # Input validation demo python session_keys.py # Session key demo

    Expected output: All tests passed


    Checklist

  • [ ] 1Password CLI installed and authenticated
  • [ ] Secrets in 1Password vault, not files
  • [ ] Session keys with expiry and limits
  • [ ] Output sanitization on all responses
  • [ ] Input validation before wallet ops
  • [ ] Pre-commit hook installed
  • [ ] Confirmation flow for high-value operations
  • [ ] Wallet operations isolated from conversation
  • [ ] .gitignore covers secrets and memory files
  • [ ] Test suite passes

  • Security Model Limitations

    This skill provides defense in depth, not a guarantee. Adversaries may:

    1. Novel injection patterns - Regex can't catch everything; semantic analysis helps but isn't perfect 2. Social engineering - Convincing the operator to approve malicious operations 3. Timing attacks - Exploiting confirmation windows 4. Encoding evasion - New encoding schemes not covered

    Recommendation: Layer these defenses with:

  • Rate limiting
  • Anomaly detection
  • Human-in-the-loop for large transactions
  • Regular security audits
  • πŸ’‘ Examples

    # 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