secure-app-scaffolder

Génère une application web sécurisée dès la conception, conforme aux normes ANSSI, CIS, FBI et OWASP ASVS niveau 2 : frontend TypeScript, backend Python, base de données PostgreSQL durcie.

Qu'est-ce que secure-app-scaffolder ?

Secure App Scaffolder est une compétence d'agent IA qui génère des applications web complètes, sécurisées par conception, en suivant les recommandations des principales autorités de sécurité (ANSSI, CIS, FBI, OWASP ASVS niveau 2). Elle produit une stack technique composée d'un frontend TypeScript, d'un backend Python et d'une base de données PostgreSQL durcie, le tout s'exécutant dans des conteneurs rootless. La compétence est idéale pour démarrer un nouveau projet, ajouter des fonctionnalités d'authentification, d'autorisation, de téléchargement de fichiers, de journalisation d'audit, d'administration, ou pour déployer avec Docker/Podman. Elle intègre automatiquement des mesures de sécurité avancées : validation zéro-confiance, autorisation au niveau des objets, chiffrement au niveau des colonnes, écritures idempotentes, OIDC/LDAPS/WebAuthn, journaux d'audit inviolables, honeytokens, signatures d'images, double scan (Trivy + OpenSCAP) et une procédure de nettoyage pré-production.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SkouedLabs/SkouedSkills/tree/HEAD/.claude/skills/secure-app-scaffolder

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Secure App Scaffolder

Génère une application sécurisée dès la conception, conforme aux normes ANSSI, CIS, FBI et OWASP ASVS niveau 2 : frontend TypeScript, backend Python, base de données PostgreSQL durcie.

La mise en page, le README et l'interface utilisateur suivent la compétence project-blueprint. Les règles de sécurité de cette compétence prévalent sur toute règle de commodité ou d'expérience utilisateur.

Fichiers de référence (à lire lors de la génération de l'artefact correspondant)

Quand l'utiliser

  • Pour démarrer, structurer ou architecturer une nouvelle application ou service web.
  • Pour des requêtes mentionnant ANSSI, CIS, FBI, OWASP, durcissement, rootless, conformité.
  • Pour ajouter l'authentification, l'autorisation, les téléchargements de fichiers, la journalisation d'audit, les fonctionnalités d'administration, les fichiers de déploiement ou les points de terminaison MCP.

Cibles de déploiement : Docker et Podman rootless uniquement. Ne générez pas de manifestes Kubernetes, Helm ou autres orchestrateurs, sauf demande explicite de l'utilisateur.

0. Modèle de Menaces

  • Créez docs/security/threat-model.md (≤ 1 page) : actifs, limites de confiance, acteurs, risques principaux (STRIDE) et le contrôle qui les atténue. Mettez-le à jour lorsqu'une nouvelle limite de confiance apparaît (téléchargement, webhook, LLM, MCP).

1. Conteneurs et Exécution

  • Rootless : chaque image se termine par un USER numérique (par ex. USER 10001:10001), y compris le serveur web (nginxinc/nginx-unprivileged, port > 1024).
  • Images minimales et épinglées : constructions multi-étapes ; l'étape d'exécution est distroless ou slim, sans shell, compilateur ni gestionnaire de paquets ; dépendances de développement exclues. Images de base épinglées par digest. Dernière version stable de Python.
  • Durcissement : read_only, tmpfs pour les chemins accessibles en écriture, cap_drop: [ALL], no-new-privileges, profil seccomp par défaut de l'exécution (jamais unconfined), pids_limit, limites mémoire, healthchecks, vidages mémoire désactivés (ulimits: core: 0). Seul le proxy inverse publie des ports ; le réseau de la base de données est internal: true. Ne montez jamais le socket Docker/Podman.
  • Pas de sous-processus : pas de subprocess, os.system, shell=True. Applicable par : pas de shell dans l'image, une règle SAST, et un filtre seccomp in-process refusant execve/execveat chargé dans chaque worker après le démarrage (un refus au niveau du conteneur empêcherait le point d'entrée lui-même de démarrer).
  • Garantie de premier lancement : sur un clone propre, docker compose up (ainsi que docker-compose up et podman compose up) fonctionne du premier coup : pas de .env, pas d'étape manuelle, aucun prérequis autre que le moteur de conteneur. Les images se construisent automatiquement (build:), seules les fonctionnalités de la spécification Compose prises en charge par Docker Compose v2 et podman-compose sont utilisées, aucun chemin hôte en dehors du dépôt, ports publiés > 1024, pas de limites CPU (indisponibles dans de nombreuses configurations rootless cgroup). make up est une mince surcouche autour de la même commande.
  • Pas de secrets en dur : Un service init unique génère les secrets dans un volume nommé (0600) consommé via les variables *_FILE. Les secrets sont lus depuis des fichiers, pas depuis des variables d'environnement, en production.
  • Autonome (air-gapped) : tous les JS/CSS/polices/icônes sont regroupés ; pas de CDN, de téléchargement à l'exécution ni de télémétrie. Les dépendances proviennent d'un miroir interne (Nexus, Artifactory, devpi, Verdaccio) lors de la construction hors ligne.
  • Prêt pour Vault : une seule abstraction de fournisseur de secrets (file par défaut, vault/sops en production).
  • TLS interne : backend ↔ base de données via TLS ; mTLS optionnel entre les services.

2. Chaîne d'Approvisionnement et Analyse

  • Dépendances verrouillées : engagez les lockfiles ; npm ci, uv sync --frozen ou pip install --require-hashes. .npmrc avec ignore-scripts=true sauf si un paquet nécessite des scripts d'installation (liste d'autorisation).
  • Passerelle de pré-construction : npm audit --audit-level=high et pip-audit font échouer la construction si le code de sortie est > 0.
  • SAST et secrets : pre-commit avec ruff, bandit/semgrep, eslint (+ eslint-plugin-security), gitleaks.
  • Analyses d'images (make scan) : trivy image (CVE + secrets + mauvaises configurations), trivy config sur les Dockerfiles et compose, oscap-podman (ou oscap-docker) contre le profil CIS du système d'exploitation de base.
  • SBOM et signature (make sbom) : SBOM CycloneDX (Trivy ou Syft), images signées avec cosign (basé sur une clé pour le hors ligne), SBOM attaché comme attestation ; le déploiement vérifie la signature.
  • DAST (optionnel, recommandé) : OWASP ZAP baseline contre la pile en cours d'exécution dans l'IC.
  • Mises à jour : Renovate/Dependabot (ou une revue hors ligne équivalente) à une cadence fixe.

3. Frontend (TypeScript)

  • Emplacement : /frontend avec son propre Dockerfile, construit en tant qu'actifs statiques servis par Nginx non privilégié.
  • Code compatible CSP : pas de <script> en ligne, pas de eval/new Function, pas de CSS-in-JS à l'exécution injectant <style> sans nonce. Préférez le CSS compilé. Trusted Types activé (require-trusted-types-for 'script').
  • Entrée zéro-confiance : schéma Zod typé par formulaire, partagé avec les types API. Jamais dangerouslySetInnerHTML/v-html sur des données non fiables ; DOMPurify si le texte enrichi est inévitable.
  • Idempotence : le client API attache une clé d'idempotence (Idempotency-Key, UUIDv4) à chaque POST/PUT/PATCH/DELETE, générée une fois par action utilisateur et réutilisée en cas de nouvelles tentatives.
  • CSRF : en-tête personnalisé (X-Requested-With) + jeton CSRF ; le backend vérifie également Origin/Sec-Fetch-Site. Liste d'autorisation CORS uniquement, jamais * avec identifiants.
  • Redirections ouvertes : next/returnUrl après connexion n'accepte que les chemins relatifs commençant par un seul /.
  • Pas de secrets dans le bundle ; pas de source maps en production ; pas de données sensibles dans localStorage/sessionStorage.

4. Backend (Python) et Base de Données

  • Validation : chaque corps, paramètre de requête, paramètre de chemin et en-tête validé par Pydantic avec des longueurs maximales et extra="forbid" (empêche l'attribution en masse : role, owner_id, is_admin ne sont jamais liables depuis l'entrée).
  • Limites de ressources : taille maximale du corps de requête, profondeur/longueur maximale du tableau JSON, taille maximale de page (par ex. 100), timeouts côté serveur. Les expressions régulières sur les entrées utilisateur sont bornées ou utilisent un moteur à temps linéaire (re2) pour éviter ReDoS.
  • Analyse sécurisée : pas de pickle, marshal, yaml.load (utilisez yaml.safe_load), eval. XML via defusedxml. Pas d'entrée utilisateur dans les sources de templates (SSTI). Les chemins de fichiers sont résolus et vérifiés par rapport à un répertoire de base (traversée de chemin).
  • Stockage d'idempotence : (user_id, key) -> request_hash, status, response, TTL de 24 h. Même clé + même hash renvoie la réponse stockée ; hash différent renvoie 422. Cela empêche les doublons ; la protection contre la relecture provient de TLS, des jetons CSRF et des sessions courtes.
  • SQL : ORM ou requêtes paramétrées uniquement ; identifiants dynamiques (ORDER BY, noms de colonnes) via une liste d'autorisation.
  • Chiffrement au niveau des colonnes : les PII sont chiffrées dans l'application avec AES-256-GCM, chiffrement en enveloppe (DEK par enregistrement enveloppé par une clé maîtresse du fournisseur de secrets), colonne key_version pour la rotation, index aveugle HMAC-SHA256 pour les champs interrogeables. La clé maîtresse n'est jamais stockée dans la base de données ni dans les sauvegardes de la base de données.
  • Durcissement de la base de données : PostgreSQL minimal, scram-sha-256, TLS, deux rôles (propriétaire des migrations, DML d'exécution uniquement), pas de superutilisateur depuis l'application, migrations Alembic, statement_timeout sur le rôle d'exécution.
  • Console SQL (si présente) : rôle en lecture seule, SELECT unique, statement_timeout, limite de lignes, configuration verrouillée.
  • Cryptographie et post-quantique : AES-256-GCM au repos est résistant au quantique. La préparation PQ cible les échanges de clés et les signatures : hybride TLS X25519MLKEM768 sur le proxy ; ML-KEM/ML-DSA (FIPS 203/204) uniquement là où la bibliothèque les prend en charge. Valeurs aléatoires provenant de secrets/crypto.getRandomValues. N'implémentez jamais de primitives cryptographiques.
  • Requêtes sortantes (SSRF) : toute URL configurable dans l'interface utilisateur (webhooks, syslog, LLM, OIDC) est validée : https uniquement (sauf liste d'autorisation explicite), IP résolue rejetée si bouclage/lien-local/métadonnées (169.254.0.0/16, fd00:ec2::254) ou privée sauf si autorisée, revérifiée après résolution DNS (rebinding DNS), pas de redirections inter-hôtes, timeouts stricts.
  • Webhooks sortants : signés avec HMAC-SHA256 (X-Signature + timestamp) afin que les récepteurs puissent les vérifier.
  • E-mail : les valeurs d'en-tête sont dépouillées de CR/LF ; SMTPS avec vérification du certificat.
  • Exportations : les cellules CSV/XLSX commençant par =, +, -, @, tabulation ou CR sont préfixées par ' (injection de formule).
  • Limitation de débit : connexion, réinitialisation de mot de passe, vérification MFA, clés API, exportations, téléchargements et points de terminaison coûteux.
  • Réponses : Cache-Control: no-store sur les réponses API authentifiées. Messages d'erreur génériques avec un request_id ; traces de pile uniquement dans les logs. Interface utilisateur OpenAPI désactivée ou réservée à l'administrateur en production.

5. Autorisation

  • Refus par défaut : chaque route déclare son autorisation requise ; une route sans déclaration fait échouer le démarrage ou les tests.
  • RBAC avec des rôles mappés aux autorisations (pas de vérification directe des rôles dans le code).
  • Vérifications au niveau des objets (IDOR/BOLA) : vérification de propriété ou de locataire dans la couche de dépôt pour chaque lecture/écriture par ID. L'accès non autorisé à un objet existant renvoie 404.
  • Vérifications au niveau des fonctions : les routes d'administration sous /api/v1/admin/* sont protégées par une seule dépendance, jamais uniquement en masquant l'interface utilisateur.
  • Actions sensibles (changements de rôle, création de clés, exportations, suppression d'utilisateurs) nécessitent une ré-authentification récente ; approbation optionnelle à quatre yeux pour l'élévation de rôle en administrateur.

6. Téléchargements de Fichiers (le cas échéant)

  • Limite de taille au niveau du proxy et de l'application ; liste d'autorisation des extensions et vérification des magic bytes.
  • Stockés en dehors de la racine web (ou stockage d'objets), noms de fichiers aléatoires, servis avec Content-Disposition: attachment et X-Content-Type-Options: nosniff.
  • Les images sont ré-encodées (supprime les EXIF et les polyglots) ; les archives sont vérifiées pour les bombes et la traversée de chemin ; antivirus hors ligne optionnel (ClamAV).
  • Les téléchargements SVG et HTML sont refusés sauf s'ils sont nettoyés et servis depuis une origine isolée.

7. Journalisation, Audit et Administration

  • Logs structurés : JSON, niveaux DEBUG/INFO/WARN/ERROR/CRITICAL, request_id partout, timestamps UTC, CR/LF supprimés des valeurs utilisateur. Les mots de passe, jetons, clés et ID de session ne sont jamais journalisés.
  • Syslog distant : RFC 5424 sur TLS (RFC 5425) avec un tampon local limité ; hôte, port, TLS, CA configurables depuis l'interface d'administration. Pas de conteneur rsyslog.
  • Notifications d'erreur : SMTPS et webhooks configurables depuis l'interface d'administration, validés contre le SSRF, bouton "Envoyer un test", limités en débit.
  • Masquage des PII : middleware activable depuis l'interface d'administration.
  • Piste d'audit inviolable : table en ajout seul (le rôle d'exécution a INSERT/SELECT uniquement), chaque ligne chaînée avec le hash de la ligne précédente, transférée à syslog. Couvre les connexions, échecs, modifications MFA, changements de rôle, modifications de configuration, exportations, clés API, hits honeytoken ; enregistre l'utilisateur, l'IP, le user agent, l'heure UTC et les valeurs avant/après.
  • Tableau de bord d'administration : statistiques d'utilisation, erreurs, alertes honeytoken, IP bloquées.
  • Hygiène planifiée : désactiver les comptes inactifs, purger les jetons/sessions/clés d'idempotence expirés, sauvegardes chiffrées quotidiennes (clé séparée de la sauvegarde), politique de conservation et procédure de restauration testée (make restore-test).
  • Données personnelles (RGPD) : périodes de conservation par type de données, exportation et suppression des données utilisateur, tâches de purge.

8. Authentification, Identité et Défense Active

  • Mots de passe : Argon2id (valeurs par défaut argon2-cffi / RFC 9106, minimum m=19 MiB, t=2, p=1), re-hachage à la connexion lorsque les paramètres changent. Politique selon NIST SP 800-63B : ≥ 12 caractères, max ≥ 64, pas de règles de composition, rejeté s'il figure dans une liste groupée de mots de passe compromis/courants.
  • Connexion : réponse et timing identiques pour les utilisateurs inconnus, délais progressifs + limitation par compte et par IP (éviter le verrouillage dur qui permet un déni de service).
  • Réinitialisation de mot de passe : jeton unique à usage unique stocké haché, expiration 30 min, même réponse que le compte existe ou non, toutes les sessions révoquées après la réinitialisation.
  • Sessions : côté serveur, cookie __Host-session (HttpOnly; Secure; SameSite=Lax; Path=/), ID tourné à la connexion et au changement de privilège, les utilisateurs peuvent lister et révoquer leurs sessions actives. Pas de JWT dans le stockage du navigateur ; si des JWT sont utilisés service à service : algorithme épinglé, none refusé, aud/iss/exp vérifiés, durée de vie courte.
  • Sessions administrateur : 1 h d'inactivité, 8 h absolues, ré-authentification pour les actions destructrices.
  • MFA : TOTP (codes de récupération hachés, rejeu du même code refusé) et WebAuthn/Passkeys. MFA obligatoire pour les comptes administrateurs.
  • Détection de contexte : les connexions administrateur depuis une IP/périphérique inconnu déclenchent une notification "Nouvelle connexion" et restreignent les droits destructeurs jusqu'à confirmation MFA.
  • Administrateur d'amorçage : mot de passe aléatoire généré au premier démarrage, lisible une fois via make admin-password, réinitialisation forcée + inscription MFA à la première connexion.
  • Compte de secours (optionnel) : administrateur local utilisable lorsque le SSO est indisponible, désactivé par défaut, chaque utilisation déclenche une alerte critique.
  • SSO : flux OIDC code + PKCE, state et nonce validés, signature/aud/iss du jeton d'ID vérifiée ; LDAPS ou StartTLS avec vérification du certificat, valeurs des filtres LDAP échappées (injection LDAP). Groupes d'annuaire mappés aux rôles.
  • Configuration SSO, deux sources équivalentes : chaque paramètre OIDC et LDAP(S) (indicateur d'activation, URL du serveur/émetteur, ID client, portées, DN de liaison, DN de base, filtres utilisateur/groupe, bundle CA, mappage groupe-à-rôle, auto-provisioning) peut être défini soit depuis l'interface d'administration soit depuis des variables d'environnement (BACKEND_OIDC_*, BACKEND_LDAP_*).
    • Les secrets (client_secret, mot de passe de liaison) proviennent des variables *_FILE ou du fournisseur de secrets, jamais de valeurs d'environnement en clair en production ; dans l'interface utilisateur, ils sont en écriture seule (••••last4).
    • Précédence : un paramètre défini par l'environnement l'emporte et est affiché en lecture seule dans l'interface d'administration avec un badge "Géré par l'environnement" ; tout le reste est modifiable et stocké chiffré dans la base de données.
    • Même validation pour les deux sources (schéma Pydantic partagé par le chargeur d'environnement et l'API d'administration) ; une configuration d'environnement invalide fait échouer le démarrage avec une erreur claire, une entrée invalide dans l'interface utilisateur est rejetée avant sauvegarde.
    • L'interface d'administration a une action "Tester la connexion" (découverte OIDC + récupération JWKS, liaison LDAP + recherche d'exemple de groupe) et chaque modification est auditée.

Skills associés