generated from bisco/codex-bootstrap
docs: add initial architecture documentation
This commit is contained in:
151
docs/security-notes.md
Normal file
151
docs/security-notes.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# 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:
|
||||
|
||||
```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.
|
||||
|
||||
## Deployment Security
|
||||
|
||||
Deployment should follow least privilege:
|
||||
|
||||
- expose only nginx publicly;
|
||||
- keep backend and database on an internal Docker network;
|
||||
- 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.
|
||||
Reference in New Issue
Block a user