Implements dual authentication system: OAuth2 (default) + mTLS (opt-in).
Zero-risk implementation - existing OAuth2 workflows unchanged.
NEW FEATURE: mTLS Certificate Authentication
- PFX/P12 certificate support for enhanced security
- Activated ONLY with --auth-pfx command-line flag
- OAuth2 remains default (no flag = OAuth2 as before)
- Perfect for testing new auth without breaking production
USAGE:
Default (OAuth2):
python scripts/a1_to_a2_download.py
With mTLS:
python scripts/a1_to_a2_download.py --auth-pfx
IMPLEMENTATION:
1. Certificate Storage (SECURE):
- NEW: config/certificates/ folder (gitignored)
- Moved PFX file to secure location
- File permissions: 600 (owner read/write only)
- Password stored in .env (already gitignored)
2. Configuration:
- .env: Added DAM_MTLS_CERT_PATH and DAM_MTLS_CERT_PASSWORD
- config.yaml: Added mtls_cert_path and mtls_cert_password
- .gitignore: Added config/certificates/, *.pfx, *.p12
3. DAM Client Dual Auth:
- NEW: pfx_to_pem() - Converts PFX to temporary PEM for requests
- UPDATED: __init__() - Accepts use_mtls flag
- NEW: _make_api_request() - Unified request wrapper
- Auto-selects auth method based on flag
- Updated ALL 8 API calls to use wrapper
4. Scripts Updated (argparse):
- test_connection.py - Added --auth-pfx flag
- a1_to_a2_download.py - Added --auth-pfx flag
- a5_to_a6_download.py - Added --auth-pfx flag
- b1_to_b2_download.py - Added --auth-pfx flag
5. Test Script:
- NEW: test_mtls_cert.py - Standalone cert loading test
- Tests PFX→PEM conversion without API calls
- Verifies certificate format and cleanup
TESTING RESULTS:
✓ Certificate loads successfully (10930 bytes)
✓ PFX→PEM conversion works (13520 bytes)
✓ Temp file cleanup working
✓ OAuth2 connection test: PASS
✓ mTLS connection test: PASS
✓ Both auth methods working independently
SECURITY:
✓ Certificate file gitignored
✓ Password in .env (gitignored)
✓ File permissions: 600
✓ Temp PEM files auto-deleted
✓ No secrets in code or config
MIGRATION PATH:
- Dev: Use dam-mtls-dev.pfx (current)
- Prod: Replace cert file, update password, same code
BACKWARD COMPATIBILITY:
✓ OAuth2 still default (100% backward compatible)
✓ Existing cron jobs unchanged
✓ No breaking changes
✓ Easy rollback (just don't use --auth-pfx)
Changes:
- .gitignore (+3 lines)
- Python-Version/.env (+3 lines)
- Python-Version/config/config.yaml (+3 lines)
- Python-Version/scripts/shared/dam_client.py (+100 lines dual auth)
- Python-Version/scripts/a1_to_a2_download.py (+14 lines argparse)
- Python-Version/scripts/a5_to_a6_download.py (+14 lines argparse)
- Python-Version/scripts/b1_to_b2_download.py (+14 lines argparse)
- Python-Version/scripts/test_connection.py (+15 lines argparse)
- NEW: Python-Version/scripts/test_mtls_cert.py (92 lines)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
111 lines
2.9 KiB
YAML
111 lines
2.9 KiB
YAML
# Ferrero Content Scaling - Main Configuration
|
|
# All settings can be overridden by environment-specific configs
|
|
|
|
# Environment selector (set via ENV environment variable)
|
|
environment: ${ENV:-staging}
|
|
|
|
# DAM Configuration
|
|
dam:
|
|
base_url: ${DAM_BASE_URL}
|
|
# OAuth2 Authentication (default - current working method)
|
|
auth_url: ${DAM_AUTH_URL}
|
|
client_id: ${DAM_CLIENT_ID}
|
|
client_secret: ${DAM_CLIENT_SECRET}
|
|
# mTLS Certificate Authentication (optional - use with --auth-pfx flag)
|
|
mtls_cert_path: ${DAM_MTLS_CERT_PATH:-}
|
|
mtls_cert_password: ${DAM_MTLS_CERT_PASSWORD:-}
|
|
timeout_seconds: 120
|
|
|
|
# Box Configuration
|
|
box:
|
|
enterprise_id: ${BOX_ENTERPRISE_ID}
|
|
client_id: ${BOX_CLIENT_ID}
|
|
client_secret: ${BOX_CLIENT_SECRET}
|
|
jwt_key_id: ${BOX_JWT_KEY_ID}
|
|
rsa_private_key_path: ../Box-config.json
|
|
passphrase: ${BOX_PASSPHRASE}
|
|
# Separate folders for different workflows
|
|
root_folder_a1_a2: ${BOX_ROOT_FOLDER_A1_A2} # For downloaded Local master assets (348304357505)
|
|
root_folder_a2_a3: ${BOX_ROOT_FOLDER_A2_A3} # For agency uploads to process (348526703108)
|
|
root_folder_b1_b2: ${BOX_ROOT_FOLDER_B1_B2} # For downloaded Global master assets (349261192115)
|
|
webhook_signature_keys:
|
|
- ${BOX_WEBHOOK_PRIMARY_KEY:-}
|
|
- ${BOX_WEBHOOK_SECONDARY_KEY:-}
|
|
|
|
# Database Configuration
|
|
database:
|
|
host: ${DB_HOST:-localhost}
|
|
port: ${DB_PORT:-5433}
|
|
database: ferrero_tracking
|
|
user: ${DB_USER}
|
|
password: ${DB_PASSWORD}
|
|
|
|
# Polling Configuration (A1→A2)
|
|
polling:
|
|
enabled: true
|
|
interval_seconds: 300 # 5 minutes
|
|
max_campaigns_per_run: 10
|
|
|
|
# Webhook Configuration (A2→A3 receiver)
|
|
webhook_receiver:
|
|
enabled: true
|
|
host: 0.0.0.0
|
|
port: ${WEBHOOK_RECEIVER_PORT:-5555}
|
|
validate_signatures: true
|
|
|
|
# Outgoing Webhooks (we call these)
|
|
webhooks:
|
|
campaign_status_update:
|
|
enabled: true
|
|
url: ${CAMPAIGN_STATUS_WEBHOOK_URL}
|
|
timeout_seconds: 10
|
|
retry_on_failure: true
|
|
max_retries: 3
|
|
auth:
|
|
type: none # bearer, basic, or none
|
|
token: ${WEBHOOK_AUTH_TOKEN:-}
|
|
|
|
# Retry Configuration
|
|
retry:
|
|
max_attempts: 3
|
|
backoff: exponential # exponential, linear, fixed
|
|
initial_delay_seconds: 5
|
|
max_delay_seconds: 60
|
|
|
|
# Notification Configuration
|
|
notifications:
|
|
enabled: true
|
|
smtp:
|
|
server: ${SMTP_SERVER}
|
|
port: ${SMTP_PORT}
|
|
user: ${SMTP_USER}
|
|
password: ${SMTP_PASSWORD}
|
|
sender_email: ${SENDER_EMAIL}
|
|
recipients:
|
|
success:
|
|
- ${REPORT_EMAILS}
|
|
errors:
|
|
- ${ERROR_EMAIL}
|
|
critical:
|
|
- ${ERROR_EMAIL}
|
|
templates_path: config/email_templates.yaml
|
|
|
|
# Field Configuration
|
|
fields:
|
|
mappings_file: config/field_mappings.yaml
|
|
|
|
# Logging Configuration
|
|
logging:
|
|
level: INFO
|
|
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
file:
|
|
directory: logs
|
|
max_bytes: 10485760 # 10MB
|
|
backup_count: 5
|
|
console: true
|
|
|
|
# Temp File Configuration
|
|
temp:
|
|
directory: temp/downloads
|
|
cleanup_after_hours: 24
|
|
max_size_mb: 1000
|