AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Bagman Skill

skill-zscole-bagman-skill-bagman-skill · by zscole

A Claude skill from zscole/bagman-skill.

— No reviews yet
0 installs
24 views
0.0% view→install

Install

$ agentstack add skill-zscole-bagman-skill-bagman-skill

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • • Prompt-injection patterns
  • • Secret / credential exfiltration
  • • Dangerous shell & filesystem operations
  • • Untrusted network calls
  • • Known-malicious package signatures
  • high Possible prompt-injection directive.

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ● Environment & secrets Used
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

— Not yet reviewed
0 installs to date
— no reviews yet
○ 7mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Bagman Skill? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

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) | | docs/autonomous-operation.md | Autonomous vs. supervised modes |


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.

Autonomous-first design: Agents should operate within bounds without asking for approval on every transaction. Use on-chain delegation caveats as the primary protection, software limits as backup.

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  # Default: autonomous
    cooldown_seconds: int = 0

# Autonomous operations (no confirmation needed - delegation caveats enforce limits)
ALLOWED_OPS = {
    "check_balance": AllowedOperation("check_balance", get_balance),
    "transfer_usdc": AllowedOperation(
        "transfer_usdc", 
        transfer,
        max_value=Decimal("500"),      # Software limit (backup)
        requires_confirmation=False,    # On-chain caveats are primary protection
        cooldown_seconds=0
    ),
    "swap": AllowedOperation(
        "swap",
        swap_tokens,
        max_value=Decimal("1000"),
        requires_confirmation=False,
        cooldown_seconds=0
    ),
    # Only require confirmation for exceptional cases
    "emergency_withdraw": AllowedOperation(
        "emergency_withdraw",
        emergency_withdraw,
        requires_confirmation=True,     # Human-in-the-loop for emergencies
    ),
}

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)

When to Use Each Protection Layer

| Layer | Use When | Example | |-------|----------|---------| | Delegation caveats (primary) | Normal autonomous operation | Daily trading, payments | | Software limits (backup) | Defense in depth | max_value checks | | Confirmation codes (opt-in) | Exceptional high-risk actions | Emergency withdrawals, revoking access |


5. Confirmation Flow (Opt-In)

Most agents should NOT use this for normal operations. Delegation caveats provide on-chain protection without friction.

Use confirmation codes only for exceptional cases where human oversight is required:

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

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.