Files
azionelab/docs/security-notes.md

4.7 KiB

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;
  • 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;
  • 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.

Authentication and Authorization

Required controls:

  • Django admin requires authenticated staff accounts;
  • check-in verification requires authenticated staff or an authenticated scanning client;
  • 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.

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:

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;
  • configure TLS for production;
  • serve static and media files without exposing private files.

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 can make booking responses depend on SMTP availability;
  • 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.