The game
Online matches are played in real time over WebSocket. Signed-in users can add friends, browse registered players and play in several modes.
Against the AI
A single-player match against a computer opponent.
Local multiplayer
2 or 4 players on the same keyboard.
Tournament
Set up a knockout tournament with friends.
Online
A live match against a player in another browser, through the server.


Security
The Vault and ModSecurity setup in this section is my work. The goal was to build the layers a real application needs: secret management, a WAF in front of the app and strong authentication.
Secrets in HashiCorp Vault
Database credentials, mail server settings and Django's SECRET_KEY are not written into the code or an .env file; they live in a KV secret in Vault (myapp/config). Services read the values from Vault on start-up, so secrets never enter the repository, are versioned and can be changed in one place.


A ModSecurity WAF in front
ModSecurity, running with Nginx, inspects incoming requests against its rules before they reach the application. Typical attack patterns such as SQL injection and XSS are blocked before they get to Django, making a bug in the application code much harder to exploit.
OAuth2 and 2FA
Sign-in over OAuth2, plus two-factor authentication (2FA).
Docker: up with one command
The app, database, Nginx, ModSecurity and Vault run in separate Docker containers; the whole system starts with one command.
