# 03 — Sécurité

> La sécurité repose sur des briques **déjà implémentées**. Ce document en donne le cadre et les règles à suivre pour chaque module.

## Authentification

### Portail web (`main`)
`form_login` + remember-me + `login_throttling` (5/15 min) + `switch_user` (ROLE_ADMIN). 2FA e-mail, approbation d'appareil, validation IP/pays selon flags utilisateur.

### API (`api`, stateless)
JWT Bearer. Flux (voir [04 — API](04-api.md)) :
- `POST /api/login {email,password}` → `{token, refresh_token, expires_in, user}` (200) ou 202 si 2FA/appareil/pays requis.
- `GET /api/me` (Bearer).
- `POST /api/token/refresh {refresh_token}` — **exige aussi le Bearer** (route sous `^/api → IS_AUTHENTICATED_FULLY`).

Artefacts : `AuthController`, `JwtTokenService` (stockage/validation, anomalie géo), `RefreshTokenService` (rotation, fenêtre 5 min, grâce même-appareil), `JWTCreatedListener` (jti). JWT TTL 6 h, refresh 7 j.

**Post-auth** : `TokenSecurityListener` révoque tous les tokens sur anomalie pays/UA/IP (désactivable via `ENABLE_TOKEN_SECURITY_VALIDATION`).

## Autorisation — RBAC par boutique

Fondation en place (voir mémoire « fondation RBAC ») :

- **Rôles globaux** (`User.roles`, JSON) : `ROLE_ADMIN` (système), `ROLE_MANAGER`, `ROLE_EMPLOYER`, `ROLE_USER` — **inchangés**, source des ~contrôles existants.
- **Rôles/permissions par boutique** : entités `Role`/`Permission` (many-to-many), portés par `UserCompany.boutiqueRole`. Scope `SYSTEM_GLOBAL` | `BOUTIQUE`.
- **Résolution centrale** : `PermissionResolver::isGranted(user, permission, ?company)` → délégué par `PermissionVoter` (attributs à point) et `CompanyVoter`.

### Règle pour chaque module
Définir ses **permissions** selon la convention `<domaine>.<action>` et les gater :

```php
// Contrôleur
$this->denyAccessUnlessGranted('pos.sell', $company);
// Template
{% if is_granted('report.view', company) %} … {% endif %}
```

Permissions POS déjà seedées : `boutique.view/edit`, `boutique.employee.manage`, `pos.sell`, `pos.refund`, `pos.session.open/close`, `report.view/export`, `media.*`. Étendre via `RbacSeedCommand` (voir [conventions](notes/conventions.md)).

> **Note de compatibilité (phase 1)** : l'autorité EDIT/MANAGE vient encore des rôles **globaux** ; la bascule vers l'autorité par `boutiqueRole` est un choix **délibéré de phase 2** (voir `PermissionResolver`). Les modules doivent utiliser les codes de permission (`pos.sell`…) pour être prêts à cette bascule.

## Chiffrement au repos

`EncryptionService` (libsodium secretbox authentifié), clé `APP_ENCRYPTION_KEY`. Utilisé pour le mot de passe des bases clients (`CompanyDatabase`). **Tout nouveau secret** (clés d'API de paiement, tokens tiers…) doit passer par ce service — jamais de secret en clair.

## Isolation & données clients

- Toute entité POS est scopée `Company` ; les requêtes doivent filtrer par la boutique de l'utilisateur (voir le pattern manager : `getPrimaryCompany()`, `findAllQueryForManagerByCompany`).
- La **base client** ne reçoit qu'une projection en lecture (surface réduite) ; l'écriture reste centrale.
- Test de connexion DB (`admin_companies_database_test`) réservé à `COMPANY_EDIT` ; **risque SSRF** (hôte/port fournis par l'admin) → durcir en phase 2 (liste blanche d'hôtes, blocage IP internes).

## Journalisation, alertes, menaces

- `FileLogger` (logs datés) — **jamais** de secret/mot de passe dans les logs.
- `AlertDeduplicationService` : toute alerte email passe par la dédup (fenêtre 15 min) — ne pas envoyer d'alerte en direct.
- `ProactiveThreatDetectionListener` : blocage proactif des scanners (indépendant du login).
- Flags `ENABLE_AUTO_IP_BLOCKING` / `ENABLE_AUTO_ACCOUNT_LOCK` câblés.

## Checklist sécurité par module

- [ ] Permissions `<domaine>.<action>` définies et seedées.
- [ ] Contrôleurs gatés (`denyAccessUnlessGranted`) + templates conditionnés.
- [ ] Requêtes scopées `Company`.
- [ ] Secrets éventuels chiffrés (`EncryptionService`).
- [ ] Endpoints API sous le firewall `api` (Bearer) sauf public explicite.
- [ ] Erreurs via try/catch + `FileLogger` ; aucune fuite de secret.
- [ ] Tests d'accès (autorisé/refusé) — voir [06 — Plan de tests](06-plan-de-tests.md).

## Suite

Conception de l'API : [04 — API](04-api.md).
