Zero-Trust IoT Identity & Authentication System
ESP32-C3 + ATECC608A + MySQL RDBMS + FastAPI + Vanilla JS Dashboard
Each IoT device holds an ATECC608A crypto chip. The private key never leaves the chip. Authentication is done by:
- Device requests a one-time nonce from the server
- ATECC chip signs the nonce using its private key
- Server verifies the ECDSA signature using the stored public key
- On success: Short-lived JWT issued, auth event logged
This is hardware-backed zero-trust authentication — no passwords, no shared secrets.
ROT_PROJECT/
├── database/ ← MySQL RDBMS schema + seed data
├── backend/ ← FastAPI server (raw pymysql, NO ORM)
├── frontend/ ← Dashboard (Vanilla HTML/CSS/JS)
├── firmware/ ← ESP32-C3 Arduino firmware
├── simulator/ ← Python device simulator (no hardware needed)
└── docs/ ← DBMS documentation (normalization, ER, Advanced Features)
- MySQL 8.0+
- Python 3.11+
python setup_db.pycd backend
pip install -r requirements.txtEdit .env if needed:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=rot_platform
DB_USER=root
DB_PASSWORD=your_password
JWT_SECRET=change_this_in_productioncd backend
uvicorn main:app --reload --port 8000- API: http://localhost:8000/api/v1
- Swagger Docs: http://localhost:8000/docs
- Dashboard: http://localhost:8000/
cd simulator
pip install cryptography requestsNormal auth (all 3 virtual chips):
python device_simulator.pyAttack simulations:
python device_simulator.py --attack replay # Replay attack
python device_simulator.py --attack fake # Fake device
python device_simulator.py --attack brute # Brute forceContinuous loop (like real firmware):
python device_simulator.py --loop| Feature | Where Used |
|---|---|
| Custom ENUM types | device_status, policy_action, auth_result |
| JSON | metadata, factors, conditions |
| VARCHAR(45) | IP addresses in auth_logs |
| CHAR(36) | All primary keys |
| Stored Functions | Trust scoring, suspicious flagging, nonce cleanup |
| Triggers | Auto-update trust scores on auth events |
| Database Views | Dashboard stats, alerts, recent logs |
| Indexes | JSON column queries |
| Unique Index | One active key per device |
| Table | Purpose |
|---|---|
devices |
IoT device registry |
device_keys |
EC P-256 public keys (rotation-safe) |
auth_challenges |
Single-use nonces with TTL |
auth_logs |
Immutable audit trail |
trust_scores |
Computed trust score per device |
policy_rules |
Dynamic access control rules |
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/devices/register |
Register new device |
| GET | /api/v1/devices |
List all devices |
| PATCH | /api/v1/devices/{id}/status |
Activate / revoke device |
| GET | /api/v1/auth/challenge/{hw_id} |
Issue nonce challenge |
| POST | /api/v1/auth/verify |
Verify signature → JWT |
| GET | /api/v1/logs |
Auth log (filterable) |
| GET | /api/v1/logs/alerts |
Security alert feed |
| GET | /api/v1/analytics/summary |
Dashboard stats |
| GET | /api/v1/analytics/trust/{id} |
Trust score |
| GET | /api/v1/policy/rules |
List policy rules |
| POST | /api/v1/policy/rules |
Create rule |
- Never trust the device ID — anyone can claim any ID
- Trust only the signature — only the real chip can sign
- Never trust the nonce twice — single-use + 5-min expiry (anti-replay)
- Every request logged — full audit trail
-- Atomically consume nonce — if already used, no rows updated
UPDATE auth_challenges
SET used = TRUE
WHERE nonce = %s AND device_id = %s AND used = FALSE AND expires_at > NOW();Rules evaluated in priority order from the policy_rules table.
No hard-coded access logic — all driven by DB records.
| File | Contents |
|---|---|
docs/normalization.md |
0NF → 1NF → 2NF → 3NF → BCNF with FD proofs |
docs/mysql_features.md |
Detailed overview of advanced MySQL features used |
docs/er_diagram.md |
Mermaid ER diagram + cardinality analysis |
ESP32-C3 ATECC608A
GPIO 4 (SDA) → SDA
GPIO 5 (SCL) → SCL
3.3V → VCC
GND → GND
Three chips at addresses: 0x60, 0x61, 0x62
Open firmware/main/main.ino in Arduino IDE.
- Install:
ArduinoJson,SparkFun ATECC608Alibraries - Set
WIFI_SSID,WIFI_PASSWORD,SERVER_BASEinmain.ino