Chaîne d'approvisionnement

Les agents de codage installent beaucoup de paquets, et une dépendance fraîchement compromise est l'un des moyens les plus directs d'empoisonner un bac à sable. Le volet Chaîne d'approvisionnement configure la politique par espace de travail que Bromure Agentic Coding applique à chaque récupération de paquet. Comme l'indique la description du volet : Bromure analyse chaque récupération de paquet (npm, PyPI, Cargo, RubyGems, Maven, NuGet, modules Go, Packagist) via le MITM de l'hôte et applique ces politiques avant que l'agent ne voie la réponse ; le .npmrc / pip.conf interne à la VM ne peut que restreindre davantage ces paramètres — il ne peut pas les assouplir. Utilisez les listes d'autorisation par paquet pour des dérogations chirurgicales.

Le volet Chaîne d'approvisionnement de l'éditeur de paramètres de l'espace de travail, montrant le groupe Filtrage par âge activé avec un minimum de 2 jours et le groupe de contrôle de vulnérabilité OSV

Le volet regroupe cinq couches activées indépendamment : Filtrage par âge, Contrôle de vulnérabilité OSV, Filtrage de paquets, Scripts d'installation et Installations épinglées par fichier de verrouillage (faites défiler pour voir les trois dernières). Cette page documente les paramètres ; le pipeline complet — couverture des écosystèmes, journal de sécurité, en-têtes de réponse et détection de compromission — est traité dans le chapitre sur la protection de la chaîne d'approvisionnement.

Fonctionnement de l'application

Tous les contrôles s'exécutent dans le proxy côté hôte, jamais à l'intérieur de la VM. Les clés d'API des services de réputation (socket.dev, Delpi) sont conservées uniquement sur l'hôte et ne sont jamais exportées dans la VM. Lorsqu'un contrôle se déclenche, le proxy bloque le téléchargement avec une réponse HTTP 451 portant une raison en texte clair (par exemple, « npm package [email protected] published 4 hours ago — policy requires 2 days minimum ») ; npm, pip et cargo affichent ce texte tel quel, de sorte que l'agent comme vous voyez exactement pourquoi une installation a échoué. Les réponses bloquées portent l'en-tête X-Bromure-Block: supply-chain ; les réponses réécrites portent X-Bromure-Rewritten: supply-chain.

Les modifications de politique s'appliquent en direct : l'enregistrement de l'espace de travail transmet immédiatement la nouvelle politique aux sessions en cours — sans redémarrage de la VM — et chaque changement est confirmé par une ligne [supply-chain] policy engaged dans le journal de sécurité (menu Fenêtre → Journal de sécurité…).

Remarque : Les paquets déjà présents dans le cache local de npm ou de pip ne touchent jamais le réseau, donc rien n'est contrôlé ni journalisé pour eux. Un journal de sécurité silencieux pendant une installation peut simplement signifier que tout était en cache.

Filtrage par âge

Le filtrage par âge refuse les versions de paquets plus récentes qu'un seuil configurable, sur la théorie que les versions tout juste publiées sont celles les plus susceptibles d'être un paquet fraîchement compromis. C'est la seule couche activée par défaut.

  • Refuser les paquets plus récents que le seuil — l'interrupteur principal. Activé par défaut.
  • Âge minimum — le seuil en jours (sélecteur, 0–90). Par défaut : 2 jours.
  • Paquets exemptés — une liste d'autorisation au format npm:axios (un écosystème) ou simplement axios (tous les écosystèmes), insensible à la casse. Cliquez sur Ajouter une entrée pour ajouter une ligne.

Les références flottantes (pkg@latest, plages semver) ne sont jamais bloquées catégoriquement : le proxy réécrit les métadonnées du registre pour que les versions trop récentes n'existent tout simplement pas du point de vue de l'agent, et le gestionnaire de paquets se résout à la version autorisée la plus récente. Seules les références épinglées à des versions trop récentes reçoivent le 451, indiquant l'âge du paquet et le minimum requis.

Remarque : Maven, NuGet et les modules Go ne portent pas d'horodatage par version dans leurs réponses de métadonnées standard, de sorte que le filtrage par âge ne bloque actuellement pas ces trois écosystèmes. npm, PyPI, Cargo, RubyGems et Packagist sont entièrement couverts (pour PyPI, Bromure recherche les dates de publication à la demande via l'API JSON de PyPI).

Contrôle de vulnérabilité OSV

Lorsque Rechercher les paquets sur api.osv.dev (gratuit, aucune clé requise) est activé, l'écosystème, le paquet et la version de chaque artefact téléchargé sont vérifiés dans la base de données OSV — une agrégation gratuite de la GitHub Advisory Database, des avis PyPI, de la base de données de vulnérabilités de Go, de RubySec et d'autres. Tout avis au niveau ou au-dessus du seuil Bloquer à partir de la gravité bloque le téléchargement avec un 451.

  • Désactivé par défaut — comme le note le volet, une CVE de faible gravité dans un sous-paquet transitif ne devrait pas interrompre un flux de travail.
  • Bloquer à partir de la gravité propose Faible et au-dessus, Moyenne et au-dessus, Élevée et au-dessus (la valeur par défaut) ou Critique uniquement.
  • Couvre les huit écosystèmes ; les contrôles s'exécutent au moment du téléchargement de l'artefact, pas lors des récupérations de métadonnées.

Filtrage de paquets

Le bouton radio Filtrage de paquets sélectionne un fournisseur de réputation : Aucun, socket.dev ou Delpi. Les deux fournisseurs fonctionnent différemment — socket.dev est une recherche préalable que le proxy consulte avant de laisser passer une récupération, tandis que Delpi remplace purement et simplement le registre npm — ils sont donc mutuellement exclusifs. Les clés d'API stockées sont conservées lorsque vous changez, de sorte que basculer entre les fournisseurs n'est pas destructeur.

socket.dev

Avec socket.dev sélectionné, collez un jeton d'API dans Clé d'API (le lien Obtenir une clé d'API ouvre la page des jetons de socket.dev). Les deux interrupteurs ci-dessous restent désactivés tant qu'une clé n'est pas saisie, et une clé vide désactive entièrement socket.dev quels que soient les interrupteurs. La clé est stockée uniquement côté hôte et n'entre jamais dans la VM.

  • Bloquer les paquets compromis (scripts d'installation malveillants, signalés comme malwares, typosquats, télémétrie suspecte) — bloque sur les signaux de risque de chaîne d'approvisionnement en forme d'attaque : indicateurs de malware définitifs à n'importe quelle gravité ; signaux plus bruyants tels que code obfusqué, scripts d'installation, typosquatting ou accès shell uniquement lorsque socket.dev les évalue comme élevés ou critiques (de sorte qu'un paquet avec un postinstall bénin n'est pas bloqué). Désactivé par défaut.
  • Bloquer les paquets avec des CVE connues — bloque sur le compartiment de vulnérabilités de socket.dev au niveau ou au-dessus du Seuil de blocage des CVE (par défaut Élevée et au-dessus ; le sélecteur est désactivé tant que cet interrupteur n'est pas activé). Désactivé par défaut.

Remarque : socket.dev ne prend pas en charge Cargo. Avec le filtrage socket.dev activé, chaque artefact crates.io ne produit aucun verdict et déclenche la mise en attente de paquet non vérifié décrite ci-dessous — en pratique une invite par version de crate. Désactivez socket.dev pour les espaces de travail à forte composante Rust, ou attendez-vous à répondre à des invites.

Delpi

Avec Delpi sélectionné et une clé d'API saisie (le lien Obtenir une clé d'API ouvre landh.tech), le proxy réachemine chaque requête au registre npm — métadonnées, tarballs, audit, tout ce qui est adressé à registry.npmjs.org — vers le registre sécurisé compatible npm de Delpi à depi-npm-proxy.landh.tech, en y attachant votre clé sous forme de jeton Bearer injecté par l'hôte. Delpi sert des paquets pré-validés, donc au lieu d'une recherche par paquet, c'est tout le registre qui est remplacé. Les autres couches (filtrage par âge, OSV, suppression de scripts) s'appliquent toujours par-dessus : Delpi remplace socket.dev, pas la politique locale.

Tant que le champ de clé est vide, un avertissement orange affiche Saisissez une clé d'API — Delpi reste désactivé sans elle. Si Delpi rejette la clé, l'installation npm échoue avec une erreur Bromure claire, le rejet est enregistré dans le journal de sécurité et une alerte unique est déclenchée. Delpi n'affecte que npm ; les autres écosystèmes ne sont pas touchés.

Scripts d'installation

Supprimer preinstall / install / postinstall / prepare des tarballs npm à la volée retire les hooks que les paquets npm malveillants utilisent pour exécuter du code au moment de l'installation. Bromure réécrit le tarball en vol — retire les clés de script du package.json du paquet, recalcule la somme de contrôle du tar, recompresse en gzip — et efface les hachages d'intégrité des métadonnées du registre afin que la propre vérification de npm réussisse toujours pour les installations non épinglées. Les suppressions sont journalisées en orange dans le journal de sécurité ; en cas d'échec d'analyse, le tarball d'origine passe intact (cette couche échoue en mode ouvert plutôt que de casser une installation bien formée).

Les compilateurs de liaisons qui ont réellement besoin de scripts d'installation (better-sqlite3, node-canvas, …) vont dans Autoriser les scripts d'installation pour, au format npm:better-sqlite3.

Désactivé par défaut ; npm uniquement (les sdists PyPI ne sont jamais réécrits — setup.py est du code arbitraire).

Installations épinglées par fichier de verrouillage

Les installations épinglées par fichier de verrouillage (npm ci, pip --require-hashes) épinglent les hachages d'intégrité des tarballs dans le fichier de verrouillage, de sorte que Bromure ne peut pas réécrire ces tarballs sans casser la vérification. Par défaut, ils passent sans modification et silencieusement.

Activez Demander avant de laisser passer les tarballs épinglés par fichier de verrouillage sans modification (npm ci, pip --require-hashes) pour qu'on vous le demande à la place : la première récupération épinglée par fichier de verrouillage d'un lot fait apparaître une boîte de dialogue hôte intitulée Pass through npm ci (lockfile-pinned install) from workspace "<name>"? avec les choix Autoriser pendant 15 minutes, Autoriser une fois, Autoriser pour le reste de la session et Ne pas autoriser. Tout le lot suit la décision (les récupérations concurrentes fusionnent sur une seule invite) ; le refus bloque avec un 451 et est mémorisé pendant 60 secondes.

Remarque : Bien que l'étiquette mentionne pip --require-hashes, la détection n'est actuellement implémentée que pour le npm ci de npm — les installations pip épinglées par hachage ne déclenchent pas l'invite.

Lorsqu'une source de réputation est inaccessible

Si une source de réputation activée (OSV ou socket.dev) ne peut pas produire de verdict — réseau hors service, débit limité, échec d'authentification, écosystème non pris en charge — Bromure échoue en mode fermé plutôt que d'autoriser silencieusement. Le téléchargement est mis en attente et une boîte de dialogue demande, par paquet et par version, s'il faut accepter le paquet non vérifié ; le refus bloque avec un 451. Les approbations sont indexées par package@version, de sorte qu'une seule réponse ne peut pas couvrir un graphe de dépendances entier.

Il s'agit d'une protection délibérée contre un attaquant induisant des limitations de débit pour faire passer des paquets en douce. Cela signifie également qu'un travail entièrement hors ligne avec OSV ou socket.dev activé demandera une invite pour chaque paquet non mis en cache — désactivez ces couches pour une utilisation hors ligne. Dans les sessions SSH/CLI sans interface, la même question est posée à l'intérieur du tmux de l'espace de travail ; aucune réponse signifie refus.

Référence des paramètres

ParamètreTypePar défaut
Refuser les paquets plus récents que le seuilInterrupteurActivé
Âge minimumSélecteur, 0–90 jours2 jours
Paquets exemptésListe (npm:axios ou axios)Vide
Rechercher les paquets sur api.osv.dev (gratuit, aucune clé requise)InterrupteurDésactivé
Bloquer à partir de la gravité (OSV)Sélecteur : Faible / Moyenne / Élevée et au-dessus, Critique uniquementÉlevée et au-dessus
Filtrage de paquetsRadio : Aucun / socket.dev / DelpiAucun
Clé d'API (socket.dev)Champ sécuriséVide
Bloquer les paquets compromisInterrupteur (nécessite une clé socket.dev)Désactivé
Bloquer les paquets avec des CVE connuesInterrupteur (nécessite une clé socket.dev)Désactivé
Seuil de blocage des CVESélecteur (activé avec l'interrupteur CVE)Élevée et au-dessus
Clé d'API (Delpi)Champ sécuriséVide (Delpi reste désactivé sans elle)
Supprimer preinstall / install / postinstall / prepare des tarballs npm à la voléeInterrupteurDésactivé
Autoriser les scripts d'installation pourListe (npm:better-sqlite3)Vide
Demander avant de laisser passer les tarballs épinglés par fichier de verrouillage sans modificationInterrupteurDésactivé

Les clés d'API saisies ici résident dans le profile.json de l'espace de travail sur l'hôte (jamais dans la VM) ; tous les appels de réputation proviennent du proxy hôte. Pour le journal de sécurité, les détails d'interception par écosystème et l'alarme de détection de compromission qui accompagne ces politiques, consultez le chapitre sur la protection de la chaîne d'approvisionnement.