Lynguine Secure Credential Management
Overview
Lynguine’s secure credential management system provides enterprise-grade security for API credentials, OAuth tokens, and other sensitive authentication data. This system addresses critical vulnerabilities in credential storage and access while maintaining backward compatibility with existing configurations.
Features
Core Security Features
Multiple Storage Backends: Environment variables, encrypted files, and cloud vault integration
End-to-End Encryption: AES encryption with PBKDF2 key derivation for stored credentials
Access Control: Role-based access control with fine-grained permissions
Audit Logging: Comprehensive security event logging for compliance
Rate Limiting: Protection against brute force attacks
Credential Rotation: Support for automatic credential rotation
Secure Error Handling: Prevents credential leakage in logs and exceptions
Integration Features
Backward Compatible: Works with existing lynguine configurations
Credential References: Use
${credential:name}syntax in configuration filesMigration Tools: Automated migration from plain-text credentials
Validation: Credential format and type validation
Caching: TTL-based caching for performance
Quick Start
Installation
The basic credential system works out of the box. For encrypted storage, install the cryptography library:
pip install cryptography
Basic Usage
1. Storing Credentials
from lynguine.security import set_credential
# Store Google Sheets OAuth credentials
google_creds = {
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"redirect_uri": "http://localhost:8080"
}
set_credential("google_sheets_oauth", google_creds)
2. Using Credentials in Configuration
Update your _lynguine.yml or machine.yml:
google_oauth: ${credential:google_sheets_oauth}
3. Retrieving Credentials Programmatically
from lynguine.security import get_credential
creds = get_credential("google_sheets_oauth")
print(f"Client ID: {creds['value']['client_id']}")
Storage Backends
Environment Variables
Best for: Development, CI/CD pipelines, containerized environments
# Set credential as environment variable
export LYNGUINE_CRED_GOOGLE_SHEETS_OAUTH='{"client_id":"...","client_secret":"..."}'
from lynguine.security import EnvironmentCredentialProvider, CredentialManager
provider = EnvironmentCredentialProvider(prefix="LYNGUINE_CRED")
manager = CredentialManager(providers=[provider])
Advantages:
No additional dependencies
Easy integration with deployment systems
No file storage required
Disadvantages:
Credentials visible in process environment
Not suitable for long-term storage
Limited to process lifetime
Encrypted Files
Best for: Production environments, persistent storage, desktop applications
from lynguine.security import EncryptedFileCredentialProvider, CredentialManager
# Set master key (do this once, store securely!)
import os
os.environ["LYNGUINE_MASTER_KEY"] = "your-secure-master-password"
provider = EncryptedFileCredentialProvider(
storage_path="~/.lynguine/credentials",
master_key=os.environ["LYNGUINE_MASTER_KEY"]
)
manager = CredentialManager(providers=[provider])
Advantages:
Strong encryption (AES via Fernet)
Persistent storage
Secure file permissions (0600)
Metadata tracking
Disadvantages:
Requires cryptography library
Master key management required
Slower than environment variables
Cloud Vaults (Future)
Support for HashiCorp Vault and AWS Secrets Manager is planned for future releases.
Access Control
Basic Access Control
from lynguine.security import AccessPolicy, AccessLevel
policy = AccessPolicy()
# Allow specific user read access to production credentials
policy.add_rule(
credential_pattern="prod_*",
user_pattern="prod_user",
access_level=AccessLevel.READ
)
# Allow admins full access to all credentials
policy.add_rule(
credential_pattern="*",
user_pattern="admin",
access_level=AccessLevel.ADMIN
)
Access Levels
NONE: No accessREAD: Can retrieve credentialsWRITE: Can create and update credentialsDELETE: Can delete credentialsADMIN: Full access to all operations
Audit Logging
Enable Audit Logging
from lynguine.security import AuditLogger, AuditEventType
# Create audit logger
audit_logger = AuditLogger(
log_path="~/.lynguine/audit.log",
enable_file=True,
enable_console=False
)
Query Audit Events
from datetime import datetime, timedelta
# Query last 24 hours of credential access events
events = audit_logger.query_events(
event_type=AuditEventType.CREDENTIAL_ACCESS,
start_time=datetime.now() - timedelta(days=1),
limit=100
)
for event in events:
print(f"{event['timestamp']}: {event['user']} accessed {event['credential_key']}")
Audit Event Types
CREDENTIAL_ACCESS: Credential retrievedCREDENTIAL_CREATE: New credential createdCREDENTIAL_UPDATE: Credential modifiedCREDENTIAL_DELETE: Credential deletedACCESS_DENIED: Access attempt deniedVALIDATION_FAILED: Credential validation failedRATE_LIMIT_EXCEEDED: Rate limit triggered
Secure Logging
Prevent credential leakage in application logs:
from lynguine.security import get_secure_logger, setup_secure_logging
# Get a secure logger that automatically sanitizes sensitive data
logger = get_secure_logger(__name__)
# Sensitive data is automatically redacted
logger.info(f"Connecting with api_key={api_key}")
# Output: "Connecting with api_key=***API_KEY***"
# Set up secure logging for the entire application
setup_secure_logging(level=logging.INFO)
Custom Sanitization
from lynguine.security import sanitize_dict
sensitive_data = {
"username": "john",
"password": "secret123",
"api_key": "abc-xyz-123"
}
sanitized = sanitize_dict(sensitive_data)
print(sanitized)
# {'username': 'john', 'password': '***', 'api_key': '***REDACTED***'}
Migration
Automated Migration
Migrate existing plain-text credentials to secure storage:
from lynguine.security import CredentialMigrator
# Set master key for encrypted storage
import os
os.environ["LYNGUINE_MASTER_KEY"] = "your-master-key"
# Create migrator
migrator = CredentialMigrator()
# Migrate Google Sheets credentials
report = migrator.migrate_google_sheets_credentials(
config_file="~/.lynguine/config/machine.yml",
credential_name="google_sheets_oauth",
dry_run=False # Set True to test first
)
print(f"Migrated: {len(report['migrated'])} credentials")
print(f"Errors: {len(report['errors'])} errors")
# Validate migration
validation = migrator.validate_migration("~/.lynguine/config/machine.yml")
if validation['valid']:
print("✓ Migration successful")
else:
print("✗ Issues found:", validation['issues'])
Manual Migration Steps
Backup Configuration
cp ~/.lynguine/config/machine.yml ~/.lynguine/config/machine.yml.backup
Set Master Key
export LYNGUINE_MASTER_KEY="your-secure-master-password"
Store Credentials
from lynguine.security import set_credential set_credential("google_sheets_oauth", { "client_id": "your-client-id", "client_secret": "your-client-secret" })
Update Configuration
Replace:
google_oauth: client_id: your-client-id client_secret: your-client-secret
With:
google_oauth: ${credential:google_sheets_oauth}
Test
from lynguine import Interface interface = Interface.from_file("_lynguine.yml") # Should work without errors
Rollback
If migration fails, restore from backup:
migrator.rollback("/path/to/backup/machine.yml.backup_20231215_143022")
Advanced Configuration
Multiple Providers with Priority
from lynguine.security import (
CredentialManager,
EnvironmentCredentialProvider,
EncryptedFileCredentialProvider
)
# Environment variables take priority (e.g., for dev overrides)
env_provider = EnvironmentCredentialProvider(prefix="LYNGUINE_CRED")
# Encrypted files for production credentials
file_provider = EncryptedFileCredentialProvider(
storage_path="~/.lynguine/credentials",
master_key=os.environ["LYNGUINE_MASTER_KEY"]
)
# Create manager with priority order
manager = CredentialManager(
providers=[env_provider, file_provider], # env checked first
cache_ttl=300, # 5 minute cache
enable_cache=True
)
Custom Validators
from lynguine.security import get_credential_manager
manager = get_credential_manager()
# Register custom validator
def validate_google_oauth(credential):
"""Ensure Google OAuth has required fields."""
if "value" not in credential:
return False
value = credential["value"]
required = ["client_id", "client_secret", "redirect_uri"]
return all(field in value for field in required)
manager.register_validator("google_oauth", validate_google_oauth)
# Credentials are now validated on retrieval
creds = manager.get_credential("google_auth", credential_type="google_oauth")
Rate Limiting
from lynguine.security import RateLimiter
# Limit to 100 requests per minute per user
limiter = RateLimiter(max_requests=100, time_window=60)
if not limiter.check_rate_limit("google_sheets_oauth", user="current_user"):
raise Exception("Rate limit exceeded")
Security Best Practices
1. Master Key Management
DO:
Generate strong master keys (20+ characters, mixed case, numbers, symbols)
Store master key in secure key management system
Use different master keys for dev/staging/production
Rotate master key periodically
DON’T:
Hard-code master key in source code
Commit master key to version control
Share master key via email or chat
Use weak or predictable master keys
2. Credential Storage
DO:
Use encrypted file storage for production
Set restrictive file permissions (0600)
Store credentials outside of application directory
Back up encrypted credential files securely
DON’T:
Store credentials in plain text
Use world-readable permissions
Store credentials in application repository
Forget to backup credentials
3. Access Control
DO:
Implement principle of least privilege
Use specific credential patterns
Monitor audit logs regularly
Set up rate limiting
DON’T:
Grant blanket admin access
Ignore access denied events
Disable audit logging
Allow unlimited credential access
4. Credential Lifecycle
DO:
Rotate credentials regularly (90 days or less)
Revoke credentials immediately on compromise
Track credential usage via audit logs
Test credential rotation procedures
DON’T:
Use the same credentials indefinitely
Leave old credentials active after rotation
Forget to update credential references
Skip testing after rotation
Troubleshooting
Common Issues
“Credential not found” Error
# Check available credentials
from lynguine.security import get_credential_manager
manager = get_credential_manager()
print("Available credentials:", manager.list_credentials())
“Access denied” Error
# Check access policy
from lynguine.security import get_access_controller
controller = get_access_controller()
# Review and update policies as needed
“Cryptography library not available”
pip install cryptography
Wrong Master Key
If you get decryption errors:
Verify master key is correct
Check
LYNGUINE_MASTER_KEYenvironment variableEnsure same master key was used for encryption
Migration Validation Failures
# Get detailed validation report
validation = migrator.validate_migration("config.yml")
print("Issues:", validation['issues'])
# Check each credential reference
for ref in validation['credential_references']:
try:
cred = manager.get_credential(ref)
print(f"✓ {ref}: OK")
except Exception as e:
print(f"✗ {ref}: {e}")
API Reference
Core Functions
get_credential(key, credential_type=None, default=None): Retrieve a credentialset_credential(key, value, credential_type=None): Store a credentialget_credential_manager(): Get global credential managerget_access_controller(): Get global access controller
Classes
CredentialManager: Central credential managementEnvironmentCredentialProvider: Environment variable backendEncryptedFileCredentialProvider: Encrypted file backendCredentialAccessController: Access control and auditingAuditLogger: Security event loggingCredentialMigrator: Migration utilities
See module documentation for detailed API reference.
Examples
Example 1: Simple Google Sheets Integration
from lynguine.security import set_credential
from lynguine import Interface
# One-time setup: Store credentials
google_creds = {
"client_id": "123456789.apps.googleusercontent.com",
"client_secret": "your-client-secret",
"redirect_uri": "http://localhost:8080"
}
set_credential("google_sheets_oauth", google_creds)
# Update _lynguine.yml:
# google_oauth: ${credential:google_sheets_oauth}
# Use normally
interface = Interface.from_file("_lynguine.yml")
data, _ = interface.read_inputs()
Example 2: Multi-Environment Setup
import os
from lynguine.security import (
CredentialManager,
EnvironmentCredentialProvider,
EncryptedFileCredentialProvider
)
# Detect environment
env = os.environ.get("LYNGUINE_ENV", "development")
if env == "production":
# Production: Use encrypted files only
provider = EncryptedFileCredentialProvider(
storage_path="/var/lynguine/credentials",
master_key=os.environ["LYNGUINE_MASTER_KEY"]
)
else:
# Development: Use environment variables
provider = EnvironmentCredentialProvider()
manager = CredentialManager(providers=[provider])
Example 3: Credential Rotation
from lynguine.security import get_credential_manager
manager = get_credential_manager()
# Store new credentials
new_creds = {
"client_id": "new-client-id",
"client_secret": "new-client-secret"
}
# Update with new credentials
manager.set_credential("google_sheets_oauth", new_creds)
# Invalidate cache to force refresh
if manager.cache:
manager.cache.invalidate("google_sheets_oauth")
print("Credentials rotated successfully")
Support and Resources
License
This security module is part of Lynguine and is licensed under the same license as the main project.