Lagomare Gates
A web-based gate access management and control system. Authorized users can remotely open physical car and pedestrian gates via a mobile-friendly PWA. An admin dashboard provides full management of gates, access codes, and users.
Features
- Keypass authentication — users authenticate with an access code; each keypass can have a per-gate allowlist and an optional expiration date
- Remote gate control — integrates with AVConnect to trigger gate macros
- Role-based admin panel — two roles (
admin,manager) with different permission levels - Access audit log — every open attempt is logged with timestamp, keypass, gate, IP, and result
- Progressive Web App — installable on mobile devices with offline caching
Tech Stack
| Layer | Technology |
|---|---|
| Backend | FastAPI + Uvicorn |
| ORM | SQLAlchemy |
| Database | SQLite |
| Auth | JWT (HS256) + bcrypt |
| Credential storage | Fernet symmetric encryption |
| Gate integration | AVConnect HTTP API |
| Frontend | Vanilla JS PWA |
Project Structure
src/
├── main.py # App entry point, startup, static file serving
├── core/
│ ├── auth.py # JWT creation/verification, password hashing
│ ├── config.py # Settings loaded from environment variables
│ ├── database.py # SQLAlchemy models and DB initialization
│ ├── dependencies.py # FastAPI dependency injection (auth guards)
│ └── schemas.py # Pydantic request/response schemas
├── models/ # Thin wrappers re-exporting DB models
├── routers/
│ ├── auth.py # POST /api/auth/admin, POST /api/auth/keypass
│ ├── gates.py # User-facing gate list and open endpoints
│ ├── keypasses.py # Admin keypass CRUD
│ ├── admins.py # Admin user management
│ ├── credentials.py # AVConnect credential management
│ └── stats.py # Access log / statistics
├── services/
│ ├── avconnect.py # AVConnect session management and macro execution
│ └── gates.py # Gate open orchestration
└── static/ # Frontend PWA (index.html, admin.html, JS, CSS)
data/
└── gates.db # SQLite database (auto-created on first run)
API Endpoints
Authentication
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/admin |
Admin login — returns JWT |
| POST | /api/auth/keypass |
Keypass login — returns JWT |
User (keypass token required)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/gates |
List gates accessible to the authenticated keypass |
| POST | /api/gates/{gate_id}/open |
Open a gate |
Admin — Gates (manager+)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/gates |
List all gates |
| POST | /api/admin/gates |
Create a gate (admin only) |
| PUT | /api/admin/gates/{gate_id} |
Update a gate (admin only) |
| DELETE | /api/admin/gates/{gate_id} |
Delete a gate (admin only) |
| POST | /api/admin/gates/{gate_id}/open |
Manually open a gate |
Admin — Keypasses (manager+)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/keypasses |
List all keypasses |
| POST | /api/admin/keypasses |
Create a keypass |
| PATCH | /api/admin/keypasses/{kp_id} |
Update a keypass |
| DELETE | /api/admin/keypasses/{kp_id} |
Revoke a keypass |
Admin — Users (admin only)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/admins |
List admin users |
| POST | /api/admin/admins |
Create an admin user |
| DELETE | /api/admin/admins/{username} |
Delete an admin user |
| PATCH | /api/admin/admins/{username}/password |
Change password |
Admin — AVConnect Credentials (admin only)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/credentials |
View stored credentials |
| PUT | /api/admin/credentials |
Create or update credentials |
Admin — Statistics (manager+)
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/stats |
Retrieve the last 500 access log entries |
Configuration
All settings are read from environment variables.
| Variable | Default | Description |
|---|---|---|
SECRET_KEY |
Random 32 bytes | JWT signing key and Fernet encryption key. Set this explicitly in production. |
ADMIN_USERNAME |
admin |
Username for the initial admin account |
ADMIN_PASSWORD |
(none) | Password for the initial admin account. If unset, no seed account is created. |
APP_PORT |
8000 |
HTTP port the server listens on |
DATABASE_URL |
sqlite:///data/gates.db |
SQLAlchemy database URL |
MOCK_AVCONNECT |
false |
Set to true to skip real AVConnect calls (always returns success — useful for development) |
Running with Docker Compose
# Copy and edit the compose file to set your SECRET_KEY
docker compose up -d
The default docker-compose.yml starts the service on port 8000 with the initial admin credentials admin / changeme. Change ADMIN_PASSWORD and set a strong SECRET_KEY before deploying.
The ./data directory is mounted into the container so the SQLite database persists across restarts.
Running Locally
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
export SECRET_KEY="change-me"
export ADMIN_USERNAME="admin"
export ADMIN_PASSWORD="changeme"
uvicorn src.main:app --reload --port 8000
The application is then available at:
- User interface —
http://localhost:8000/ - Admin dashboard —
http://localhost:8000/admin
AVConnect Integration
Gates are controlled through the AVConnect platform. Each gate is mapped to an AVConnect macro ID. When a gate open request is received, the service:
- Authenticates with AVConnect using the stored credentials (session is cached in the database)
- Executes the configured macro for the gate
Credentials (password) are stored encrypted in the database using Fernet symmetric encryption derived from SECRET_KEY.
Roles
| Role | Permissions |
|---|---|
admin |
Full access — all endpoints including gate/user/credential management |
manager |
Gate open, keypass management, statistics — cannot manage admin users, AVConnect credentials, or create/delete gates |