doc: update base_url ver: bump
8.3 KiB
Secure Memory Operations
Overview
NOMYO now includes client-side secure memory operations to protect sensitive data in memory. This feature prevents plaintext payloads from being swapped to disk and guarantees memory is zeroed after encryption.
Features
- Cross-platform support: Linux, Windows, macOS
- Memory locking: Prevents sensitive data from being swapped to disk
- Guaranteed zeroing: Memory is cleared immediately after use
- Context managers: Automatic cleanup even on exceptions
- Backward compatible: Works even if secure memory is not available
- Configurable: Can be enabled/disabled per client instance
Security Benefits
- Prevent memory swapping: Sensitive data won't be written to disk via swap files
- Guaranteed zeroing: Memory is cleared immediately after encryption
- Protection against memory dumping: Reduces risk from memory analysis tools
- Automatic cleanup: Context managers ensure cleanup even on exceptions
Usage
Basic Usage
from nomyo import SecureChatCompletion
# Create client with secure memory enabled (default)
client = SecureChatCompletion(
base_url="https://api.nomyo.ai",
secure_memory=True # Enabled by default
)
# Use as normal - payloads are automatically protected
response = await client.create(
model="Qwen/Qwen3-0.6B",
messages=[{"role": "user", "content": "Sensitive data"}]
)
Disabling Secure Memory
from nomyo import SecureChatCompletion
# Disable secure memory for testing or when not needed
client = SecureChatCompletion(
base_url="https://api.nomyo.ai",
secure_memory=False
)
Global Configuration
from nomyo import disable_secure_memory, enable_secure_memory, get_memory_protection_info
# Disable globally
disable_secure_memory()
# Enable globally
enable_secure_memory()
# Check current status
info = get_memory_protection_info()
print(f"Secure memory enabled: {info['enabled']}")
print(f"Platform: {info['platform']}")
print(f"Protection level: {info['protection_level']}")
Using Secure Bytes Directly
from nomyo import secure_bytes
# Protect sensitive data
sensitive_data = b"Secret information"
with secure_bytes(sensitive_data) as protected:
# Data is locked in memory and will be zeroed on exit
process(protected)
# Memory automatically zeroed here
Platform Support
| Platform | Memory Locking | Secure Zeroing | Protection Level |
|---|---|---|---|
| Linux | ✓ (mlock) | ✓ (memset) | Full |
| Windows | ✓ (VirtualLock) | ✓ (RtlSecureZeroMemory) | Full |
| macOS | ✓ (mlock) | ✓ (memset) | Full |
| Other | ✗ | ✓ (fallback) | Zeroing only |
Implementation Details
Memory Locking
- Linux/macOS: Uses
mlock()system call to lock memory pages - Windows: Uses
VirtualLock()API to lock memory pages - Fallback: If memory locking fails, only zeroing is performed
Memory Zeroing
- bytearray: Zeroed in-place for maximum security
- bytes: Best-effort approach (Python's immutable bytes)
- Automatic: Always performed when exiting context manager
Error Handling
- Graceful degradation: If memory locking fails, continues with zeroing
- No exceptions: Operations continue even if security features unavailable
- Logging: Detailed logs for debugging security issues
Best Practices
- Keep secure memory enabled in production environments
- Use HTTPS for all communications (enabled by default)
- Encrypt sensitive data before processing
- Minimize plaintext lifetime - encrypt as soon as possible
- Monitor security logs for any issues with memory protection
Troubleshooting
Memory Locking Failures
Error: mlock permission denied
Solution: Grant CAP_IPC_LOCK capability or increase ulimit -l
# Temporary solution
sudo prlimit --memlock=unlimited --pid $$
# Permanent solution (Linux)
sudo setcap cap_ipc_lock=ep $(which python)
Windows: Usually works without special privileges
macOS: Usually works without special privileges
Secure Memory Unavailable
If secure memory is not available, the system falls back to standard memory handling with a warning. This ensures the application continues to work while alerting you to the reduced security level.
API Reference
Classes
SecureMemory
Cross-platform secure memory handler.
Methods:
lock_memory(data: bytes) -> bool: Lock memory to prevent swappingunlock_memory(data: bytes) -> bool: Unlock memory pageszero_memory(data: bytes) -> None: Securely zero memoryget_protection_info() -> dict: Get capability information
Context Managers
secure_bytes(data: bytes, lock: bool = True)
Context manager for secure byte handling.
Parameters:
data: Bytes to protectlock: Whether to attempt memory locking (default: True)
Example:
with secure_bytes(sensitive_data) as protected:
# Use protected data
pass
# Memory automatically zeroed
Functions
get_memory_protection_info() -> dict
Get information about available memory protection features.
Returns:
- Dictionary with protection status including:
enabled: Whether secure memory is enabledplatform: Current platformprotection_level: "full", "zeroing_only", or "none"has_memory_locking: Whether memory locking is availablehas_secure_zeroing: Whether secure zeroing is availablesupports_full_protection: Whether full protection is available
disable_secure_memory() -> None
Disable secure memory operations globally.
enable_secure_memory() -> None
Re-enable secure memory operations globally.
Examples
Secure Chat Completion
from nomyo import SecureChatCompletion
async def secure_chat():
# Create client with maximum security
client = SecureChatCompletion(
base_url="https://api.nomyo.ai",
secure_memory=True # Default
)
# All payloads are automatically protected
response = await client.create(
model="Qwen/Qwen3-0.6B",
messages=[
{"role": "system", "content": "You are a secure assistant"},
{"role": "user", "content": "Sensitive information here"}
],
temperature=0.7
)
return response
Secure Data Processing
from nomyo import secure_bytes
import json
def process_sensitive_data(data_dict):
# Serialize to JSON
data_json = json.dumps(data_dict).encode('utf-8')
# Process with secure memory
with secure_bytes(data_json) as protected:
# Perform operations on protected data
result = encrypt_and_send(protected)
return result
Checking Security Status
from nomyo import get_memory_protection_info
def check_security_status():
info = get_memory_protection_info()
print(f"Security Status:")
print(f" Enabled: {info['enabled']}")
print(f" Platform: {info['platform']}")
print(f" Protection Level: {info['protection_level']}")
print(f" Memory Locking: {info['has_memory_locking']}")
print(f" Secure Zeroing: {info['has_secure_zeroing']}")
return info
Security Considerations
Memory Protection Levels
-
Full Protection (Linux/Windows/macOS):
- Memory locked to prevent swapping
- Memory zeroed after use
- Best security available
-
Zeroing Only (Fallback):
- Memory zeroed after use
- No memory locking
- Still provides significant security benefits
-
None (Disabled):
- No memory protection
- Standard Python memory management
- Only for testing or non-sensitive applications
When to Disable Secure Memory
Secure memory should only be disabled in the following scenarios:
- Testing: When testing encryption/decryption without security
- Performance testing: Measuring baseline performance
- Non-sensitive data: When processing public/non-sensitive information
- Debugging: When memory analysis is required
Security Warnings
- Memory locking may fail without appropriate privileges
- Python's memory management limits zeroing effectiveness for immutable bytes
- Always use HTTPS for production deployments
- Monitor logs for security-related warnings