FlowKit

Task Runners n8n : isoler et sécuriser l'exécution du node Code

Publié le 1 août 2026 · 6 min de lecture

Jusqu'à récemment, un node Code n8n s'exécutait directement dans le processus principal de l'instance : un bug ou un script malveillant collé dans un champ pouvait, en théorie, toucher tout ce que ce processus voyait — credentials en mémoire, autres exécutions en cours, ressources système. Depuis n8n 2.0, sorti en avril 2026, ce n'est plus le comportement par défaut : le node Code s'exécute dans un processus Task Runner séparé, isolé de l'instance principale. Ce guide explique comment fonctionne cette architecture, comment la configurer en self-hosted, et ce qui change concrètement pour vos workflows IA.

Ce que change l'isolation par défaut

Sur une instance n8n qui manipule des credentials API, reçoit des webhooks exposés publiquement et exécute du code fourni par plusieurs collaborateurs, le node Code est historiquement le point le plus sensible : c'est le seul endroit où du JavaScript (ou du Python) arbitraire tourne. Avec n8n 2.0, ce code ne s'exécute plus dans le processus principal : il est délégué à un Task Runner, un processus séparé qui n'a par défaut ni accès aux variables d'environnement de l'instance, ni la possibilité d'exécuter des commandes système. C'est un changement « secure by default » assumé par l'équipe n8n, pas une option cachée dans la documentation avancée.

Ce principe n'est pas nouveau en sécurité logicielle : la séparation de privilèges — isoler un composant à risque dans son propre processus, avec ses propres droits, pour limiter les dégâts en cas de compromission — est un modèle décrit dès 2003 par Niels Provos, Markus Friedl et Peter Honeyman dans leur article de référence présenté au 12th USENIX Security Symposium (« Preventing Privilege Escalation » — Google Scholar), qui a notamment popularisé cette approche pour OpenSSH. Les Task Runners appliquent la même logique au node Code : un script buggé ou une dépendance compromise reste cantonné au runner, sans accès direct au reste de l'instance.

L'architecture : runner, broker, requester

Trois composants interagissent :

  • Le task requester — l'instance principale n8n, qui a besoin d'exécuter un node Code et soumet une demande.
  • Le task broker — un serveur intégré à n8n qui reçoit les demandes et les distribue aux runners disponibles via une connexion websocket. Il expose un endpoint de santé (/healthz) sur le port 5679 par défaut, configurable via N8N_RUNNERS_BROKER_PORT.
  • Le task runner — le processus qui exécute réellement le code JavaScript ou Python et renvoie le résultat.

Cette architecture rappelle volontairement celle du mode queue avec Redis : dans les deux cas, l'exécution est déportée hors du processus principal pour gagner en robustesse. La différence, c'est l'objectif — le mode queue vise le débit et la haute disponibilité, les Task Runners visent avant tout l'isolation de sécurité d'un composant précis, le node Code. Les deux mécanismes sont indépendants et se combinent sans conflit sur une même instance.

Mode interne vs mode externe

n8n propose deux façons de faire tourner les runners :

Mode interne

L'instance n8n lance elle-même le runner comme processus enfant et gère son cycle de vie. Le runner partage le même utilisateur système (uid/gid) que le processus principal. C'est le mode le plus simple à activer, mais l'isolation reste partielle : n8n et le runner tournent avec les mêmes droits sur le système de fichiers. La documentation officielle déconseille ce mode en production.

Mode externe

Un launcher dédié — fourni dans l'image officielle n8nio/runners — démarre et supervise le runner dans son propre conteneur, indépendant du processus n8n. C'est le mode recommandé en production : sur un déploiement Docker Compose, cela se traduit par un service sidecar dédié.

services:
  n8n:
    image: n8nio/n8n:2.x
    environment:
      - N8N_RUNNERS_MODE=external
      - N8N_RUNNERS_BROKER_PORT=5679
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
    ports:
      - "5678:5678"

  n8n-runner:
    image: n8nio/runners:latest
    environment:
      - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}

Deux points à ne pas manquer :

  • Le jeton partagé (N8N_RUNNERS_AUTH_TOKEN) doit être identique sur l'instance principale et sur chaque runner : c'est lui qui authentifie la connexion websocket au broker, pour empêcher un processus tiers de s'y connecter.
  • Le port du broker n'écoute que sur localhost par défaut. Avec plusieurs conteneurs Docker Compose, il doit accepter des connexions externes au conteneur n8n principal — un détail qui piège souvent les premiers déploiements en mode externe, avec un runner qui ne parvient jamais à se connecter alors que la configuration semble correcte.

Ce que l'isolation change pour vos modules et vos variables

Deux réglages qui vivaient auparavant sur le processus principal n8n doivent désormais être posés sur le runner :

  • N8N_RUNNERS_STDLIB_ALLOW — équivalent, côté runner, de l'ancien NODE_FUNCTION_ALLOW_BUILTIN : la liste des modules Node.js intégrés autorisés dans le node Code.
  • NODE_FUNCTION_ALLOW_EXTERNAL (ou son équivalent runner selon la version) — pour les modules npm externes, qui doivent aussi être physiquement présents dans le node_modules du conteneur runner, pas seulement dans celui de l'instance principale.

Nous détaillons cette configuration, image Docker personnalisée comprise, dans notre guide sur l'installation de modules npm dans le node Code. Le piège le plus fréquent après une migration vers n8n 2.0 reste le même : poser ces variables sur le service n8n au lieu du service n8n-runner, ce qui laisse le module introuvable sans message d'erreur explicite pointant vers la vraie cause.

Autre conséquence directe de l'isolation : les variables d'environnement de l'instance ne sont plus accessibles depuis un node Code par défaut, même via process.env. Un workflow qui lisait une clé de configuration de cette façon doit être adapté — en général en passant la valeur explicitement en entrée du node, via un node Set en amont.

Migrer une instance existante vers n8n 2.0

Avant de basculer, la démarche recommandée reprend les mêmes réflexes qu'une mise à jour n8n classique, avec une étape spécifique aux runners :

  1. Tester en amont : sur une version antérieure à 2.0, activer manuellement N8N_RUNNERS_ENABLED=true sur un environnement de test pour observer le comportement avant que ce ne soit plus optionnel.
  2. Recenser les Code nodes existants qui lisent des variables d'environnement directement, appellent des modules npm externes, ou dépendent d'un accès système — ce sont les candidats les plus probables à casser après la migration.
  3. Provisionner le sidecar runner (mode externe) dans votre docker-compose.yml avant le passage en 2.0, plutôt que de découvrir l'erreur de connexion au broker en production.
  4. Rejouer les workflows critiques après upgrade, en particulier ceux qui utilisent intensivement le node Code — pipelines de chunking RAG ou logique de scoring personnalisée par exemple.

Pourquoi ça compte particulièrement pour des workflows IA

Les packs qui reposent sur des Code nodes complexes — transformation de payloads avant un appel LLM, calcul de scores de priorité, parsing de réponses structurées — sont exactement le type de workflow où l'isolation des Task Runners change le calcul de risque. Le pipeline d'ingestion documentaire du Pack Assistant RAG (119 €) et les workflows de tri du Pack Inbox IA (79 €) s'exécutent normalement sous n8n 2.0 sans modification, précisément parce qu'ils évitent déjà les modules npm superflus et les accès système directs — la même discipline qui rend une migration vers les Task Runners indolore. Pour une instance qui traite des données sensibles ou réglementées, le Pack Conformité & Audit (149 €) s'appuie sur cette même logique de traçabilité : moins un Code node a de surface d'accès, plus l'audit de ce qu'il fait — et de ce qu'il ne peut pas faire — est simple à documenter.

En résumé

Les Task Runners ne sont plus une fonctionnalité optionnelle à activer : depuis n8n 2.0, c'est le mode d'exécution par défaut du node Code, construit autour de trois composants (requester, broker, runner) et de deux modes de déploiement, dont seul le mode externe est recommandé en production. La bascule demande de déplacer certaines variables d'environnement du processus principal vers le runner, de vérifier l'accessibilité réseau du broker entre conteneurs, et de tester les Code nodes qui dépendaient d'un accès direct au système. Une fois en place, c'est un gain de sécurité qui ne coûte rien en fonctionnalité pour la grande majorité des workflows — y compris tous ceux des packs FlowKit.

FAQ

Questions fréquentes

Les Task Runners sont-ils obligatoires depuis n8n 2.0 ?

Oui. Depuis la version 2.0, sortie en avril 2026, les Task Runners sont activés par défaut et la variable N8N_RUNNERS_ENABLED est dépréciée : elle n'a plus besoin d'être définie manuellement. Exécuter le node Code directement dans le processus principal n8n est désormais un mode déprécié, à éviter sur toute instance qui reçoit encore des mises à jour.

Faut-il configurer les Task Runners sur n8n Cloud ?

Non. Sur n8n Cloud, l'isolation du node Code est gérée en coulisses par n8n : il n'y a ni broker à configurer, ni sidecar à déployer. La configuration décrite dans cet article ne concerne que les instances self-hosted (Docker, VPS, Kubernetes).

Quelle est la différence concrète entre le mode interne et le mode externe ?

En mode interne, n8n lance lui-même le processus runner comme processus enfant, avec le même utilisateur système : pratique pour tester, mais l'isolation reste partielle puisque runner et instance principale partagent les mêmes droits. En mode externe, un composant séparé (le launcher, fourni dans l'image n8nio/runners) démarre et supervise le runner dans son propre conteneur, avec son propre cycle de vie — c'est le mode recommandé en production.

Comment savoir si un Code node plante à cause de l'isolation des Task Runners ?

Le symptôme typique est une erreur qui ne mentionne pas explicitement les runners : module introuvable, variable d'environnement absente dans le node Code, ou timeout sur une exécution auparavant instantanée. Le réflexe est de vérifier les logs du conteneur runner (et non ceux de l'instance principale n8n) et de contrôler que N8N_RUNNERS_STDLIB_ALLOW ou NODE_FUNCTION_ALLOW_EXTERNAL sont bien définis sur le bon processus.

Bundle FlowKit Complet

269 €