# Security Notes This document records security assumptions and controls for AzioneLab's initial architecture. ## Assumptions - The public website is readable by anonymous visitors. - Booking endpoints are public but must validate input strictly. - Administration and check-in functions require authenticated staff users. - HTTPS is expected in production. - PostgreSQL is reachable only from trusted application containers. - Email is sent through a configured SMTP provider or relay. ## Personal Data Reservations contain personal data such as name, email address, optional phone number, and optional notes. Controls: - collect only data required to manage the reservation; - do not expose reservation personal data through public APIs; - do not include personal data in QR codes; - keep check-in preview and confirmation responses limited to operational admission data; - avoid logging request bodies from booking and confirmation endpoints; - avoid logging raw tokens; - restrict admin access to staff users who need it. ## Token Handling Reservation tokens are used for email confirmation and QR verification. Rules: - generate tokens with a cryptographically secure random generator; - make tokens opaque and non-guessable; - do not encode personal data in tokens; - store token hashes when practical; - treat raw tokens as secrets; - keep confirmation tokens and check-in tokens separate by purpose; - allow confirmation tokens only for reservation confirmation; - allow check-in tokens only for QR retrieval and check-in validation; - mark one-time confirmation tokens as used after successful confirmation; - expire confirmation tokens after a reasonable period; - keep QR tokens valid only for the intended performance and check-in period where practical. ## QR Codes QR codes must contain only: - an opaque verification token; or - a verification URL containing an opaque token. QR codes must not contain: - name; - email; - phone; - notes; - reservation metadata that identifies the visitor. The check-in endpoint resolves the token server-side and returns only the minimum information staff need. ## Check-In Security Check-in is performed by authenticated staff or admin users through a mobile-friendly web page. Controls: - require staff authentication for QR verification preview and check-in confirmation; - allow QR scanning and manual token entry in the staff interface; - validate every token server-side; - require the reservation to be confirmed before check-in; - reject duplicate check-in attempts; - store successful check-in timestamp and staff user; - return clear validation states without exposing unnecessary personal data; - do not log raw QR tokens. ## Authentication and Authorization Required controls: - Django admin requires authenticated staff accounts; - check-in verification preview and confirmation require authenticated staff or admin users; - staff permissions should separate content management from operational check-in when practical; - public APIs must not allow clients to set protected fields such as reservation status, token values, or check-in state. - CORS must allow only configured Angular frontend origins through `CORS_ALLOWED_ORIGINS`. ## Input Validation Public booking endpoints must validate: - required fields; - email format; - maximum field lengths; - positive party size; - booking status for the selected performance; - capacity availability; - unexpected fields. Validation must happen server-side even when the frontend also validates input. ## Anti-Overbooking The backend must enforce capacity server-side. Capacity calculation: ```text available seats = room capacity + additional seats - manually occupied seats - confirmed reservations ``` Controls: - use database transactions for confirmation; - lock the performance row or use an equivalent consistency control; - recalculate availability inside the transaction; - confirm the reservation only when enough seats remain; - ensure duplicate confirmation requests are idempotent or rejected safely; - do not rely on frontend availability values. ## Secrets Secrets must not be committed to the repository. Expected secret configuration: - Django `SECRET_KEY`; - database password; - SMTP credentials; - TLS private keys or certificate automation credentials, if used. Use environment variables, Docker secrets, or deployment-managed secret injection. Documentation and example configuration should use placeholders only. For the Docker Compose setup, copy `.env.example` to `.env` and replace placeholder values outside version control. The repository ignores `.env` and `.env.*` files except `.env.example`. ## Deployment Security Deployment should follow least privilege: - expose only nginx publicly; - keep backend and database on an internal Docker network; - do not publish backend, frontend, or PostgreSQL ports to the host in production; - avoid privileged containers; - use explicit image tags rather than `latest`; - persist PostgreSQL data in a named volume; - run production with `DJANGO_DEBUG=false`; - use a strong private `DJANGO_SECRET_KEY`; - restrict `DJANGO_ALLOWED_HOSTS` and `DJANGO_CSRF_TRUSTED_ORIGINS` to the real public deployment hosts; - keep `SITE_BASE_URL` set to the real public HTTPS URL so email and QR links are correct; - configure TLS for production; - serve static and media files without exposing private files. Operational production notes: - `.env.example` is for local development and examples only, not direct production use; - replace the console email backend with real SMTP settings before sending reservation emails; - create admin accounts explicitly and protect them with strong passwords and limited access; - keep verified database backups for the PostgreSQL volume before accepting live bookings. ## Logging Logs should help diagnose operational issues without exposing sensitive data. Do not log: - raw confirmation tokens; - raw QR tokens; - full booking payloads; - passwords; - session cookies; - authorization headers; - SMTP credentials. ## Residual Risks Initial residual risks: - synchronous email after commit can still add latency to booking requests even though it no longer runs inside the reservation transaction; - QR codes can be copied, so duplicate check-in prevention must be reliable; - staff account compromise would expose admin and check-in functionality; - retention and deletion rules for personal data still need a project policy.