# Security — IoT SmartBin

## Overview

The security model is layered:
1. **Transport:** MQTT over TLS (port 8883)
2. **Authentication:** Username/password per device
3. **Authorization:** ACL restricting topic access per device
4. **Backend:** TLS + credentials to broker

---

## 1. TLS Configuration

### Generate Self-Signed Certificates (Development)

```bash
# Create CA key and certificate
openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
  -subj "/CN=SmartBin CA"

# Create server key and CSR
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/CN=mqtt.smartbin.local"

# Sign server certificate with CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 3650

# Copy to infra/mosquitto/certs/
cp ca.crt server.crt server.key ../infra/mosquitto/certs/
```

### File Placement
```
infra/mosquitto/certs/
  ca.crt        # CA certificate (also embedded in firmware)
  server.crt    # Server certificate
  server.key    # Server private key (keep secret!)
```

---

## 2. Mosquitto Configuration

### mosquitto.conf
```conf
# Listener — plain (dev only, disable in production)
listener 1883
protocol mqtt

# Listener — TLS (production)
listener 8883
protocol mqtt
cafile /mosquitto/certs/ca.crt
certfile /mosquitto/certs/server.crt
keyfile /mosquitto/certs/server.key
tls_version tlsv1.2

# Authentication
allow_anonymous false
password_file /mosquitto/config/password_file

# Authorization
acl_file /mosquitto/config/acl_file

# Performance tuning (10k devices)
max_connections -1
max_inflight_messages 20
max_queued_messages 1000
message_size_limit 8192
```

### password_file
Generate with mosquitto_passwd:
```bash
# Create new password file
mosquitto_passwd -c /mosquitto/config/password_file bin-001
# Add more devices
mosquitto_passwd -b /mosquitto/config/password_file bin-002 SecurePass002
mosquitto_passwd -b /mosquitto/config/password_file backend-ingestion BackendSecret123
mosquitto_passwd -b /mosquitto/config/password_file backend-api BackendApiSecret456
```

Example entries (hashed):
```
bin-001:$7$101$...hashedpassword...
bin-002:$7$101$...hashedpassword...
backend-ingestion:$7$101$...hashedpassword...
backend-api:$7$101$...hashedpassword...
```

### acl_file
```
# ============================================
# Device ACLs — each device has isolated topics
# ============================================

# Pattern: %u = username (= deviceId)
# Device can publish its own telemetry, status, availability
user bin-001
topic write smartbin/+/+/+/bin-001/telemetry
topic write smartbin/+/+/+/bin-001/status
topic write smartbin/+/+/+/bin-001/availability

# Device can subscribe to its own command topic
user bin-001
topic read smartbin/+/+/+/bin-001/cmd

# ============================================
# Using pattern-based ACL (recommended for scale)
# ============================================
pattern write smartbin/+/+/+/%u/telemetry
pattern write smartbin/+/+/+/%u/status
pattern write smartbin/+/+/+/%u/availability
pattern read  smartbin/+/+/+/%u/cmd

# ============================================
# Backend services — full access
# ============================================
user backend-ingestion
topic read smartbin/#

user backend-api
topic readwrite smartbin/#
```

> **Note:** Pattern-based ACL uses `%u` (username) as wildcard, mapping device username to its deviceId. This scales to 10,000+ devices without individual entries.

---

## 3. Firmware TLS Support

### Config Flag
```cpp
#define MQTT_USE_TLS true   // Toggle TLS on/off
```

### Embedded CA Certificate (PROGMEM)
```cpp
const char ca_cert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUY...
...paste your ca.crt content here...
-----END CERTIFICATE-----
)EOF";
```

### Connection Code
```cpp
#if MQTT_USE_TLS
  WiFiClientSecure espClient;
  espClient.setCACert(ca_cert);
#else
  WiFiClient espClient;
#endif
PubSubClient mqtt(espClient);
```

---

## 4. Backend TLS Connection

### Node.js MQTT Client
```javascript
const mqtt = require('mqtt');
const fs = require('fs');

const options = {
  host: process.env.MQTT_HOST,
  port: parseInt(process.env.MQTT_PORT) || 8883,
  protocol: 'mqtts',
  username: process.env.MQTT_USER,
  password: process.env.MQTT_PASS,
  ca: [fs.readFileSync('./certs/ca.crt')],
  rejectUnauthorized: true
};

const client = mqtt.connect(options);
```

---

## 5. Production Recommendations

### Certificate Management
- Use **Let's Encrypt** or organizational CA for production certificates
- Rotate certificates annually minimum
- Store private keys in secret management (Vault, AWS Secrets Manager)

### Authentication Upgrade Path
1. **Phase 1 (current):** Username/password per device via Mosquitto password_file
2. **Phase 2:** JWT token-based auth via EMQX auth plugin
3. **Phase 3:** X.509 client certificates per device (mutual TLS)

### Network Security
- Firewall: only expose port 8883 (TLS), block 1883 in production
- Use VPN or private network between backend and broker
- Rate limiting per client on broker

### Monitoring
- Monitor failed auth attempts (broker logs)
- Alert on LWT offline events exceeding threshold
- Track certificate expiration dates

### EMQX/HiveMQ Migration
When migrating from Mosquitto to EMQX/HiveMQ:
- ACL can be managed via database (MySQL/PostgreSQL) or REST API
- Built-in JWT authentication support
- Dashboard for real-time monitoring
- Rule engine for server-side processing
