FerrVault hérite des contrôles de base de la plateforme FerrLabs — voir ferrlabs.com/fr/security pour l'identité, l'infrastructure, la divulgation de vulnérabilités et la notification de violation. Les addenda ci-dessous couvrent ce qui est spécifique à un gestionnaire de secrets : comment une valeur passe de votre CLI ou pod, à travers TLS, vers un stockage chiffré par enveloppe, puis ressort sous audit.
<h2>Transport</h2>
<ul>
<li>
<strong>TLS 1.2+ uniquement.</strong> Profil Mozilla « Modern » pinné en bord de cluster :
suites AEAD uniquement (AES-GCM, ChaCha20-Poly1305), courbes ECDH P-384/P-521, SNI strict.
<a href="https://www.ssllabs.com/ssltest/analyze.html?d=api.ferrvault.com&latest"
>Note SSL Labs A+</a
>
à date.
</li>
<li>
<strong>Échange de clés hybride post-quantique.</strong>
<code>X25519MLKEM768</code> négocié avec les clients compatibles (Chrome 124+, Firefox
132+, Edge 124+). Défense contre les attaques « harvest now, decrypt later » où un
adversaire enregistre le trafic chiffré aujourd'hui pour tenter de le déchiffrer plus tard
avec un ordinateur quantique.
</li>
<li>
<strong>HSTS preload</strong> sur tous les sous-domaines FerrVault :
<code>max-age=31536000; includeSubDomains; preload</code>, plus une redirection 301 sur
<code>www.ferrvault.com</code>. Soumis aux listes preload Chrome / Firefox / Edge.
</li>
<li>
<strong>DNS CAA</strong> restreint l'émission de certificats à Let's Encrypt uniquement.
</li>
<li>
<strong>Compression de réponse désactivée</strong> sur les endpoints de révélation.
Supprime le canal latéral théorique BREACH.
</li>
<li>
<strong>HTTP→HTTPS</strong> redirection permanente ; l'entrée HTTP ne sert aucun contenu
réel.
</li>
</ul>
<h2>Stockage et chiffrement</h2>
<ul>
<li>
<strong>Chiffrement par enveloppe.</strong> Chaque version de secret est chiffrée avec une
Data Encryption Key (DEK) unique de 256 bits générée par un CSPRNG. La DEK est elle-même
enveloppée par une Key Encryption Key (KEK) par-vault détenue hors de la base applicative.
Aucune DEK n'est jamais écrite sur disque en clair, et aucune KEK n'est écrite — seul
l'identifiant KMS l'est.
</li>
<li>
<strong>AES-256-GCM</strong> avec un nonce aléatoire de 96 bits par écriture. Aucun couple
(clé, nonce) n'est jamais réutilisé : chaque rotation génère une nouvelle DEK.
</li>
<li>
<strong>KEK gérée par KMS.</strong> La production tourne contre HashiCorp Vault Transit ;
LocalKMS est explicitement refusé au démarrage quand
<code>FERRVAULT_ENVIRONMENT=production</code>.
</li>
<li>
<strong>Rotation de KEK</strong> auditable ; les événements de rotation émettent une entrée
dédiée <code>kek.rotated</code>.
</li>
<li>Chiffrement au repos du volume Postgres sous-jacent.</li>
</ul>
<h2>Autorisation et isolation</h2>
<ul>
<li>
<strong>Hiérarchie à trois niveaux :</strong> Vault → Environnement → Secret. Un token
opérateur de staging ne peut littéralement pas déchiffrer un ciphertext de production — le
SAT est lié à un tuple unique <code>(vault, environnement, rôle)</code> et chaque requête
SQL est scopée par <code>environment_id</code>.
</li>
<li>
<strong>Rôles RBAC :</strong> Viewer (lecture), Writer (lecture + rotation), Admin (complet
+ grants).
</li>
<li>
<strong>Allowlist IP par SAT.</strong> Chaque token de service peut déclarer une liste de
CIDR / IP littérales (v4 + v6) en dehors desquels il est rejeté en 403.
</li>
<li>
<strong>Rate-limit par SAT + par IP.</strong> 60 requêtes / minute sur chaque axe ; un
flood de tokens forgés ne peut pas contourner via rotation de bearer aléatoire.
</li>
<li>
Les tokens SAT sont hashés avec <strong>Argon2id</strong> au repos ; la lookup utilise un
hash SHA-256 indexé pour rester O(1) sous charge.
</li>
<li>
L'auth JWT utilise des signatures <strong>ed25519</strong> émises par l'IdP central
FerrLabs.
</li>
</ul>
<h2>Audit</h2>
<ul>
<li>
<strong>Chaque lecture d'une valeur de secret est journalisée</strong> — c'est le produit,
et un échec d'insertion d'audit bloque la lecture. Le plaintext ne quitte pas le process si
la trace ne peut pas être persistée.
</li>
<li>
Chaque écriture, restauration de version, changement de grant, rotation de KEK et événement
de cycle de vie d'environnement est également enregistré.
</li>
<li>
Les lignes d'audit portent l'org, le vault, le secret, l'acteur (JWT utilisateur ou ID
SAT), l'action et des metadata structurées. Accessibles via l'API et l'UI web sous l'onglet
<em>Audit</em> de chaque vault.
</li>
<li>
Audit anti-falsification (chaîne de hash append-only + export immuable) sur la roadmap.
</li>
</ul>
<h2>Headers HTTP de sécurité</h2>
<p>
Appliqués à chaque réponse <code>api.ferrvault.com</code>, <code>app.ferrvault.com</code>,
<code>auth.ferrvault.com</code> et <code>ferrvault.com</code> :
</p>
<ul>
<li><code>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload</code></li>
<li>
<code>Content-Security-Policy: frame-ancestors 'none'</code> +
<code>X-Frame-Options: DENY</code>
</li>
<li><code>X-Content-Type-Options: nosniff</code></li>
<li><code>Referrer-Policy: strict-origin-when-cross-origin</code></li>
<li><code>Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()</code></li>
<li><code>Cross-Origin-Opener-Policy: same-origin</code></li>
<li><code>X-DNS-Prefetch-Control: off</code></li>
</ul>
<h2>Durcissement opérationnel</h2>
<ul>
<li>
Plafond strict sur la taille des bodies entrants (1 MiB) — élimine les tentatives d'OOM par
POST de taille arbitraire.
</li>
<li>
SQL entièrement paramétré ; aucune entrée utilisateur n'est jamais concaténée dans une
string de requête.
</li>
<li>
<code>ON DELETE CASCADE</code> sur chaque clé étrangère scopée par vault — aucune référence
pendante après suppression de vault ou d'environnement.
</li>
<li>
Les erreurs base de données sont mappées sur un body générique
<code>"Database error occurred"</code> ; l'erreur complète est journalisée côté serveur
uniquement.
</li>
<li>
Images de conteneur pulled depuis <code>ghcr.io/ferrlabs/*</code> ; pods en non-root avec
root filesystem en lecture seule.
</li>
</ul>
<h2>Ce que nous ne prétendons pas</h2>
<ul>
<li>
FerrVault n'est <strong>pas encore certifié SOC 2 / ISO 27001.</strong> Suivi sur la
roadmap compliance FerrLabs.
</li>
<li>
Aucun pentest externe n'a été conduit à date. Les contrôles ci-dessus sont le résultat
d'une revue interne.
</li>
<li>
Le mTLS pour operator → API et l'audit append-only chaîné par hash sont sur la roadmap mais
non shippés à date.
</li>
</ul>
<h2>Contact</h2>
<p>
<a href="mailto:security@ferrlabs.com">security@ferrlabs.com</a> ·
<a href="https://ferrlabs.com/fr/security">Sécurité plateforme FerrLabs →</a>
</p>