{
  "schemaVersion": "1.0",
  "item": {
    "slug": "bagman",
    "name": "Openclaw",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/zscole/bagman",
    "canonicalUrl": "https://clawhub.ai/zscole/bagman",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/bagman",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=bagman",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/delegation-framework.md",
      "references/leak-prevention.md",
      "references/prompt-injection-defense.md",
      "references/prompt-injection.md",
      "references/secure-storage.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/bagman"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/bagman",
    "agentPageUrl": "https://openagent3.xyz/skills/bagman/agent",
    "manifestUrl": "https://openagent3.xyz/skills/bagman/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/bagman/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Bagman",
        "body": "Secure key management patterns for AI agents handling wallets, private keys, and secrets."
      },
      {
        "title": "When to Use This Skill",
        "body": "Agent needs wallet/blockchain access\nHandling API keys, credentials, or secrets\nBuilding systems where AI controls funds\nPreventing secret leakage via prompts or outputs"
      },
      {
        "title": "Quick Start",
        "body": "# Install 1Password CLI\nbrew install 1password-cli\n\n# Authenticate\neval $(op signin)\n\n# Create vault for agent credentials\nop vault create \"Agent-Credentials\"\n\n# Run examples\ncd examples && python test_suite.py"
      },
      {
        "title": "Core Rules",
        "body": "RuleWhyNever store raw private keysConfig, env, memory, or conversation = leakedUse delegated accessSession keys with time/value/scope limitsSecrets via secret manager1Password, Vault, AWS Secrets ManagerSanitize all outputsScan for key patterns before any responseValidate all inputsCheck for injection attempts before wallet ops"
      },
      {
        "title": "Architecture",
        "body": "┌─────────────────────────────────────────────────────┐\n│                   AI Agent                          │\n├─────────────────────────────────────────────────────┤\n│  Session Key (bounded)                              │\n│  ├─ Expires after N hours                           │\n│  ├─ Max spend per tx/day                            │\n│  └─ Whitelist of allowed contracts/methods          │\n├─────────────────────────────────────────────────────┤\n│  Secret Manager (1Password/Vault)                   │\n│  ├─ Retrieve at runtime only                        │\n│  ├─ Never persist to disk                           │\n│  └─ Audit trail of accesses                         │\n├─────────────────────────────────────────────────────┤\n│  Smart Account (ERC-4337)                           │\n│  ├─ Programmable permissions                        │\n│  └─ Recovery without key exposure                   │\n└─────────────────────────────────────────────────────┘"
      },
      {
        "title": "Implementation Files",
        "body": "FilePurposeexamples/secret_manager.py1Password integration for runtime secret retrievalexamples/sanitizer.pyOutput sanitization (keys, seeds, tokens)examples/validator.pyInput validation (prompt injection defense)examples/session_keys.pyERC-4337 session key configurationexamples/delegation_integration.tsMetaMask Delegation Framework (EIP-7710)examples/pre-commitGit hook to block secret commitsexamples/test_suite.pyAdversarial test suitedocs/prompt-injection.mdDeep dive on injection defensedocs/secure-storage.mdSecret storage patternsdocs/session-keys.mdSession key architecturedocs/leak-prevention.mdOutput sanitization patternsdocs/delegation-framework.mdOn-chain permission enforcement (EIP-7710)"
      },
      {
        "title": "1Password CLI Pattern",
        "body": "# Retrieve at runtime (never store result)\nSESSION_KEY=$(op read \"op://Agents/my-agent/session-key\")\n\n# Run with injected secrets (never touch disk)\nop run --env-file=.env.tpl -- python agent.py"
      },
      {
        "title": ".env.tpl (safe to commit - no secrets)",
        "body": "PRIVATE_KEY=op://Agents/trading-bot/session-key\nRPC_URL=op://Infra/alchemy/sepolia-url\nOPENAI_API_KEY=op://Services/openai/api-key"
      },
      {
        "title": "Python Usage",
        "body": "from secret_manager import get_session_key\n\n# Retrieve validated session key\ncreds = get_session_key(\"trading-bot-session\")\n\n# Check validity\nif creds.is_expired():\n    raise ValueError(\"Session expired - request renewal from operator\")\n\nprint(f\"Time remaining: {creds.time_remaining()}\")\nprint(f\"Allowed contracts: {creds.allowed_contracts}\")\n\n# Use the key (never log it!)\nclient.set_signer(creds.session_key)"
      },
      {
        "title": "Vault-Level ACL (Recommended)",
        "body": "Configure 1Password vault permissions:\n\nAgent-Credentials/\n├── trading-bot-session    # Agent can read\n├── payment-bot-session    # Agent can read\n└── master-key             # Operator ONLY (agent has no access)\n\nPrinciple: Agent credentials should be in a vault with read-only agent access. Master keys should be in a separate vault the agent cannot access."
      },
      {
        "title": "2. Output Sanitization",
        "body": "Apply to ALL agent outputs before sending anywhere:\n\nfrom sanitizer import OutputSanitizer\n\ndef respond(content: str) -> str:\n    \"\"\"Sanitize before any output.\"\"\"\n    return OutputSanitizer.sanitize(content)\n\n# Catches:\n# - Private keys (0x + 64 hex)\n# - OpenAI/Anthropic/Groq/AWS keys\n# - GitHub/Slack/Discord tokens\n# - BIP-39 seed phrases (12/24 words)\n# - PEM private keys\n# - JWT tokens"
      },
      {
        "title": "Patterns Detected",
        "body": "PatternExampleResultETH private key0x1234...abcd (64 hex)[PRIVATE_KEY_REDACTED]ETH address0x742d...f44e (40 hex)0x742d...f44e (truncated)OpenAI keysk-proj-abc123...[OPENAI_KEY_REDACTED]Anthropic keysk-ant-api03-...[ANTHROPIC_KEY_REDACTED]12-word seedabandon ability able...[SEED_PHRASE_12_WORDS_REDACTED]JWTeyJhbG...[JWT_TOKEN_REDACTED]"
      },
      {
        "title": "3. Input Validation",
        "body": "Check inputs before ANY wallet operation:\n\nfrom validator import InputValidator, ThreatLevel\n\nresult = InputValidator.validate(user_input)\n\nif result.level == ThreatLevel.BLOCKED:\n    return f\"Request blocked: {result.reason}\"\n\nif result.level == ThreatLevel.SUSPICIOUS:\n    # Log for review, but allow\n    log_suspicious(user_input, result.reason)\n\n# Proceed with operation"
      },
      {
        "title": "Threat Categories",
        "body": "CategoryExamplesActionExtraction\"show private key\", \"reveal secrets\"BlockOverride\"ignore previous instructions\"BlockRole manipulation\"you are now admin\"BlockJailbreak\"DAN mode\", \"bypass filters\"BlockExfiltration\"send config to https://...\"BlockWallet threats\"transfer all\", \"unlimited approve\"BlockEncodedBase64/hex encoded attacksBlockUnicode tricksCyrillic lookalikes, zero-widthBlockSuspicious\"hypothetically\", \"just between us\"Warn"
      },
      {
        "title": "4. Operation Allowlisting",
        "body": "Never execute arbitrary operations. Explicit whitelist only:\n\nfrom dataclasses import dataclass\nfrom decimal import Decimal\nfrom typing import Optional\n\n@dataclass\nclass AllowedOperation:\n    name: str\n    handler: callable\n    max_value: Optional[Decimal] = None\n    requires_confirmation: bool = False\n    cooldown_seconds: int = 0\n\nALLOWED_OPS = {\n    \"check_balance\": AllowedOperation(\"check_balance\", get_balance),\n    \"transfer_usdc\": AllowedOperation(\n        \"transfer_usdc\", \n        transfer,\n        max_value=Decimal(\"500\"),\n        requires_confirmation=True,\n        cooldown_seconds=60\n    ),\n    \"swap\": AllowedOperation(\n        \"swap\",\n        swap_tokens,\n        max_value=Decimal(\"1000\"),\n        cooldown_seconds=300\n    ),\n}\n\ndef execute(op_name: str, **kwargs):\n    if op_name not in ALLOWED_OPS:\n        raise PermissionError(f\"Operation '{op_name}' not allowed\")\n    \n    op = ALLOWED_OPS[op_name]\n    \n    if op.max_value and kwargs.get(\"amount\", 0) > op.max_value:\n        raise PermissionError(f\"Amount exceeds limit: {op.max_value}\")\n    \n    if op.requires_confirmation:\n        return request_confirmation(op_name, kwargs)\n    \n    return op.handler(**kwargs)"
      },
      {
        "title": "5. Confirmation Flow",
        "body": "High-value operations require explicit confirmation:\n\nimport hashlib\nimport time\n\npending_confirmations = {}\n\ndef request_confirmation(operation: str, details: dict) -> str:\n    code = hashlib.sha256(\n        f\"{operation}{time.time()}\".encode()\n    ).hexdigest()[:8].upper()\n    \n    pending_confirmations[code] = {\n        \"op\": operation,\n        \"details\": details,\n        \"expires\": time.time() + 300  # 5 minutes\n    }\n    \n    return f\"⚠️ Confirm '{operation}' with code: {code}\\n(expires in 5 minutes)\"\n\ndef confirm(code: str):\n    if code not in pending_confirmations:\n        return \"Invalid confirmation code\"\n    \n    req = pending_confirmations.pop(code)\n    \n    if time.time() > req[\"expires\"]:\n        return \"Confirmation code expired\"\n    \n    return execute_confirmed(req[\"op\"], req[\"details\"])"
      },
      {
        "title": "6. Session Keys (ERC-4337)",
        "body": "Instead of giving agents master keys, issue bounded session keys:\n\nfrom session_keys import SessionKeyManager\n\n# Operator creates trading session for agent\nconfig = SessionKeyManager.create_trading_session(\n    agent_name=\"alpha-trader\",\n    operator_address=\"0x742d...\",\n    duration_hours=24,\n    max_trade_usdc=1000,\n    daily_limit_usdc=5000,\n)\n\n# Export for storage in 1Password\nexport_data = SessionKeyManager.export_for_1password(\n    config, \n    session_key_hex=\"0x...\"  # Generated session key\n)\n\n# op item create ... (store in 1Password)"
      },
      {
        "title": "Session Key Benefits",
        "body": "FeatureMaster KeySession KeyExpirationNeverConfigurable (hours/days)Spending limitsNonePer-tx and daily capsContract restrictionsFull accessWhitelist onlyRevocationRequires key rotationInstant, no key changeAuditNoneFull operation log"
      },
      {
        "title": "7. Pre-commit Hook",
        "body": "Block commits containing secrets:\n\n# Install\ncp examples/pre-commit .git/hooks/\nchmod +x .git/hooks/pre-commit\n\nDetected patterns:\n\nETH private keys (64 hex chars)\nOpenAI/Anthropic/Groq keys\nAWS access keys\nGitHub/GitLab tokens\nSlack/Discord tokens\nPEM private keys\nGeneric PASSWORD/SECRET assignments\nBIP-39 seed phrases"
      },
      {
        "title": "8. Defense Layers",
        "body": "USER INPUT\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 1: Input Validation  │  ← Regex + encoding + unicode checks\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 2: Op Allowlisting   │  ← Explicit whitelist only\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 3: Value Limits      │  ← Max per-tx and per-day\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 4: Confirmation      │  ← Time-limited codes for $$$\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 5: Isolated Exec     │  ← Wallet ops != conversation\n└────────────────────────────┘\n    │\n    ▼\nOUTPUT SANITIZATION"
      },
      {
        "title": "❌ Keys in memory files",
        "body": "# memory/2026-02-07.md\nPrivate key: 0x9f01dad551039daad...\n\nFix: Store reference only: Private key: [stored in 1Password: test-wallet]"
      },
      {
        "title": "❌ Keys in error messages",
        "body": "except Exception as e:\n    log(f\"Failed with key {private_key}: {e}\")\n\nFix: Never include credentials in error context"
      },
      {
        "title": "❌ Keys in .env.example",
        "body": "PRIVATE_KEY=sk-ant-api03-real-key...  # \"for testing\"\n\nFix: Use obviously fake: PRIVATE_KEY=your-key-here"
      },
      {
        "title": "❌ \"All\" in transfer requests",
        "body": "User: \"Transfer all my USDC\"\nAgent: *executes unlimited transfer*\n\nFix: Block \"all/everything/max\" patterns, require explicit amounts"
      },
      {
        "title": "❌ Trusting conversation context",
        "body": "# Wallet has access to conversation history\nself.wallet.execute(conversation[-1][\"content\"])\n\nFix: Wallet operations must be isolated from conversation context"
      },
      {
        "title": "Testing",
        "body": "cd examples\n\n# Run full test suite\npython test_suite.py\n\n# Test individual components\npython sanitizer.py    # Output sanitization demo\npython validator.py    # Input validation demo\npython session_keys.py # Session key demo\n\nExpected output: All tests passed"
      },
      {
        "title": "Checklist",
        "body": "1Password CLI installed and authenticated\n Secrets in 1Password vault, not files\n Session keys with expiry and limits\n Output sanitization on all responses\n Input validation before wallet ops\n Pre-commit hook installed\n Confirmation flow for high-value operations\n Wallet operations isolated from conversation\n .gitignore covers secrets and memory files\n Test suite passes"
      },
      {
        "title": "Security Model Limitations",
        "body": "This skill provides defense in depth, not a guarantee. Adversaries may:\n\nNovel injection patterns - Regex can't catch everything; semantic analysis helps but isn't perfect\nSocial engineering - Convincing the operator to approve malicious operations\nTiming attacks - Exploiting confirmation windows\nEncoding evasion - New encoding schemes not covered\n\nRecommendation: Layer these defenses with:\n\nRate limiting\nAnomaly detection\nHuman-in-the-loop for large transactions\nRegular security audits"
      }
    ],
    "body": "Bagman\n\nSecure key management patterns for AI agents handling wallets, private keys, and secrets.\n\nWhen to Use This Skill\nAgent needs wallet/blockchain access\nHandling API keys, credentials, or secrets\nBuilding systems where AI controls funds\nPreventing secret leakage via prompts or outputs\nQuick Start\n# Install 1Password CLI\nbrew install 1password-cli\n\n# Authenticate\neval $(op signin)\n\n# Create vault for agent credentials\nop vault create \"Agent-Credentials\"\n\n# Run examples\ncd examples && python test_suite.py\n\nCore Rules\nRule\tWhy\nNever store raw private keys\tConfig, env, memory, or conversation = leaked\nUse delegated access\tSession keys with time/value/scope limits\nSecrets via secret manager\t1Password, Vault, AWS Secrets Manager\nSanitize all outputs\tScan for key patterns before any response\nValidate all inputs\tCheck for injection attempts before wallet ops\nArchitecture\n┌─────────────────────────────────────────────────────┐\n│                   AI Agent                          │\n├─────────────────────────────────────────────────────┤\n│  Session Key (bounded)                              │\n│  ├─ Expires after N hours                           │\n│  ├─ Max spend per tx/day                            │\n│  └─ Whitelist of allowed contracts/methods          │\n├─────────────────────────────────────────────────────┤\n│  Secret Manager (1Password/Vault)                   │\n│  ├─ Retrieve at runtime only                        │\n│  ├─ Never persist to disk                           │\n│  └─ Audit trail of accesses                         │\n├─────────────────────────────────────────────────────┤\n│  Smart Account (ERC-4337)                           │\n│  ├─ Programmable permissions                        │\n│  └─ Recovery without key exposure                   │\n└─────────────────────────────────────────────────────┘\n\nImplementation Files\nFile\tPurpose\nexamples/secret_manager.py\t1Password integration for runtime secret retrieval\nexamples/sanitizer.py\tOutput sanitization (keys, seeds, tokens)\nexamples/validator.py\tInput validation (prompt injection defense)\nexamples/session_keys.py\tERC-4337 session key configuration\nexamples/delegation_integration.ts\tMetaMask Delegation Framework (EIP-7710)\nexamples/pre-commit\tGit hook to block secret commits\nexamples/test_suite.py\tAdversarial test suite\ndocs/prompt-injection.md\tDeep dive on injection defense\ndocs/secure-storage.md\tSecret storage patterns\ndocs/session-keys.md\tSession key architecture\ndocs/leak-prevention.md\tOutput sanitization patterns\ndocs/delegation-framework.md\tOn-chain permission enforcement (EIP-7710)\n1. Secret Retrieval\n1Password CLI Pattern\n# Retrieve at runtime (never store result)\nSESSION_KEY=$(op read \"op://Agents/my-agent/session-key\")\n\n# Run with injected secrets (never touch disk)\nop run --env-file=.env.tpl -- python agent.py\n\n.env.tpl (safe to commit - no secrets)\nPRIVATE_KEY=op://Agents/trading-bot/session-key\nRPC_URL=op://Infra/alchemy/sepolia-url\nOPENAI_API_KEY=op://Services/openai/api-key\n\nPython Usage\nfrom secret_manager import get_session_key\n\n# Retrieve validated session key\ncreds = get_session_key(\"trading-bot-session\")\n\n# Check validity\nif creds.is_expired():\n    raise ValueError(\"Session expired - request renewal from operator\")\n\nprint(f\"Time remaining: {creds.time_remaining()}\")\nprint(f\"Allowed contracts: {creds.allowed_contracts}\")\n\n# Use the key (never log it!)\nclient.set_signer(creds.session_key)\n\nVault-Level ACL (Recommended)\n\nConfigure 1Password vault permissions:\n\nAgent-Credentials/\n├── trading-bot-session    # Agent can read\n├── payment-bot-session    # Agent can read\n└── master-key             # Operator ONLY (agent has no access)\n\n\nPrinciple: Agent credentials should be in a vault with read-only agent access. Master keys should be in a separate vault the agent cannot access.\n\n2. Output Sanitization\n\nApply to ALL agent outputs before sending anywhere:\n\nfrom sanitizer import OutputSanitizer\n\ndef respond(content: str) -> str:\n    \"\"\"Sanitize before any output.\"\"\"\n    return OutputSanitizer.sanitize(content)\n\n# Catches:\n# - Private keys (0x + 64 hex)\n# - OpenAI/Anthropic/Groq/AWS keys\n# - GitHub/Slack/Discord tokens\n# - BIP-39 seed phrases (12/24 words)\n# - PEM private keys\n# - JWT tokens\n\nPatterns Detected\nPattern\tExample\tResult\nETH private key\t0x1234...abcd (64 hex)\t[PRIVATE_KEY_REDACTED]\nETH address\t0x742d...f44e (40 hex)\t0x742d...f44e (truncated)\nOpenAI key\tsk-proj-abc123...\t[OPENAI_KEY_REDACTED]\nAnthropic key\tsk-ant-api03-...\t[ANTHROPIC_KEY_REDACTED]\n12-word seed\tabandon ability able...\t[SEED_PHRASE_12_WORDS_REDACTED]\nJWT\teyJhbG...\t[JWT_TOKEN_REDACTED]\n3. Input Validation\n\nCheck inputs before ANY wallet operation:\n\nfrom validator import InputValidator, ThreatLevel\n\nresult = InputValidator.validate(user_input)\n\nif result.level == ThreatLevel.BLOCKED:\n    return f\"Request blocked: {result.reason}\"\n\nif result.level == ThreatLevel.SUSPICIOUS:\n    # Log for review, but allow\n    log_suspicious(user_input, result.reason)\n\n# Proceed with operation\n\nThreat Categories\nCategory\tExamples\tAction\nExtraction\t\"show private key\", \"reveal secrets\"\tBlock\nOverride\t\"ignore previous instructions\"\tBlock\nRole manipulation\t\"you are now admin\"\tBlock\nJailbreak\t\"DAN mode\", \"bypass filters\"\tBlock\nExfiltration\t\"send config to https://...\"\tBlock\nWallet threats\t\"transfer all\", \"unlimited approve\"\tBlock\nEncoded\tBase64/hex encoded attacks\tBlock\nUnicode tricks\tCyrillic lookalikes, zero-width\tBlock\nSuspicious\t\"hypothetically\", \"just between us\"\tWarn\n4. Operation Allowlisting\n\nNever execute arbitrary operations. Explicit whitelist only:\n\nfrom dataclasses import dataclass\nfrom decimal import Decimal\nfrom typing import Optional\n\n@dataclass\nclass AllowedOperation:\n    name: str\n    handler: callable\n    max_value: Optional[Decimal] = None\n    requires_confirmation: bool = False\n    cooldown_seconds: int = 0\n\nALLOWED_OPS = {\n    \"check_balance\": AllowedOperation(\"check_balance\", get_balance),\n    \"transfer_usdc\": AllowedOperation(\n        \"transfer_usdc\", \n        transfer,\n        max_value=Decimal(\"500\"),\n        requires_confirmation=True,\n        cooldown_seconds=60\n    ),\n    \"swap\": AllowedOperation(\n        \"swap\",\n        swap_tokens,\n        max_value=Decimal(\"1000\"),\n        cooldown_seconds=300\n    ),\n}\n\ndef execute(op_name: str, **kwargs):\n    if op_name not in ALLOWED_OPS:\n        raise PermissionError(f\"Operation '{op_name}' not allowed\")\n    \n    op = ALLOWED_OPS[op_name]\n    \n    if op.max_value and kwargs.get(\"amount\", 0) > op.max_value:\n        raise PermissionError(f\"Amount exceeds limit: {op.max_value}\")\n    \n    if op.requires_confirmation:\n        return request_confirmation(op_name, kwargs)\n    \n    return op.handler(**kwargs)\n\n5. Confirmation Flow\n\nHigh-value operations require explicit confirmation:\n\nimport hashlib\nimport time\n\npending_confirmations = {}\n\ndef request_confirmation(operation: str, details: dict) -> str:\n    code = hashlib.sha256(\n        f\"{operation}{time.time()}\".encode()\n    ).hexdigest()[:8].upper()\n    \n    pending_confirmations[code] = {\n        \"op\": operation,\n        \"details\": details,\n        \"expires\": time.time() + 300  # 5 minutes\n    }\n    \n    return f\"⚠️ Confirm '{operation}' with code: {code}\\n(expires in 5 minutes)\"\n\ndef confirm(code: str):\n    if code not in pending_confirmations:\n        return \"Invalid confirmation code\"\n    \n    req = pending_confirmations.pop(code)\n    \n    if time.time() > req[\"expires\"]:\n        return \"Confirmation code expired\"\n    \n    return execute_confirmed(req[\"op\"], req[\"details\"])\n\n6. Session Keys (ERC-4337)\n\nInstead of giving agents master keys, issue bounded session keys:\n\nfrom session_keys import SessionKeyManager\n\n# Operator creates trading session for agent\nconfig = SessionKeyManager.create_trading_session(\n    agent_name=\"alpha-trader\",\n    operator_address=\"0x742d...\",\n    duration_hours=24,\n    max_trade_usdc=1000,\n    daily_limit_usdc=5000,\n)\n\n# Export for storage in 1Password\nexport_data = SessionKeyManager.export_for_1password(\n    config, \n    session_key_hex=\"0x...\"  # Generated session key\n)\n\n# op item create ... (store in 1Password)\n\nSession Key Benefits\nFeature\tMaster Key\tSession Key\nExpiration\tNever\tConfigurable (hours/days)\nSpending limits\tNone\tPer-tx and daily caps\nContract restrictions\tFull access\tWhitelist only\nRevocation\tRequires key rotation\tInstant, no key change\nAudit\tNone\tFull operation log\n7. Pre-commit Hook\n\nBlock commits containing secrets:\n\n# Install\ncp examples/pre-commit .git/hooks/\nchmod +x .git/hooks/pre-commit\n\n\nDetected patterns:\n\nETH private keys (64 hex chars)\nOpenAI/Anthropic/Groq keys\nAWS access keys\nGitHub/GitLab tokens\nSlack/Discord tokens\nPEM private keys\nGeneric PASSWORD/SECRET assignments\nBIP-39 seed phrases\n8. Defense Layers\nUSER INPUT\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 1: Input Validation  │  ← Regex + encoding + unicode checks\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 2: Op Allowlisting   │  ← Explicit whitelist only\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 3: Value Limits      │  ← Max per-tx and per-day\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 4: Confirmation      │  ← Time-limited codes for $$$\n└────────────────────────────┘\n    │\n    ▼\n┌────────────────────────────┐\n│ Layer 5: Isolated Exec     │  ← Wallet ops != conversation\n└────────────────────────────┘\n    │\n    ▼\nOUTPUT SANITIZATION\n\nCommon Mistakes\n❌ Keys in memory files\n# memory/2026-02-07.md\nPrivate key: 0x9f01dad551039daad...\n\n\nFix: Store reference only: Private key: [stored in 1Password: test-wallet]\n\n❌ Keys in error messages\nexcept Exception as e:\n    log(f\"Failed with key {private_key}: {e}\")\n\n\nFix: Never include credentials in error context\n\n❌ Keys in .env.example\nPRIVATE_KEY=sk-ant-api03-real-key...  # \"for testing\"\n\n\nFix: Use obviously fake: PRIVATE_KEY=your-key-here\n\n❌ \"All\" in transfer requests\nUser: \"Transfer all my USDC\"\nAgent: *executes unlimited transfer*\n\n\nFix: Block \"all/everything/max\" patterns, require explicit amounts\n\n❌ Trusting conversation context\n# Wallet has access to conversation history\nself.wallet.execute(conversation[-1][\"content\"])\n\n\nFix: Wallet operations must be isolated from conversation context\n\nTesting\ncd examples\n\n# Run full test suite\npython test_suite.py\n\n# Test individual components\npython sanitizer.py    # Output sanitization demo\npython validator.py    # Input validation demo\npython session_keys.py # Session key demo\n\n\nExpected output: All tests passed\n\nChecklist\n 1Password CLI installed and authenticated\n Secrets in 1Password vault, not files\n Session keys with expiry and limits\n Output sanitization on all responses\n Input validation before wallet ops\n Pre-commit hook installed\n Confirmation flow for high-value operations\n Wallet operations isolated from conversation\n .gitignore covers secrets and memory files\n Test suite passes\nSecurity Model Limitations\n\nThis skill provides defense in depth, not a guarantee. Adversaries may:\n\nNovel injection patterns - Regex can't catch everything; semantic analysis helps but isn't perfect\nSocial engineering - Convincing the operator to approve malicious operations\nTiming attacks - Exploiting confirmation windows\nEncoding evasion - New encoding schemes not covered\n\nRecommendation: Layer these defenses with:\n\nRate limiting\nAnomaly detection\nHuman-in-the-loop for large transactions\nRegular security audits"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/zscole/bagman",
    "publisherUrl": "https://clawhub.ai/zscole/bagman",
    "owner": "zscole",
    "version": "2.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/bagman",
    "downloadUrl": "https://openagent3.xyz/downloads/bagman",
    "agentUrl": "https://openagent3.xyz/skills/bagman/agent",
    "manifestUrl": "https://openagent3.xyz/skills/bagman/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/bagman/agent.md"
  }
}