✓ Verified 🌐 Web Scrapers ✓ Enhanced Data

Bagman

Secure key management for AI agents.

Rating
4.1 (20 reviews)
Downloads
22,925 downloads
Version
1.0.0

Overview

Secure key management for AI agents.

Complete Documentation

View Source →

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

RuleWhy
Never store raw private keysConfig, env, memory, or conversation = leaked
Use delegated accessSession keys with time/value/scope limits
Secrets via secret manager1Password, Vault, AWS Secrets Manager
Sanitize all outputsScan for key patterns before any response
Validate all inputsCheck for injection attempts before wallet ops

Architecture

text
┌─────────────────────────────────────────────────────┐
│                   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

FilePurpose
examples/secret_manager.py1Password integration for runtime secret retrieval
examples/sanitizer.pyOutput sanitization (keys, seeds, tokens)
examples/validator.pyInput validation (prompt injection defense)
examples/session_keys.pyERC-4337 session key configuration
examples/delegation_integration.tsMetaMask Delegation Framework (EIP-7710)
examples/pre-commitGit hook to block secret commits
examples/test_suite.pyAdversarial test suite
docs/prompt-injection.mdDeep dive on injection defense
docs/secure-storage.mdSecret storage patterns
docs/session-keys.mdSession key architecture
docs/leak-prevention.mdOutput sanitization patterns
docs/delegation-framework.mdOn-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)

text
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:

text
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

PatternExampleResult
ETH 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]

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

CategoryExamplesAction
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
EncodedBase64/hex encoded attacksBlock
Unicode tricksCyrillic lookalikes, zero-widthBlock
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: 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:

python
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

FeatureMaster KeySession Key
ExpirationNeverConfigurable (hours/days)
Spending limitsNonePer-tx and daily caps
Contract restrictionsFull accessWhitelist only
RevocationRequires key rotationInstant, no key change
AuditNoneFull operation log

7. Pre-commit Hook

Block commits containing secrets:

bash
# 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

text
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

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

❌ Keys in error messages

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

❌ Keys in .env.example

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

❌ "All" in transfer requests

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

❌ Trusting conversation context

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


Testing

bash
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:

  • Novel injection patterns - Regex can't catch everything; semantic analysis helps but isn't perfect
  • Social engineering - Convincing the operator to approve malicious operations
  • Timing attacks - Exploiting confirmation windows
  • 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

Installation

Terminal bash

openclaw install bagman
    
Copied!

💻Code Examples

cd examples && python test_suite.py

cd-examples--python-testsuitepy.txt
---

## 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

└─────────────────────────────────────────────────────┘

.txt
---

## 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

client.set_signer(creds.session_key)

clientsetsignercredssessionkey.txt
### Vault-Level ACL (Recommended)

Configure 1Password vault permissions:

└── master-key # Operator ONLY (agent has no access)

-master-key--operator-only-agent-has-no-access.txt
**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:

# - JWT tokens

---jwt-tokens.txt
### 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:

# Proceed with operation

-proceed-with-operation.txt
### 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:

return op.handler(**kwargs)

-return-ophandlerkwargs.txt
---

## 5. Confirmation Flow

High-value operations require explicit confirmation:

return execute_confirmed(req["op"], req["details"])

-return-executeconfirmedreqop-reqdetails.txt
---

## 6. Session Keys (ERC-4337)

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

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

-op-item-create--store-in-1password.txt
### 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:

chmod +x .git/hooks/pre-commit

chmod-x-githookspre-commit.txt
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

Tags

#search_and-research

Quick Info

Category Web Scrapers
Model Claude 3.5
Complexity Multi-Agent
Author zscole
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install bagman