9-course Dutch e-learning platform fused onto atlasacademy.nl via Caddy reverse proxy. Odoo 19 Community as course engine (website_slides), static HTML for marketing front. Single Odoo account system. - static/: 8 marketing pages (index, pricing, coaching, leerpad, over, shop, bisl, esf) - backend/odoo_relay.py: lead relay Flask service (POST /academy-lead → Odoo CRM) - caddy/academy.caddyfile: full Caddy config with Odoo proxy + auth rewrites - docs/: ARCHITECTURE, USERFLOW, COURSES, DEPLOYMENT, SECURITY, ODOO Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
Security Model — Atlas Academy
Dreigingsmodel
| Dreiging | Maatregel | Status |
|---|---|---|
| Hardcoded secrets in source | Env-bestanden (/etc/atlas/*.env, root 600) |
✅ Opgelost |
| Zwakke wachtwoord-hashing | bcrypt via academy_auth_v2.py (nu retired; Odoo native auth) |
✅ Opgelost |
| PII in publieke admin-panel | academy_admin.py verwijderd uit docroot |
✅ Opgelost |
| Odoo backend publiek bereikbaar | /web niet geproxied via academy-domein |
✅ Opgelost |
| Open signup op corp-website | website 1.auth_signup_uninvited = 'b2b' |
✅ Opgelost |
| Clickjacking | X-Frame-Options: DENY via Caddy |
✅ Actief |
| MIME-sniffing | X-Content-Type-Options: nosniff |
✅ Actief |
| HTTPS downgrade | Strict-Transport-Security: max-age=31536000 |
✅ Actief |
| ESF-tracker indexeerbaar | X-Robots-Tag: noindex, nofollow + robots.txt |
✅ Actief |
| Stale SMTP app-wachtwoord | Handmatige rotatie vereist (Google Account UI) | ⚠️ Openstaand |
| XML-RPC relay-wachtwoord | In env, maar waarde mogelijk stale | ⚠️ Controleren |
Secrets locaties
Alle secrets zijn buiten source gehouden. Alleen locaties zijn gedocumenteerd.
| Bestand | Inhoud | Rechten |
|---|---|---|
/etc/atlas/academy-relay.env |
ODOO_RELAY_LOGIN, ODOO_RELAY_PASS, ACADEMY_ADMIN_PASS, LEAD_SMTP_PASS |
root:root 600 |
/etc/atlas/academy-auth.env |
AA_SECRET (retired Flask JWT secret) |
root:root 600 |
Toegangsarchitectuur
Internet
│
▼
atlasacademy.nl (Caddy)
│
├── /slides, /web/login, /web/signup → Odoo (public eLearning)
│
├── /academy-lead → odoo_relay.py (localhost only)
│
├── /var/www/atlasacademy.nl/* → Static files
│
└── /web (NIET geproxied) → ❌ Geblokkeerd voor publiek
(Odoo backend enkel via tailnet)
odoo.atlascorporation.nl (Caddy)
│
└── Authentik forward_auth → Alleen via SSO bereikbaar
Odoo signup-beveiliging
Website 1 (Atlas Corporation) → auth_signup_uninvited = 'b2b' → GESLOTEN
Website 3 (Atlas Academy) → auth_signup_uninvited = 'b2c' → OPEN (gewenst)
Verificatie:
ssh atlas-01 "docker exec -i atlas-odoo odoo shell -d atlas --no-http" <<'EOF'
for w in env['website'].sudo().search([]):
print(f"Website {w.id} ({w.name}): signup={w.auth_signup_uninvited}")
EOF
Headers (Caddy)
header {
X-Frame-Options DENY
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security max-age=31536000
}
Secrets roteren
SMTP app-wachtwoord (LEAD_SMTP_PASS)
- Ga naar myaccount.google.com/apppasswords
- Verwijder het oude wachtwoord, maak een nieuw aan
- Update op atlas-01:
sudo nano /etc/atlas/academy-relay.env - Herstart:
sudo systemctl restart atlas-academy-relay
Odoo relay-wachtwoord (ODOO_RELAY_PASS)
- Log in op Odoo backend (tailnet)
- Wijzig wachtwoord van de relay-gebruiker
- Update
/etc/atlas/academy-relay.env sudo systemctl restart atlas-academy-relay
Wat NIET te doen
- ❌ Nooit secrets committen in git
- ❌ Nooit
/webproxien via het publieke academy-domein - ❌ Nooit wachtwoorden automatisch roteren (operator handelt dit af)
- ❌ Nooit
--sendgebruiken inatlas_client_email.pyzonder goedkeuring - ❌ Nooit studentgegevens publiceren (geen nep-reviews, nep-studentaantallen)