2026-01-25 18:01:48 +01:00

248 lines
6.4 KiB
Markdown

# Security Model & Best Practices
## Credential Management
### CRITICAL: Never Store Plaintext Passwords
All SSH credentials must be handled securely:
#### Option 1: Runtime Credentials (Recommended)
User provides SSH credentials at push time:
```typescript
// Frontend
const response = await fetch('/api/v1/configurations/123/push', {
method: 'POST',
body: JSON.stringify({
configuration_id: 123,
device_id: 456,
ssh_username: 'admin',
ssh_password: 'SecurePass123', // ONLY sent at push time
confirmed: true,
dry_run: false
})
})
```
Backend receives credentials in request, uses immediately, discards after execution.
#### Option 2: Encrypted Storage (Advanced)
If storing credentials (not recommended without vault):
```python
# Backend
from app.core.security import encrypt_credential, decrypt_credential
# Encrypt before storing
encrypted = encrypt_credential("plaintext_password")
device.ssh_password_encrypted = encrypted
# Decrypt only when pushing
plaintext = decrypt_credential(device.ssh_password_encrypted)
executor = SSHExecutor(..., password=plaintext)
# Use immediately
plaintext = None # Clear from memory
```
⚠️ **Never** use hardcoded encryption keys. Use:
- AWS KMS
- HashiCorp Vault
- Azure Key Vault
- Environment variables (CI/CD only)
## Access Control
### User Isolation
- Each user owns their projects
- Projects contain devices & configs
- API enforces `project.owner_id == current_user.id`
```python
# Backend example
def get_project(project_id: int, current_user: User):
project = db.query(Project).filter(Project.id == project_id).first()
if project.owner_id != current_user.id:
raise HTTPException(status_code=403, detail="Forbidden")
return project
```
### Token-Based Authentication
- JWT tokens expire after 30 minutes
- Refresh token pattern (future: V1)
- Token contains only user email (no sensitive data)
```python
# core/security.py
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=30)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(
to_encode,
settings.secret_key,
algorithm=settings.algorithm
)
return encoded_jwt
```
## SSH Security
### Pre-Push Validation
1. ✅ Dry-run mode (generate only, no execution)
2. ✅ CLI preview (user sees exact commands)
3. ✅ Confirmation modal (explicit yes/no)
4. ✅ Backup running-config before push
### Connection Security
- SSH only (no Telnet)
- Device authentication via username/password or SSH keys (future)
- 30-second timeout (prevent hanging)
- Error handling without exposing internals
```python
# ssh/__init__.py
def connect(self):
try:
device = {
"device_type": "cisco_ios",
"host": self.ip_address,
"username": self.username,
"password": self.password,
"port": self.ssh_port,
"timeout": self.timeout, # 30s timeout
}
self.connection = ConnectHandler(**device)
except NetmikoAuthenticationException as e:
raise SSHConnectionError(f"Auth failed") # No password leak
except NetmikoTimeoutException as e:
raise SSHConnectionError(f"Timeout") # Generic error
```
### Audit Logging
All SSH operations logged to `push_logs` table:
```sql
-- What was pushed
- device_id
- configuration_id
- commands_sent (plain text)
- device_output (verbatim)
-- When & by whom
- created_at
- pushed_by (username)
-- Safety
- pre_push_backup (running-config before)
- was_rolled_back (if reverted)
- rollback_reason
```
Example query to review push history:
```sql
SELECT id, device_id, created_at, pushed_by, status
FROM push_logs
WHERE device_id = 456
ORDER BY created_at DESC
LIMIT 10;
```
## Network Security
### HTTPS in Production
```python
# main.py production config
if not settings.debug:
# Redirect HTTP to HTTPS
app.add_middleware(HTTPSRedirectMiddleware)
# Add HSTS header
app.add_middleware(HSTSMiddleware, max_age=31536000)
```
### CORS Configuration
```python
# main.py
app.add_middleware(
CORSMiddleware,
allow_origins=["https://your-domain.com"], # NOT *
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Authorization", "Content-Type"],
)
```
### API Rate Limiting (TODO: V1)
```python
# Prevent brute force / DoS
# 100 requests per minute per IP
# 1000 requests per hour per user
```
## Database Security
### SQL Injection Prevention
Use SQLAlchemy ORM (parameterized queries):
```python
# ✅ Safe - parameterized
user = db.query(User).filter(User.email == user_email).first()
# ❌ NEVER - raw SQL with string formatting
user = db.execute(f"SELECT * FROM users WHERE email = '{user_email}'")
```
### Sensitive Data
- Passwords: BCrypt hashed (never plaintext)
- SSH credentials: Encrypted or runtime-only
- API keys: Environment variables (never in code)
## Disclaimer & User Awareness
### In UI
```html
<!-- Frontend -->
<div class="security-disclaimer">
<p>⚠️ <strong>WARNING</strong></p>
<p>This tool executes commands on live network devices.</p>
<p>Review all configurations before pushing.</p>
<p>Test in lab environment first.</p>
<p>Backup devices before any changes.</p>
<p>All operations are logged for audit.</p>
</div>
```
### In API
```python
# main.py
@app.get("/api/v1/docs")
def docs():
"""
Include security warning in OpenAPI docs
"""
return {
"warning": "This API modifies network device configurations via SSH. Use with caution.",
"docs": "...",
}
```
## Deployment Checklist
- [ ] **Secrets**: Use environment variables (AWS Secrets Manager, etc.)
- [ ] **SSL/TLS**: Enforce HTTPS only
- [ ] **CORS**: Lock down to your domain
- [ ] **Database**: PostgreSQL with strong credentials, encrypted connection
- [ ] **SSH Keys**: Support SSH key auth (not just passwords)
- [ ] **Logging**: Centralized logging (ELK, Datadog, etc.)
- [ ] **Monitoring**: Alert on failed pushes, timeout errors
- [ ] **Backup**: Database backups daily
- [ ] **Compliance**: Log retention policy (min 90 days)
- [ ] **Testing**: Penetration test before launch
## Future: V1 Features
- [ ] SSH key authentication (instead of passwords)
- [ ] OAuth 2.0 / SSO integration
- [ ] Role-based access control (RBAC)
- [ ] Encryption at rest (database)
- [ ] Multi-factor authentication (MFA)
- [ ] Webhook integration for audit events
- [ ] Compliance reporting (PCI-DSS, SOC2)