Skip to main content

Anonymize AWS infrastructure identifiers for secure LLM processing

Project description

CloudMask Logo

CloudMask-AWS 🎭

Anonymize AWS infrastructure identifiers for secure LLM processing

PyPI version Python Versions License: MIT

CloudMask helps you safely share AWS infrastructure data with Large Language Models by anonymizing sensitive identifiers while maintaining structure and reversibility.

Features

  • 🔒 Secure Anonymization: Hash-based deterministic anonymization
  • 🔄 Reversible: Complete mapping for unanonymization
  • 🏗️ Structure-Preserving: Maintains AWS resource ID prefixes (vpc-, i-, etc.)
  • ⚙️ Configurable: YAML-based configuration for company names and custom patterns
  • 🐍 Dual Interface: Use as CLI tool or Python library
  • 📋 Clipboard Support: Direct clipboard anonymization for quick workflows
  • 📦 Modern Python: Built with Python 3.10+ features (pattern matching, union types)
  • 🚀 Minimal Dependencies: Only requires PyYAML and pyperclip

Requirements

  • Python 3.10 or higher
  • PyYAML 6.0+

CloudMask leverages modern Python features including structural pattern matching, union type operators, and built-in generic types.

Installation

pip install cloudmask-aws

Quick Start

CLI Usage

# Generate config file
cloudmask init-config

# Anonymize (mapping stored in ~/.cloudmask/mapping.json by default)
cloudmask anonymize -i infrastructure.txt -o anonymized.txt

# Anonymize clipboard content
cloudmask anonymize --clipboard

# Restore original values
cloudmask unanonymize -i llm-response.txt -o restored.txt

# Restore clipboard content
cloudmask unanonymize --clipboard

# Use custom mapping location if needed
cloudmask anonymize --clipboard -m /path/to/custom-mapping.json

Python Library Usage

from cloudmask import CloudMask, CloudUnmask, get_default_mapping_path

# Anonymize text
mask = CloudMask(seed="my-secret-seed")
anonymized = mask.anonymize("""
    Instance i-1234567890abcdef0 is running in vpc-abcdef123456
    Account: 123456789012
    Company: Acme Corp
""")

# Save mapping to secure central location (~/.cloudmask/mapping.json)
mask.save_mapping(get_default_mapping_path())

# Unanonymize later
unmask = CloudUnmask(mapping_file=get_default_mapping_path())
original = unmask.unanonymize(anonymized)

Quick Function Usage

from cloudmask import anonymize, unanonymize

# One-liner anonymization
text, mapping = anonymize(
    "Instance i-123 in account 123456789012",
    seed="my-seed",
    company_names=["Acme Corp"]
)

# Restore original
original = unanonymize(text, mapping)

Configuration

Create a ~/.cloudmask/config.yml file (or use cloudmask init-config):

company_names:
  - Acme Corp
  - Example Inc
  - MyCompany LLC

custom_patterns:
  - pattern: '\bTICKET-\d{4,6}\b'
    name: ticket
  - pattern: '\bPROJ-[A-Z0-9]+'
    name: project
  # Example: Match company domains
  - pattern: '[a-zA-Z0-9][-a-zA-Z0-9.]*\.acme\.local\b'
    name: domain
  # Example: Match company emails
  - pattern: '[a-zA-Z0-9._%+-]+@acme-corp\.local\b'
    name: email

preserve_prefixes: true
anonymize_ips: true
anonymize_domains: false
seed: my-secret-seed

Custom Pattern Edge Cases

When creating custom patterns, be aware of:

  • Case sensitivity: Patterns are case-insensitive by default
  • Multi-level subdomains: Use [-a-zA-Z0-9.]* to match app.corp.acme.local
  • HTML entities: " in data is handled automatically
  • Email variations: Pattern supports user+tag@domain and user.name@domain
  • URLs and paths: Patterns work in https://server.acme.local/path
  • Trailing punctuation: Word boundaries (\b) handle server.acme.local.

Test your patterns:

cloudmask anonymize -i test.txt -o output.txt
grep -i "sensitive-term" output.txt  # Should return nothing

What Gets Anonymized?

  • ✅ AWS Resource IDs (vpc-, i-, sg-, ami-, etc.)
  • ✅ AWS Account IDs (12-digit numbers)
  • ✅ AWS ARNs
  • ✅ IP Addresses
  • ✅ Company names (from config)
  • ✅ Custom patterns (via regex)
  • ✅ Domain names (optional)

Use Cases

  • 🤖 LLM Assistance: Get help with infrastructure without exposing sensitive IDs
  • 📊 Data Sharing: Share infrastructure diagrams and configs safely
  • 🔍 Security Analysis: Analyze configs with external tools
  • 📝 Documentation: Create shareable examples from real infrastructure

Advanced Usage

Using in Scripts

from cloudmask import CloudMask, Config
from pathlib import Path

# Load custom config
config = Config.from_yaml(Path("custom-config.yaml"))

# Create anonymizer
mask = CloudMask(config=config, seed="production-seed")

# Process multiple files
for file in Path("configs").glob("*.yaml"):
    output = Path("anonymized") / file.name
    mask.anonymize_file(file, output)

# Save single mapping for all files
mask.save_mapping("master-mapping.json")

Context Manager

from cloudmask import TemporaryMask

with TemporaryMask(seed="temp-seed") as mask:
    anonymized = mask.anonymize("vpc-123 i-456")
    # Process anonymized data
    # Mapping is discarded after context exits

Batch Processing

from cloudmask import create_batch_anonymizer

# Create reusable anonymizer
anon = create_batch_anonymizer(seed="batch-seed")

# Use it multiple times
result1 = anon("vpc-123")
result2 = anon("i-456")

Central Storage

CloudMask stores mapping files in a secure central location by default:

~/.cloudmask/mapping.json

Benefits

  • 🔐 Automatic Security: Files created with 600 permissions (owner read/write only)
  • 📍 Centralized: All mappings in one location
  • 🔄 Auto-Merge: New mappings are merged with existing ones (same seed required)
  • Convenient: No need to specify -m flag for common workflows

Seed Verification

CloudMask tracks which seed created each mapping file. Mappings can only be merged if they use the same seed:

# First use
mask1 = CloudMask(seed="prod-seed")
mask1.anonymize("vpc-11111")
mask1.save_mapping(get_default_mapping_path())  # Creates mapping

# Later use with SAME seed - mappings merge automatically
mask2 = CloudMask(seed="prod-seed")
mask2.anonymize("vpc-22222")
mask2.save_mapping(get_default_mapping_path())  # Merges with existing

# Different seed - prevents accidental corruption
mask3 = CloudMask(seed="different-seed")
mask3.save_mapping(get_default_mapping_path())  # ERROR: Seed mismatch

Custom Locations

You can still use custom mapping locations:

cloudmask anonymize -i file.txt -m /custom/path/mapping.json
mask.save_mapping("/custom/path/mapping.json")

Security Notes

⚠️ Keep your mapping files secure! They contain the reversible mappings.

  • The ~/.cloudmask/ directory is automatically secured with 700 permissions
  • Mapping files are created with 600 permissions (owner only)
  • Store mapping files separately from anonymized data
  • Use strong, unique seeds for different projects
  • Don't commit mapping files to version control
  • Consider encrypting mapping files for sensitive data
  • Always use the same seed for a project to enable mapping merges

Contributing

Contributions welcome! Please check out the GitHub repository.

License

MIT License - see LICENSE file for details

Troubleshooting

Pattern Not Matching?

  1. Test the regex: python -c "import re; print(re.search(r'your-pattern', 'test-string'))"
  2. Check case sensitivity: Patterns are case-insensitive
  3. Verify word boundaries: \b may not work with special characters
  4. Test with real data: Use small samples first

Data Still Leaking?

  1. Check pattern order: Custom patterns run before company names
  2. Verify pattern name: Use generic names like domain, not acme-domain
  3. Test thoroughly: grep -i "sensitive" output.txt

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cloudmask_aws-0.3.0.tar.gz (447.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloudmask_aws-0.3.0-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file cloudmask_aws-0.3.0.tar.gz.

File metadata

  • Download URL: cloudmask_aws-0.3.0.tar.gz
  • Upload date:
  • Size: 447.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for cloudmask_aws-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e1f00034fe1efd708f5d5142958f72c2a1199631a66215f11953d92c5d3036b1
MD5 4fb6db523c86721835ea66a5906641cb
BLAKE2b-256 5fa9b0b25f901e5c9bb6b6a296c533343ec090cf8133531230f8905b64791c28

See more details on using hashes here.

File details

Details for the file cloudmask_aws-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: cloudmask_aws-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for cloudmask_aws-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e53837d6c6dee409e4bd491ddb097be141b54141063c7b15cdfa3a42baaffbe1
MD5 2eaacd263f5d9e51ee3f6fa148b6c28f
BLAKE2b-256 6f2f0c18fa968cdec33aa2c4cf40fd015c409bbc3e760754c8fa63f872d0690c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page