Skip to content

Dossier de Sécurité — APT Repo Manager

Classification : Confidentiel — Usage RSSI / DSI
Version : 1.0
Date : 2026-05-12
Destinataires : RSSI, CISO, équipe sécurité


Table des matières

  1. Vue d'ensemble sécurité
  2. Authentification et gestion des identités
  3. Contrôle d'accès (RBAC)
  4. Pipeline de sécurité des paquets
  5. Gestion des vulnérabilités (CVE)
  6. SBOM et traçabilité
  7. Journalisation et audit trail
  8. Durcissement infrastructure
  9. Headers de sécurité HTTP
  10. Limitations connues et points ouverts
  11. Checklist de conformité

1. Vue d'ensemble sécurité

APT Repo Manager est une plateforme de gestion de dépôts de paquets Debian (format APT) conçue pour les environnements d'entreprise. Elle assure la maîtrise complète de la chaîne d'approvisionnement logicielle, de la réception des paquets jusqu'à leur distribution aux systèmes cibles.

Posture de sécurité

La plateforme repose sur les principes suivants :

  • Défense en profondeur : chaque paquet reçu traverse un pipeline de contrôles séquentiels et indépendants (antivirus, CVE, signature GPG, intégrité).
  • Moindre privilège : cinq rôles distincts avec des périmètres d'action précisément délimités.
  • Séparation des responsabilités : les décisions sur les vulnérabilités (CVE review) sont réservées au RSSI ; les opérateurs n'ont pas accès à l'approbation finale.
  • Traçabilité complète : chaque action sensible est journalisée dans des fichiers JSONL immuables.
  • Conformité réglementaire : alignement NIS2, SecNumCloud (ANSSI), RGPD.

Composants principaux

Composant Technologie Rôle
Backend API FastAPI (Python 3.11) Logique métier, authentification, pipeline sécurité
Base de données SQLite (production : PostgreSQL recommandé) Utilisateurs, paquets, tokens, CVE
Antivirus ClamAV (conteneur dédié) Détection de malwares à chaque upload
Scanner CVE Grype (Anchore) Analyse des vulnérabilités connues
Frontend React + Nginx Interface RSSI/opérateurs
Stockage Volume Docker /repos Paquets, manifestes, audit logs, GPG

2. Authentification et gestion des identités

2.1 Authentification locale

  • Stockage des mots de passe : hachage bcrypt via passlib[bcrypt]. Aucun mot de passe en clair en base.
  • Politique de mots de passe (contrôlée au niveau API) :
  • Longueur minimale : 8 caractères
  • Obligation : au moins 1 majuscule ET au moins 1 chiffre ou caractère spécial
  • Application côté serveur uniquement (non contournable via l'API)
  • Réinitialisation de mot de passe : les tokens de réinitialisation sont stockés sous forme de hash SHA-256 uniquement — jamais en clair en base de données.
  • Statut du compte : champ is_active vérifié à chaque requête authentifiée. La désactivation d'un compte invalide immédiatement toutes les sessions.

2.2 Tokens JWT (sessions utilisateur)

  • Algorithme : HS256
  • Durée de vie : 60 minutes (non configurable sans modification du code)
  • Clé secrète : JWT_SECRET_KEY validée au démarrage. Si la valeur par défaut ou absente est détectée en environnement production (ENV=production), l'application refuse de démarrer.
  • Vérification : le statut actif de l'utilisateur est contrôlé à chaque requête (pas uniquement à la création du token).
  • Point d'attention : absence de mécanisme de révocation/blacklist. Un token valide reste fonctionnel jusqu'à son expiration naturelle (60 min) même après déconnexion explicite. Voir section 10.

2.3 Tokens API (CI/CD)

  • Format : préfixe repod_ + suffixe aléatoire cryptographiquement sûr
  • Stockage : SHA-256 du token uniquement, jamais en clair
  • Expiration : configurable par token (optionnelle)
  • Révocation : immédiate, par l'administrateur ou le propriétaire du token
  • Usage : conçus pour les pipelines CI/CD sans interaction humaine

2.4 LDAP / Active Directory (optionnel)

  • Bibliothèque : ldap3
  • TLS : verify_cert=True par défaut (vérification du certificat serveur LDAP)
  • Provisionnement automatique : à la première connexion LDAP réussie, un compte local est créé avec un mot de passe local aléatoire non utilisable (authentification LDAP exclusive ensuite)
  • Configuration : URL, DN de bind, base de recherche, filtre utilisateur — tous configurables via l'interface d'administration
  • Mots de passe de bind LDAP : masqués dans les réponses GET /settings

2.5 Rate limiting

Endpoint Limite
Authentification (/auth/*) 10 requêtes / minute
Upload de paquets 20 requêtes / minute
Import / fetch 10 requêtes / minute
Opérations batch 5 requêtes / minute
Synchronisation 3 requêtes / minute

3. Contrôle d'accès (RBAC)

Le système implémente un contrôle d'accès basé sur les rôles (RBAC) avec 5 niveaux.

3.1 Matrice des permissions

Permission admin maintainer uploader auditor reader
Gestion des utilisateurs Oui Non Non Non Non
Modification des paramètres Oui Non Non Non Non
Upload de paquets Oui Oui Oui Non Non
Import de paquets Oui Oui Oui Non Non
Promotion de paquets Oui Oui Non Non Non
Suppression de paquets Oui Oui Non Non Non
Synchronisation de dépôts Oui Oui Non Non Non
Décision CVE (approve/reject) Oui Non Non Non Non
Lecture des audit logs Oui Oui Non Oui Non
Lecture des paquets Oui Oui Oui Oui Oui
Export SBOM Oui Oui Non Oui Non
Gestion des tokens API Oui (tous) Oui (siens) Oui (siens) Non Non

3.2 Description des rôles

admin : accès complet à toutes les fonctionnalités. Seul rôle autorisé à créer/modifier/supprimer des utilisateurs, modifier la configuration système, et approuver ou rejeter les vulnérabilités CVE en file d'attente RSSI.

maintainer : cycle de vie complet des paquets (upload, import, promotion, suppression, synchronisation). Accès en lecture aux audit logs. Ne peut pas gérer les utilisateurs ni approuver des CVE.

uploader : peut téléverser et importer des paquets. Ne peut pas promouvoir, supprimer ou synchroniser. Rôle adapté aux pipelines CI/CD sans accès élargi.

auditor : accès en lecture seule aux paquets et aux journaux d'audit. Rôle dédié aux équipes de conformité et aux auditeurs externes. Aucune action d'écriture.

reader : accès en lecture seule aux paquets uniquement. Pas d'accès aux audit logs. Rôle adapté aux consommateurs passifs du dépôt.


4. Pipeline de sécurité des paquets

Chaque paquet reçu (upload ou import) est soumis à un pipeline séquentiel de 7 contrôles avant toute publication.

4.1 Schéma du pipeline

Paquet reçu
     |
     v
[1] Validation de format (dpkg-deb)
     |-- ECHEC --> Rejet immédiat (400)
     v
[2] Vérification de provenance SHA-256
     |-- ECHEC --> Rejet immédiat
     v
[3] Scan antivirus ClamAV
     |-- VIRUS DETECTE --> Quarantaine + blocage
     v
[4] Scan CVE Grype
     |-- CRITICAL/HIGH (policy=block) --> Quarantaine
     |-- CRITICAL/HIGH (policy=review) --> pending_review (file RSSI)
     |-- MEDIUM/LOW (policy=warn) --> Publié avec avertissement
     v
[5] Vérification signature GPG
     |-- INVALIDE --> Avertissement (non bloquant)
     v
[6] Vérification des dépendances
     |-- MANQUANTES --> Avertissement (non bloquant)
     v
[7] Enrichissement EPSS + CISA KEV
     v
Paquet publié dans le dépôt

4.2 Description détaillée de chaque étape

Étape 1 — Validation de format (dpkg-deb)
Vérifie l'intégrité structurelle du fichier .deb via dpkg-deb --info. Tout fichier malformé, tronqué ou ne respectant pas la structure Debian est rejeté avec un code HTTP 400. Cette étape protège contre les tentatives de contrebande de fichiers déguisés en paquets Debian.

Étape 2 — Vérification de provenance SHA-256
Le hash SHA-256 du paquet uploadé est comparé à celui présent dans l'index Packages.gz du dépôt source. Garantit que le paquet n'a pas été altéré entre sa source et la plateforme. Un écart de hash entraîne le rejet immédiat.

Étape 3 — Scan antivirus ClamAV
Le paquet est soumis à ClamAV (base de signatures mise à jour quotidiennement). Toute détection de malware provoque le placement en quarantaine et le blocage de la publication. La quarantaine est un répertoire isolé du dépôt actif, accessible uniquement à l'administrateur.

Étape 4 — Scan CVE Grype
Grype analyse le SBOM du paquet et le croise avec les bases NVD, GitHub Advisory, CISA KEV. La réaction à chaque vulnérabilité est déterminée par la politique configurée par sévérité :

Sévérité Politique Comportement
Critical block Rejet en quarantaine, jamais publié
Critical review pending_review, file d'attente RSSI obligatoire
High block Rejet en quarantaine
High review pending_review, file d'attente RSSI
Medium warn Publié avec flag d'avertissement
Low allow Publié sans restriction

La politique est configurable par l'administrateur via l'interface.

Étape 5 — Vérification signature GPG
Contrôle que le paquet est signé avec une clé GPG de confiance. Cette étape est non bloquante : un paquet sans signature valide est publié mais marqué unsigned. Le RSSI peut configurer une politique stricte (block si non signé) via les paramètres.

Étape 6 — Vérification des dépendances
Contrôle que toutes les dépendances déclarées dans le champ Depends: du paquet sont disponibles dans le dépôt. Un paquet avec des dépendances manquantes génère un avertissement mais est publié. Cela évite d'introduire des paquets incohérents tout en ne bloquant pas les workflows légitimes.

Étape 7 — Enrichissement EPSS + CISA KEV
Pour chaque CVE identifiée lors de l'étape 4 : - EPSS (Exploit Prediction Scoring System) : probabilité d'exploitation dans les 30 prochains jours, fournie par FIRST.org. - CISA KEV (Known Exploited Vulnerabilities) : vérifie si la CVE est activement exploitée selon le catalogue CISA.

Ces données enrichissent le rapport de vulnérabilité présenté au RSSI pour priorisation.


5. Gestion des vulnérabilités (CVE)

5.1 File d'attente RSSI (pending_review)

Les paquets dont au moins une CVE déclenche la politique review passent en statut pending_review. Ils sont visibles dans l'interface RSSI mais ne sont pas accessibles aux consommateurs du dépôt. Le RSSI dispose de deux actions :

  • Approuver : le paquet est promu en publication. La justification est obligatoire et enregistrée dans l'audit trail.
  • Rejeter : le paquet est déplacé en quarantaine. La justification est obligatoire et enregistrée.

5.2 Workflow de décision

pending_review
     |
     |-- RSSI: Approuver (justification requise) --> Publié
     |-- RSSI: Rejeter  (justification requise) --> Quarantaine

Seul le rôle admin peut effectuer ces décisions. Le rôle maintainer peut lire la file d'attente mais ne peut pas approuver.

5.3 SLA par sévérité

Sévérité SLA par défaut Configurable
Critical 0 jour (décision immédiate) Oui
High 30 jours Oui
Medium 90 jours Oui
Low Pas de SLA Oui

Le dépassement de SLA génère des alertes dans l'interface d'administration. Les SLA sont configurables par l'administrateur via les paramètres.

5.4 Enrichissement contextuel

Chaque CVE présentée au RSSI inclut : - Score CVSS v3 (base + vecteur) - Score EPSS (probabilité exploitation 30j) - Présence dans le catalogue CISA KEV - Paquet affecté, version, fix disponible - Justification de la décision précédente (si existante)


6. SBOM et traçabilité

6.1 Formats supportés

Standard Version Organisme
CycloneDX 1.5 OWASP
SPDX 2.3 ISO/IEC 5962:2021

6.2 Contenu du SBOM

Chaque SBOM généré contient : - Inventaire complet des composants du paquet (dépendances directes et transitives) - Identifiants CVE associés et leur statut (suppressed, in_triage, exploitable) - Hash SHA-256 de chaque composant - Métadonnées du fournisseur, version, licence SPDX - Horodatage de génération et de la dernière analyse CVE

6.3 Conformité réglementaire

Le SBOM répond aux exigences de : - NIS2 (UE 2022/2555) : article 21 — inventaire logiciel, gestion des vulnérabilités - ANSSI SecNumCloud : inventaire de logiciels, traçabilité des composants - Executive Order 14028 (US, pour référence) : SBOM pour logiciels livrés

6.4 Export

L'export SBOM est disponible via : - Interface web (rôles : admin, maintainer, auditor) - API REST : GET /api/packages/{id}/sbom?format=cyclonedx ou ?format=spdx


7. Journalisation et audit trail

7.1 Format et stockage

  • Format : JSONL (JSON Lines) — un événement par ligne
  • Organisation : un fichier par jour — /repos/audit/YYYY-MM-DD.jsonl
  • Accès : lecture réservée aux rôles admin, maintainer, auditor
  • Écriture : append-only. Aucune API de modification ou de suppression n'existe.
  • Rétention : configurable (défaut : 90 jours). La suppression des anciens fichiers est gérée par la rotation automatique.

7.2 Structure d'un événement

{
  "timestamp": "2026-05-12T14:32:01.412Z",
  "event": "UPLOAD",
  "user": "john.doe",
  "role": "maintainer",
  "ip": "10.0.1.42",
  "details": {
    "package": "libssl3_3.0.2-0ubuntu1_amd64.deb",
    "sha256": "a3f1...",
    "clamav": "clean",
    "grype_findings": 2,
    "status": "pending_review"
  }
}

7.3 Événements journalisés

Événement Déclencheur
LOGIN_SUCCESS Connexion réussie (avec IP source)
LOGIN_FAILURE Échec de connexion (avec IP source et motif)
USER_CREATE Création d'un compte utilisateur
USER_UPDATE Modification d'un compte (rôle, statut, email)
USER_DELETE Suppression d'un compte
PASSWORD_CHANGE Changement de mot de passe par l'utilisateur
PASSWORD_RESET Réinitialisation de mot de passe (admin ou token)
UPLOAD Upload d'un paquet (résultat du pipeline inclus)
DELETE Suppression d'un paquet
PROMOTE Promotion d'un paquet vers un autre dépôt
IMPORT Import depuis un dépôt externe
SYNC Synchronisation de dépôt
SETTINGS_CHANGE Modification de la configuration (champ modifié logué)
GPG_GENERATE Génération d'une paire de clés GPG
CVE_APPROVE Approbation d'un paquet en pending_review (avec justification)
CVE_REJECT Rejet d'un paquet en pending_review (avec justification)
TOKEN_CREATE Création d'un token API
TOKEN_REVOKE Révocation d'un token API

7.4 Conformité RGPD

Les journaux d'audit contiennent les adresses IP des utilisateurs. Ces données sont des données à caractère personnel au sens du RGPD. Points à noter :

  • La rétention est configurable et doit être alignée sur la politique interne de l'organisation.
  • Aucune autre donnée personnelle n'est présente dans les logs (pas de mots de passe, pas de données de session).
  • La finalité est la sécurité du système d'information (base légale : intérêt légitime / obligation légale NIS2).

8. Durcissement infrastructure

8.1 Conteneurisation (Docker)

Mesure Statut Détail
Socket Docker non monté Appliqué Le conteneur backend n'a pas accès à /var/run/docker.sock
Code source non monté en production Appliqué Seul le volume /repos est monté en production
GPG via volume partagé Appliqué /repos/gnupg partagé entre backend et service GPG, sans socket Docker
Utilisateur non-root Appliqué Le processus backend s'exécute sous un UID dédié (non root)
Image de base minimale Recommandé Utiliser une image Debian slim ou distroless

8.2 Application FastAPI

Mesure Statut Détail
Swagger UI désactivé en production Appliqué ENV=production/docs et /redoc retournent 404
Hot-reload désactivé Appliqué uvicorn démarre sans --reload en production
Nombre de workers Appliqué 2 workers uvicorn en production
Validation JWT_SECRET_KEY Appliqué Crash au démarrage si valeur par défaut ou absente en production
Masquage des secrets dans /settings Appliqué Mots de passe SMTP et LDAP bind masqués (***) dans les réponses GET
Proxies de confiance Configurable TRUSTED_PROXIES env var pour la liste des IPs de proxy autorisés

8.3 Réseau

Mesure Statut Détail
HTTPS en production Non inclus Délégué au reverse proxy (voir REVERSE_PROXY.md)
Port backend exposé Point d'attention Port 8000 exposé sur 0.0.0.0 sans reverse proxy — voir section 10
Isolation réseau Docker Recommandé Utiliser des réseaux Docker dédiés pour isoler les composants

8.4 Clés GPG

  • La génération de clés GPG pour la signature du dépôt est intégrée à l'interface d'administration.
  • Les clés sont stockées dans /repos/gnupg avec les permissions restrictives habituelles de GnuPG.
  • La clé publique est exportée automatiquement dans le dépôt pour permettre la vérification par les clients APT.

9. Headers de sécurité HTTP

Les headers de sécurité suivants sont configurés sur le frontend Nginx.

Header Valeur configurée Objectif
X-Frame-Options SAMEORIGIN Protection contre le clickjacking
X-Content-Type-Options nosniff Prévention du MIME sniffing
X-XSS-Protection 1; mode=block Protection XSS legacy (IE/Edge anciens)
Referrer-Policy strict-origin-when-cross-origin Limitation des informations de référence
Content-Security-Policy default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self' Restriction des sources de contenu
Permissions-Policy camera=(), microphone=(), geolocation=(), payment=() Désactivation des APIs sensibles du navigateur

9.1 Point d'attention : CSP unsafe-inline

La directive 'unsafe-inline' est présente dans script-src et style-src. Cette configuration est due à l'utilisation de styles inline par React. Elle affaiblit la protection CSP contre les attaques XSS. La migration vers une CSP basée sur des nonces est planifiée pour la version 3 (voir section 10).


10. Limitations connues et points ouverts

Cette section liste les limitations actuelles connues de la plateforme, avec leur niveau de risque et les mesures compensatoires recommandées.

10.1 Absence de révocation JWT

Attribut Valeur
Risque Moyen
Description Les tokens JWT ont une durée de vie de 60 minutes. Après une déconnexion explicite ou une désactivation de compte, le token reste techniquement valide jusqu'à son expiration.
Impact Une session volée reste exploitable jusqu'à expiration du token, même si le compte est désactivé.
Mesure compensatoire La durée de 60 minutes limite la fenêtre d'exploitation. La désactivation du compte est vérifiée à chaque requête, bloquant les tokens associés à des comptes désactivés.
Correction planifiée Implémentation d'un blacklist Redis en v2.x

10.2 Absence de HTTPS par défaut

Attribut Valeur
Risque Élevé (si déployé sans reverse proxy)
Description La configuration par défaut ne termine pas TLS au niveau de la plateforme.
Impact Les communications client-serveur ne sont pas chiffrées sans reverse proxy.
Mesure compensatoire Déploiement obligatoire derrière un reverse proxy TLS (nginx, Traefik, HAProxy). Voir REVERSE_PROXY.md.
Statut Non prévu d'intégrer TLS natif (reverse proxy est la pratique standard)

10.3 Port backend exposé sur 0.0.0.0

Attribut Valeur
Risque Moyen (en l'absence de reverse proxy)
Description Le port 8000 du backend est accessible sur toutes les interfaces réseau.
Impact Sans reverse proxy ou règle de firewall, l'API est accessible directement, sans les headers de sécurité du frontend.
Mesure compensatoire Appliquer des règles iptables/nftables limitant l'accès au port 8000 aux seules IPs du reverse proxy.

10.4 Content-Security-Policy avec unsafe-inline

Attribut Valeur
Risque Faible (interface interne, pas d'entrée utilisateur dans les scripts)
Description La CSP autorise unsafe-inline pour les scripts et styles.
Impact Réduction de la protection contre les attaques XSS injectées.
Correction planifiée Migration vers des nonces CSP en v3

10.5 Provisionnement automatique LDAP

Attribut Valeur
Risque Faible
Description Un compte local est créé automatiquement lors de la première connexion LDAP réussie, avec un mot de passe local aléatoire inutilisable.
Impact Des comptes peuvent se créer sans action explicite de l'administrateur.
Mesure compensatoire L'administrateur doit attribuer un rôle manuellement (le compte créé automatiquement n'a aucun rôle par défaut).

11. Checklist de conformité

11.1 NIS2 (UE 2022/2555)

Exigence NIS2 Statut Implémentation
Politique de sécurité des systèmes Partiel RBAC, pipeline sécurité — politique documentée requise
Gestion des incidents Partiel Audit trail complet — procédure de réponse interne requise
Continuité d'activité Non À définir au niveau organisation
Sécurité de la chaîne d'approvisionnement OK Pipeline CVE, SBOM, signature GPG, antivirus
Sécurité des réseaux Partiel Headers HTTP — TLS délégué au reverse proxy
Contrôle d'accès OK RBAC 5 rôles, JWT, MFA non inclus
Chiffrement Partiel Mots de passe hachés, TLS par reverse proxy
Gestion des vulnérabilités OK Grype, file RSSI, SLA configurable, EPSS, CISA KEV
Journalisation OK Audit trail JSONL, rétention configurable, 18 types d'événements
Tests de sécurité Non À planifier (pentest, revue de code)

11.2 ANSSI SecNumCloud

Exigence Statut Implémentation
Inventaire logiciel OK SBOM CycloneDX 1.5 + SPDX 2.3 par paquet
Journaux d'audit OK JSONL append-only, rétention configurable
Contrôle d'accès OK RBAC, moindre privilège
Séparation des environnements Partiel Conteneurs Docker — isolation réseau à renforcer
Chiffrement des données au repos Non Volume /repos non chiffré par défaut — à gérer au niveau OS/infrastructure
Chiffrement des données en transit Partiel Délégué au reverse proxy
Gestion des clés Partiel GPG intégré, JWT secret validé — HSM non inclus

11.3 RGPD

Exigence Statut Implémentation
Minimisation des données OK Seuls email, rôle et IP sont collectés
Durée de conservation Configurable Rétention audit logs configurable (défaut 90j) — définir selon politique interne
Sécurité des données OK Hachage bcrypt, TLS (reverse proxy), accès restreint
Registre des traitements Non À documenter par l'organisation
Procédure d'exercice des droits Non À définir par l'organisation

11.4 Synthèse globale

Domaine Statut global
Authentification & identité OK
Contrôle d'accès OK
Sécurité des paquets OK
Gestion des vulnérabilités OK
SBOM & traçabilité OK
Journalisation & audit OK
Durcissement infrastructure Partiel
Chiffrement & TLS Partiel
Conformité NIS2 Partiel
Conformité SecNumCloud Partiel
Conformité RGPD Partiel

Signalement de vulnérabilités

Le signalement de vulnérabilités de sécurité doit être effectué par voie confidentielle :

Contact : security@[organisation]
Canal : Ne pas utiliser le gestionnaire de tickets public pour les vulnérabilités de sécurité.
Délai de réponse cible : 72 heures pour accusé de réception, 30 jours pour correction (vulnérabilités High/Critical).


Document généré le 2026-05-12 — APT Repo Manager v1.x — Usage restreint RSSI/DSI