PlainPunch is a small self-hosted time clock without surveillance. Employees make explicit clock-in, clock-out, and break punches; they can review their own history and request corrections. Administrators review those requests, export CSV records, and retain an immutable audit trail of every material action.
It deliberately does not track location, screenshots, keystrokes, browser activity, applications, or productivity scores.
- Employee web sign-in and a privacy-preserving shared kiosk
- Explicit shift and break punches
- Personal history with calculated worked time
- Correction requests with approve/reject review
- Before-and-after evidence for approved corrections
- Administrator-created users and CSV export
- UTC storage with configurable local-time display
- SQLite, Docker Compose, health check, and documented backup path
cp .env.example .env
# Replace PLAINPUNCH_SECRET_KEY and set your timezone in .env.
docker compose up -d --build
docker compose exec app plainpunch --database /data/plainpunch.sqlite3 create-admin \
--name "Administrator" --email admin@example.org --employee-code ADMINOpen http://localhost:8080. Put TLS and rate limiting in front of the service before exposing it outside a trusted network.
python -m venv .venv
python -m pip install -e ".[dev]"
plainpunch init-db
plainpunch create-admin --name "Administrator" --email admin@example.org --employee-code ADMIN
flask --app plainpunch:create_app run --debugAll authoritative records live in one SQLite file (instance/plainpunch.sqlite3 locally or /data/plainpunch.sqlite3 in Docker). Stop writes or use SQLite's online backup API before copying it. Back up the database and your deployment configuration; never commit either.
CSV export is an interoperability aid, not a complete backup: it excludes passwords, break detail, requests, and audit events.
Passwords and kiosk PINs use Werkzeug's scrypt password hashes. State-changing HTTP requests require session-bound CSRF tokens. Cookies are HTTP-only and SameSite=Lax; production deployments should set PLAINPUNCH_SECURE_COOKIES=1 behind HTTPS. The application makes no third-party analytics or telemetry requests.
PlainPunch is not a payroll processor and does not encode jurisdiction-specific overtime, rounding, leave, scheduling, or record-retention rules. Operators remain responsible for legal review, backups, access control, incident response, and accurate payroll practices.
The tested runtime is Python 3.11–3.14 on Linux, macOS, and Windows. Docker deployment targets Linux containers. Modern browsers are supported.
Feature complete for v1.0. Maintenance prioritizes correctness, security, import/export portability, and a deliberately narrow scope. See DEVELOPMENT.md, TESTING.md, and SECURITY.md.
Released under the MIT License. Contributions follow CONTRIBUTING.md.
PlainPunch is part of the Logan Pendragon Forge open-source collection.