Skip to content

OpenLatch

Electronic door lock system for a hackerspace. NFC-based entry with a NUKI Smart Lock Ultra, controlled by an ESP32 that operates offline with cryptographically signed allow-lists.

Architecture

┌───────────────┐    HTTPS (poll)    ┌───────────────────┐
│   ESP32       │ ◄────────────────► │  Backend Server   │
│  Controller   │  signed allow-list │  (Python/FastAPI) │
│               │                    │  + PostgreSQL     │
│ ┌───────────┐ │                    │                   │
│ │ Wiegand   │◄── CONLAN M1200      │  ┌─────────────┐  │
│ │ Decoder   │ │  NFC Terminal      │  │  Admin UI   │  │
│ └───────────┘ │  (DESFire auth)    │  └─────────────┘  │
│ ┌───────────┐ │                    └───────────────────┘
│ │ NUKI BLE  │──► NUKI Smart Lock
│ │ Control   │ │  Ultra
│ └───────────┘ │
└───────────────┘

Components

  • Backend (backend/): Python FastAPI server managing members, NFC keys, access rules, and generating signed allow-lists
  • Firmware (firmware/): ESP32 C++ firmware (PlatformIO) that reads NFC cards via Wiegand, checks the local allow-list, and controls the NUKI lock via BLE
  • Protocol (proto/): Binary allow-list protocol specification with Ed25519 signing

Hardware

  • NUKI Smart Lock Ultra
  • ESP32 DevKit
  • CONLAN M1200 NFC Terminal (MIFARE DESFire, Wiegand output, IP67)

Development

Prerequisites

  • Python 3.12+
  • PlatformIO CLI
  • Docker (for PostgreSQL)
  • PostgreSQL 16

Backend Setup

cd backend
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Start PostgreSQL
cd ../tools && docker compose up -d

# Run tests
cd ../backend && pytest -v

Firmware Setup

cd firmware

# Run native (host) tests — no hardware required
pio test -e native

# Build for ESP32 (requires ESP32 toolchain)
pio run -e esp32dev

# Flash to connected device
pio run -e esp32dev --target upload

Site-specific configuration

Hardware varies between installations (Ethernet vs. WiFi, door hardware, etc.). Create a firmware/local.ini from the provided example and uncomment the scenario that matches your setup — this file is git-ignored so it stays local to your install:

cp firmware/local.ini.example firmware/local.ini
# edit firmware/local.ini — uncomment one of the example sections

See firmware/local.ini.example for all available scenarios (prod Ethernet, WiFi fallback, PN532 dev reader, door hardware) and a full reference of every build flag. See firmware/platformio.ini for the base environments that local.ini extends.

Generate Ed25519 Keypair

python tools/keygen.py --write

Security

  • Allow-list updates are signed with Ed25519
  • Replay protection via monotonic versions and validity windows
  • MIFARE DESFire EV2/EV3 challenge-response authentication (handled by NFC terminal)
  • NVS encryption for credentials on ESP32
  • Argon2id password hashing for admin accounts
  • JWT with short-lived tokens for admin API

License

License: AGPL v3

OpenLatch is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). Community spaces, hackerspaces, and individuals may use, deploy, and modify it freely. If you distribute modified code or run it as a network service, you must make your source available under the same license.

A commercial license is available for organisations that need to keep modifications proprietary or require a warranty/SLA. See COMMERCIAL_LICENSE.md for details.

External contributors must agree to the Contributor License Agreement before their pull requests can be merged.