Sécurité de la plateforme
Recrut'Auto applique une stratégie defense in depth sur 5 couches indépendantes, du firewall périmétrique jusqu'à la validation applicative. Cette page récapitule les protections que vos intégrations (API REST, MCP, plugin LinkedIn) traversent et les garanties que vous pouvez attendre.
Couche 1 — Edge & IP intelligence
À la frontière de notre infrastructure, nous filtrons les IPs malveillantes connues avant tout traitement applicatif :
- CrowdSec Community Blocklist (~15 000 IPs auto-mises à jour) — scanners Shodan/Censys, bots de brute-force SSH, IPs identifiées par la communauté open-source CrowdSec sur l'ensemble des Security Engines connectés.
- Détection comportementale — scenarios
http-bf,http-crawl-non_statics,http-probing,http-bad-user-agentanalysent les logs en continu et bannissent automatiquement les IPs déclenchant des patterns d'attaque. - Drop kernel-level au firewall périmétrique : les IPs bannies sont rejetées avant même d'atteindre le load balancer applicatif. Latence de réaction : ~10 secondes entre détection et bannissement effectif.
Couche 2 — TLS & rate-limiting
Toutes les communications externes utilisent TLS 1.2+ avec des certificats Let's Encrypt automatiquement renouvelés. Les certificats internes sont émis via le challenge DNS-01, sans exposer aucun service interne sur Internet.
Côté rate-limit, vous êtes plafonné par défaut à :
| Surface | Limite |
|---|---|
API REST /api/* (Bearer token) | 60 r/min par utilisateur |
| Surface admin | 20 r/s |
| Endpoints publics (booking) | 10 r/s |
| MCP (Bearer PAT) | 30 r/s |
| Tunnel Sentry | 30 r/s |
Au-delà, vous recevez un 429 Too Many Requests. Implémentez un backoff exponentiel.
Couche 3 — Auth & ownership
Tous les endpoints /api/* (sauf opt-in publics explicites comme /api/calendars/public/*) exigent un des modes d'authentification suivants :
- Bearer JWT Keycloak (utilisateur connecté côté front, OIDC PKCE).
- Personal Access Token (
Authorization: Bearer ra_<token>, voir Tokens). - Token signé HS256 scopé (booking public 14 jours, image candidat 10 minutes).
Une fois authentifié, chaque requête est filtrée par ownership de souscription : vous ne voyez que les ressources de votre abonnement, jamais celles d'un autre tenant. Cette règle est appliquée au niveau de chaque service backend (get_subscription(db, current_user)), pas seulement au niveau de la base.
Les endpoints sensibles non-utilisateur (analyse de réponses LinkedIn par notre moteur ML, etc.) sont protégés par des tokens internes statiques rotables, jamais exposés au navigateur ni au plugin.
Couche 4 — Validation applicative
- Body cap — les requêtes sont rejetées avec
413 Payload Too Largeau-delà de :- 10 MiB sur le tronc commun
/api/* - 4 KiB sur les feature-flags
- 50 MiB sur l'import CV
- 10 MiB sur le tronc commun
- Transfer-Encoding sanity — les requêtes avec un header
Transfer-Encodingmalformé sont rejetées avec400(mitigation request-smuggling). - Pydantic v2 strict mode sur les schémas critiques (
extra=forbid+max_length+patternregex sur les IDs/slugs). Un payload contenant un champ inattendu est rejeté avec422. - MIME validation sur les uploads (CV PDF, enregistrements audio d'entretien) — vérifié via
python-magic, pas via le content-type déclaré par le client. - Scan antivirus ClamAV sur tous les uploads recruteurs (
POST /api/import/cv,POST /api/import/csv,POST /api/interview/meets/{id}/recording). Politique fail-closed : si le daemon clamd est injoignable, l'upload est rejeté avec503 antivirus_unavailableplutôt que de risquer un fichier non scanné. Une menace détectée renvoie422; le nom de signature ClamAV est loggé en interne mais jamais retourné au client pour éviter qu'un attaquant itère pour trouver le bypass. Les admins disposent d'une page/securitypour tester le daemon (carte status, scan d'un fichier de test, bouton EICAR).
Couche 5 — Données privées & assets
Les images de profil candidat (GET /api/candidates/{id}/image) sont servies via un mécanisme d'URL signée courte durée :
- Votre application appelle
GET /api/candidates/{id}/image-urlavec un Bearer token. - Le backend valide l'ownership et retourne un JWT HS256 audience-scopé, valide 10 minutes.
- La balise
<img src=...?token=JWT>est consommée par le navigateur sans réauthentification.
Cela permet d'authentifier l'asset sans exposer le Bearer token dans une requête <img>. Les enregistrements d'entretien (S3) suivent le même pattern avec des URLs présignées.
Audit logging
Tous les events sécurité (auth gate hit, body cap dépassé, signature invalide, IP whitelist match) sont émis sur le logger structuré recrutauto.security et collectés dans Loki. Les anomalies (taux d'anonymous_warning anormal, par exemple) sont alertées via Sentry.
Codes d'erreur courants
| Code | Signification |
|---|---|
400 | Requête malformée (Transfer-Encoding suspect, JSON invalide) |
401 | Token absent, expiré ou invalide |
402 | Aucun abonnement actif — souscrivez un plan |
403 | Permissions insuffisantes ou IP bannie au niveau périmètre |
404 | Ressource introuvable ou hors de votre périmètre d'abonnement |
413 | Body trop gros |
422 | Validation Pydantic échouée (champ inconnu, type invalide, longueur dépassée) |
429 | Rate limit dépassé |
Bonnes pratiques d'intégration
- Stockez les Personal Access Tokens dans un coffre (HashiCorp Vault, AWS Secrets Manager, etc.), jamais en clair dans le code.
- Rotation : générez un nouveau token tous les 90 jours et révoquez l'ancien après bascule.
- Scopez minimal : si votre intégration ne lit que les campagnes, évitez d'utiliser un token admin.
- Soyez rapides à back-off sur 429 — un client poli évite d'être confondu avec un scraper et d'être banni au niveau perimeter.
- Vérifiez le certificat TLS côté client. Aucun endpoint Recrut'Auto ne devrait être appelé en HTTP non chiffré.
Reporter une vulnérabilité
Si vous découvrez une faille de sécurité, contactez security@recrutauto.fr (clé PGP disponible sur demande). Nous nous engageons à accuser réception sous 24h ouvrées et à coordonner un disclosure responsable.
Cette page décrit le comportement observable depuis vos intégrations. L'architecture interne complète (composants, runbooks ops) est documentée séparément à destination des équipes RecrutAuto.