Construire un workflow (schéma JSON)
Un workflow TechWatchAlert est un graphe d’automatisation : un déclencheur réagit à un événement (nouvelle CVE, fin de vie qui approche, certificat qui expire…), des conditions filtrent, et des actions notifient ou agissent. Ce graphe est décrit par un objet JSON que vous manipulez via l’éditeur visuel, l’assistant Vigie, ou l’import/export de workflow.
Structure générale
Section intitulée « Structure générale »Le graphe (workflow.graph) a exactement deux clés :
{ "nodes": [ /* les tuiles */ ], "edges": [ /* les connexions entre tuiles */ ]}Une tuile (node)
Section intitulée « Une tuile (node) »{ "id": "c1", "type": "condition.cvss", "params": { "op": "gte", "value": 9 }, "position": { "x": 320, "y": 140 }}| Champ | Type | Description |
|---|---|---|
id | string | Identifiant unique dans le graphe (libre : trigger, c1, a1…). |
type | string | Type de tuile (voir le catalogue). |
params | object | Paramètres de la tuile (selon son type). {} si aucun. |
position | object (optionnel) | Coordonnées { x, y } dans le canevas. Omettez-le : l’éditeur dispose automatiquement les tuiles. |
Une connexion (edge)
Section intitulée « Une connexion (edge) »{ "id": "e1", "source": "trigger", "target": "c1", "sourceHandle": "out" }| Champ | Type | Description |
|---|---|---|
source | string | id de la tuile de départ. |
target | string | id de la tuile d’arrivée. |
sourceHandle | string | Sortie utilisée sur la tuile de départ : out (déclencheurs et actions) ou true / false (conditions). Défaut : out. |
id | string (optionnel) | Identifiant de la connexion. |
Règles de validation
Section intitulée « Règles de validation »Un graphe est refusé (avec un message explicite) s’il enfreint l’une de ces règles :
- Un seul déclencheur par workflow, et exactement un (
trigger.*). - Un déclencheur ne peut pas avoir d’entrée (aucune connexion ne pointe vers lui).
- Les conditions ont deux sorties :
trueetfalse. LesourceHandled’une connexion partant d’une condition doit êtretrueoufalse. - Les déclencheurs et les actions ont une seule sortie :
out. - Le graphe est acyclique (DAG) — aucune boucle.
- 30 tuiles maximum (
MAX_NODES), profondeur 20 maximum depuis le déclencheur. idde tuile unique ; toute connexion référence des tuiles existantes.- Les tuiles non reliées au déclencheur sont ignorées à l’exécution (tolérées à l’enregistrement pour ne pas bloquer un brouillon).
- 10 workflows maximum par projet.
Catalogue des tuiles
Section intitulée « Catalogue des tuiles »Le registre complet est aussi servi par l’API interne (GET /projects/{id}/workflows/node-types) pour générer la palette de l’éditeur.
Déclencheurs (trigger.*)
Section intitulée « Déclencheurs (trigger.*) »Un déclencheur réagit à un événement. Le contexte (CVE, EOL ou certificat) détermine quelles conditions ont un sens en aval. Aucun n’a de paramètre.
| Type | Événement | Contexte | Déclenché quand… |
|---|---|---|---|
trigger.cve_new_match | cve.new_match | CVE | une nouvelle CVE correspond à votre stack surveillée. |
trigger.cve_updated | cve.updated | CVE | une CVE suivie est mise à jour (score, etc.). |
trigger.cve_poc_published | cve.poc_published | CVE | un PoC public apparaît pour une CVE suivie. |
trigger.cve_kev_added | cve.kev_added | CVE | une CVE suivie entre au catalogue KEV de la CISA. |
trigger.eol_approaching | eol.approaching | EOL | la fin de vie d’un produit suivi approche. |
trigger.eol_support_ending | eol.support_ending | EOL | la fin de support actif approche. |
trigger.eol_new_release | eol.new_release | EOL | une nouvelle version d’un produit suivi sort. |
trigger.url_cert_expiring | url.cert_expiring | Certificat | le certificat HTTPS d’une URL surveillée expire bientôt. |
Conditions (condition.*)
Section intitulée « Conditions (condition.*) »Chaque condition a deux sorties (true / false). Une condition d’une autre famille que le déclencheur (ex. condition CVE après un déclencheur EOL) est sans effet utile.
| Type | Contexte | Paramètres |
|---|---|---|
condition.severity | CVE | op ∈ gte | eq | in ; value (une sévérité) pour gte/eq, values (liste) pour in. |
condition.cvss | CVE | op ∈ gt | gte | lt | lte ; value nombre 0 → 10. |
condition.epss | CVE | op ∈ gt | gte | lt | lte ; value nombre 0 → 1. |
condition.has_poc | CVE | (aucun) — vrai si un PoC public existe. |
condition.is_kev | CVE | (aucun) — vrai si la CVE est au catalogue KEV. |
condition.product_name | CVE | op ∈ contains | starts_with | ends_with | equals ; value texte (≤ 100). |
condition.vendor_name | CVE | idem product_name, sur l’éditeur. |
condition.match_type | CVE | value ∈ vendor | product | keyword (comment la CVE a matché votre stack). |
condition.case_status | CVE | op ∈ eq | ne ; value ∈ statut de suivi ou NONE. |
condition.has_tag | CVE | tag_id (UUID d’un tag de l’organisation). |
condition.eol_days_remaining | EOL | op (numérique) ; value jours −3650 → 3650. |
condition.eol_is_past | EOL | (aucun) — vrai si la date de fin de vie est dépassée. |
condition.eol_product_name | EOL | op (texte) ; value texte (≤ 100). |
condition.cert_days_remaining | Certificat | op (numérique) ; value jours −3650 → 3650. |
condition.cert_is_expired | Certificat | (aucun) — vrai si le certificat est expiré. |
condition.url_contains | Certificat | op (texte) ; value texte (≤ 100). |
Sévérités : CRITICAL, HIGH, MEDIUM, LOW, NONE, UNKNOWN.
Statuts de suivi : PENDING, ANALYZING, FIXING, ACCEPTED, RESOLVED, NOT_APPLICABLE.
Actions (action.*)
Section intitulée « Actions (action.*) »Les actions s’exécutent quand le flux les atteint. Elles ont une sortie out et peuvent s’enchaîner.
| Type | Paramètres | Effet |
|---|---|---|
action.notify_inapp | (aucun) | Notification dans l’application. |
action.send_email | recipients (optionnel) : liste d’IDs membres ; vide = tous les membres concernés. | E-mail. |
action.fire_webhooks | webhook_id (optionnel) : un webhook précis, vide = tous les webhooks actifs ; format ∈ json | slack | discord. | Webhook sortant (HMAC). |
action.create_case | status ∈ statut de suivi (requis). | Crée une fiche d’alerte (suivi). Nécessaire pour qu’une alerte apparaisse dans « Alertes » et que l’e-mail contienne le bouton « Voir l’alerte ». |
action.ai_enrich | instruction (optionnel, ≤ 500) : consigne pour l’analyse (ex. « focus remédiation Debian »). | Génère une analyse IA (résumé, risque, remédiation) à partir des seules données techniques publiques ; le résultat est mis à disposition des actions suivantes (e-mail, webhook, notification). Aucune donnée personnelle n’est envoyée au modèle. |
action.add_tag | tag_id (UUID, requis). | Ajoute un tag à la CVE dans le projet (auto-classement). |
Construire un workflow, de A à Z
Section intitulée « Construire un workflow, de A à Z »1. Le minimum : un déclencheur seul
Section intitulée « 1. Le minimum : un déclencheur seul »Valide (un workflow doit avoir exactement un déclencheur), mais n’agit pas.
{ "nodes": [ { "id": "trigger", "type": "trigger.cve_new_match", "params": {} } ], "edges": []}2. CVE critique → Slack
Section intitulée « 2. CVE critique → Slack »« Quand une nouvelle CVE touche ma stack avec un CVSS ≥ 9, notifie Slack. »
{ "nodes": [ { "id": "trigger", "type": "trigger.cve_new_match", "params": {} }, { "id": "c1", "type": "condition.cvss", "params": { "op": "gte", "value": 9 } }, { "id": "a1", "type": "action.fire_webhooks", "params": { "format": "slack" } } ], "edges": [ { "id": "e1", "source": "trigger", "target": "c1", "sourceHandle": "out" }, { "id": "e2", "source": "c1", "target": "a1", "sourceHandle": "true" } ]}La connexion c1 → a1 utilise sourceHandle: "true" : l’action ne se déclenche que si la condition est vraie.
3. Branche true / false
Section intitulée « 3. Branche true / false »« KEV → fiche d’alerte + e-mail ; sinon → notification in-app simple. »
{ "nodes": [ { "id": "trigger", "type": "trigger.cve_new_match", "params": {} }, { "id": "kev", "type": "condition.is_kev", "params": {} }, { "id": "case", "type": "action.create_case", "params": { "status": "PENDING" } }, { "id": "mail", "type": "action.send_email", "params": {} }, { "id": "inapp", "type": "action.notify_inapp", "params": {} } ], "edges": [ { "id": "e1", "source": "trigger", "target": "kev", "sourceHandle": "out" }, { "id": "e2", "source": "kev", "target": "case", "sourceHandle": "true" }, { "id": "e3", "source": "case", "target": "mail", "sourceHandle": "out" }, { "id": "e4", "source": "kev", "target": "inapp", "sourceHandle": "false" } ]}Les actions s’enchaînent (case → mail via out). La branche false mène à une notification légère.
4. Analyse IA puis e-mail enrichi
Section intitulée « 4. Analyse IA puis e-mail enrichi »{ "nodes": [ { "id": "trigger", "type": "trigger.cve_kev_added", "params": {} }, { "id": "ai", "type": "action.ai_enrich", "params": { "instruction": "Priorise la remédiation." } }, { "id": "mail", "type": "action.send_email", "params": {} } ], "edges": [ { "id": "e1", "source": "trigger", "target": "ai", "sourceHandle": "out" }, { "id": "e2", "source": "ai", "target": "mail", "sourceHandle": "out" } ]}ai_enrich est placé avant l’e-mail : son analyse est incluse dans le message.
5. Fin de vie qui approche → e-mail
Section intitulée « 5. Fin de vie qui approche → e-mail »{ "nodes": [ { "id": "trigger", "type": "trigger.eol_approaching", "params": {} }, { "id": "c1", "type": "condition.eol_days_remaining", "params": { "op": "lte", "value": 90 } }, { "id": "a1", "type": "action.send_email", "params": {} } ], "edges": [ { "id": "e1", "source": "trigger", "target": "c1", "sourceHandle": "out" }, { "id": "e2", "source": "c1", "target": "a1", "sourceHandle": "true" } ]}Erreurs de validation courantes
Section intitulée « Erreurs de validation courantes »| Message | Cause |
|---|---|
Le workflow doit contenir exactement un déclencheur | Zéro ou plusieurs tuiles trigger.*. |
Sortie '…' invalide pour … | sourceHandle incohérent (ex. out sur une condition, ou true sur une action). |
Le workflow contient une boucle | Le graphe n’est pas acyclique. |
Un déclencheur ne peut pas avoir d'entrée | Une connexion pointe vers le trigger.*. |
Paramètre requis '…' manquant pour … | Paramètre obligatoire absent (ex. value sur condition.cvss). |
Valeur '…' invalide pour … | Valeur hors de la liste autorisée (sévérité, statut, opérateur…). |
Valeur hors bornes pour … | Nombre hors plage (CVSS 0–10, EPSS 0–1, jours −3650–3650). |
Trop de tuiles (max 30) / Workflow trop profond (max 20) | Graphe trop grand. |
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Le plus simple : décrivez votre besoin à Vigie (assistant IA) sur la page Workflows — elle génère le graphe, que vous approuvez.
- L’éditeur visuel produit et relit ce même JSON ; l’export d’un workflow donne un fichier
{ name, description, graph }réimportable. - Voir aussi : Workflows (API).