Retour aux mises à jour
New releaseJul 14, 2026

threatcl v0.6.1

Documenter vos modèles de menace avec HCL

Partager

threatcl

Modélisation des menaces avec HCL

Qu'est-il arrivé à hcltm ?

hcltm a été renommé en threatcl. Bienvenue !

Aperçu

[!TIP] Vous voulez lire la nouvelle documentation ? Rendez-vous sur threatcl.dev

Il existe de nombreuses façons différentes de documenter un modèle de menaces. D'un simple fichier texte à des documents Word plus approfondis, en passant par des modèles de menaces entièrement instrumentés dans une solution centralisée. Deux des attributs les plus précieux d'un modèle de menaces sont la capacité à documenter clairement les menaces et à susciter des changements significatifs.

threatcl vise à fournir une approche DevOps-first pour documenter un modèle de menaces système en se concentrant sur les objectifs suivants :

  • Format de fichier texte simple
  • Expérience utilisateur simple basée sur la CLI
  • Intégration dans les systèmes de contrôle de version (VCS)

Ce dépôt est le domicile du logiciel CLI threatcl. La spécification threatcl est basée sur HCL2, le langage de configuration de HashiCorp, qui vise à être "agréable à lire et à écrire pour les humains, et une variante basée sur JSON plus facile à générer et à analyser pour les machines". La spécification threatcl se trouve sur github.com/threatcl/spec. La combinaison du logiciel CLI threatcl et de la spécification threatcl permet aux praticiens de définir un modèle de menaces système en HCL, par exemple :```hcl threatmodel "Tower of London" { description = "A historic castle" author = "@xntrik"

attributes { new_initiative = "true" internet_facing = "true" initiative_size = "Small" }

information_asset "crown jewels" { description = "including the imperial state crown" information_classification = "Confidential" }

usecase { description = "The Queen can fetch the crown" }

third_party_dependency "community watch" { description = "The community watch helps guard the premise" uptime_dependency = "degraded" }

threat "Crown theft" { description = "Someone who isn't the Queen steals the crown" impacts = ["Confidentiality"]

control "Guards" {
  description = "Trained guards patrol tower"
  risk_reduction = 75
}

}

data_flow_diagram_v2 "dfd name" { // ... see below for more information }

}

Voir [Diagramme de flux de données](#data-flow-diagram) pour plus d'informations sur la façon de construire des diagrammes de flux de données qui peuvent être convertis automatiquement en PNG.

Pour voir un exemple de la façon de référencer des bibliothèques de contrôles prédéfinies pour [OWASP Proactive Controls](https://owasp.org/www-project-proactive-controls/) et [AWS Security Checklist](https://d1.awsstatic.com/whitepapers/Security/AWS_Security_Checklist.pdf), consultez [examples/tm3.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm3.hcl). Nous avons également les [contrôles MITRE ATT&CK](https://attack.mitre.org/mitigations/enterprise/) [ici](https://github.com/threatcl/threatcl/blob/HEAD/examples/MITRE_ATTACK_controls.hcl).

Vous pouvez également inclure un modèle de menace externe dans le vôtre, pour référencer et utiliser toutes ses informations. Vous pouvez voir [examples/including-example/corp-app.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/including-example/corp-app.hcl) comme exemple.

Pour voir une description complète de la spécification, voir [ici](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl) ou exécutez :```bash
threatcl generate boilerplate

threatcl traitera également les fichiers JSON, mais la seule mise en garde est que les modules d'importation et les variables ne fonctionneront pas. Vous pouvez voir examples/tm1.json comme exemple.

Pourquoi HCL ?

HCL est le langage de configuration principal utilisé dans les produits de HashiCorp, en particulier Terraform, leur logiciel open-source Infrastructure-as-Code. J'ai travaillé chez HashiCorp pendant un certain temps et le langage m'a vraiment séduit. De plus, si les ingénieurs DevOps et logiciels utilisent ce langage, alors simplifier la façon dont ils documentent les modèles de menace s'aligne sur les objectifs de threatcl.

Vous pouvez utiliser threatcl avec JSON, mais vous perdez certaines fonctionnalités. Pour plus d'informations, consultez le dossier examples/.

Pourquoi ne pas simplement les documenter en MD ?

J'ai aimé l'idée d'utiliser un format pouvant être manipulé par programmation.

Remerciements et Références

L'une des fonctionnalités de threatcl est la génération automatique de diagrammes de flux de données à partir de fichiers HCL. Cela utilise le package go-dfd de Marqeta et Blake Hitchcock. Assurez-vous de consulter leur article de blog sur Threat models at the speed of DevOps.

De plus, je tiens à remercier Jamie Finnigan et Talha Tariq de HashiCorp de m'avoir permis de continuer à travailler sur cet outil open-source même après avoir quitté HashiCorp.

Merci également à l'équipe d'IriusRisk pour la spécification OpenThreatModel.

threatcl cli

Installation

Téléchargez la dernière version depuis releases et déplacez le binaire threatcl dans votre PATH.

Installer avec Homebrew

Installez threatcl avec Homebrew — la formule se trouve dans homebrew-core :```bash brew install threatcl

## Exécuter avec Docker```bash
docker run --rm -it ghcr.io/threatcl/threatcl:latest

Vérification des versions (provenance de construction)

Chaque version étiquetée est livrée avec la provenance de construction SLSA — des attestations sans clé signées par Sigstore, générées par le pipeline de publication GitHub Actions (GitHub OIDC → Fulcio, pas de clés de signature). Vous pouvez vérifier qu'un binaire ou l'image conteneur a été authentiquement construit à partir du workflow de publication de ce dépôt en utilisant le GitHub CLI (gh attestation verify — aucun outil supplémentaire ni clé de confiance à gérer).

Vérifiez une archive téléchargée (ou le fichier SHA256SUMS) :```bash gh attestation verify threatcl_.tar.gz --repo threatcl/threatcl

Vérifiez l'image du conteneur (le tag est résolu automatiquement en son digest) :```bash
gh attestation verify oci://ghcr.io/threatcl/threatcl:<version> --repo threatcl/threatcl

Pour épingler l'image exacte que vous exécutez, résolvez vous-même le digest et vérifiez (et tirez) par digest :```bash digest=$(docker buildx imagetools inspect ghcr.io/threatcl/threatcl: --format '{{ .Manifest.Digest }}') gh attestation verify oci://ghcr.io/threatcl/threatcl@${digest} --repo threatcl/threatcl

Voir [docs/SLSA.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/SLSA.md) pour l'ensemble de la posture de la chaîne d'approvisionnement.

## Exécution avec GitHub Actions

`threatcl` peut être intégré directement dans vos dépôts GitHub avec https://github.com/threatcl/threatcl-action. C'est l'une des méthodes idéales pour gérer vos modèles de menace et aide à atteindre l'objectif d'intégration dans vos systèmes de contrôle de version.

## Compilation à partir des sources

1. Clonez ce dépôt.
2. Placez-vous dans le répertoire `threatcl`
3. `make bootstrap`
4. `make build`

Pour plus d'aide sur la contribution à `threatcl`, veuillez consulter le [CHANGELOG.md](https://github.com/threatcl/threatcl/blob/HEAD/CHANGELOG.md).

## Utilisation

Pour obtenir de l'aide sur les sous-commandes, utilisez l'option `-h`.```bash
$ threatcl
Usage: threatcl [--version] [--help] <command> [<args>]

Available commands are:
    cloud        Interact with ThreatCL Cloud services
    dashboard    Generate markdown files from existing HCL threatmodel file(s)
    dfd          Generate Data Flow Diagram PNG or DOT files from existing HCL threatmodel file(s)
    export       Export threat models into other formats
    generate     Generate an HCL Threat Model
    list         List Threatmodels found in HCL file(s)
    mcp          Model Context Protocol (MCP) server for threatcl
    mermaid      Output raw mermaid source from 'mermaid' blocks in existing HCL threatmodel file(s)
    query        Execute GraphQL queries against threat model data
    server       Start a GraphQL API server for threat models
    terraform    Parse output from 'terraform show -json'
    validate     Validate existing HCL Threatmodel file(s)
    view         View existing HCL Threatmodel file(s)

(Optionnel) Fichier de configuration

La plupart des commandes threatcl disposent d'un indicateur -config qui vous permet de spécifier un fichier config.hcl. Le HCL dans ce fichier peut être utilisé pour remplacer certains des attributs par défaut de threatcl. Ceux-ci sont listés ci-dessous :

  • Tailles d'initiative - valeurs par défaut : "Undefined", "Small", "Medium", "Large"
  • Taille d'initiative par défaut - valeur par défaut : "Undefined
  • Classifications des informations - valeurs par défaut : "Restricted", "Confidential", "Public"
  • Classification des informations par défaut - valeur par défaut : "Confidential"
  • Types d'impact - valeurs par défaut : "Confidentiality", "Integrity", "Availability"
  • Éléments STRIDE - valeurs par défaut : "Spoofing", "Tampering", "Info Disclosure", "Denial Of Service", "Elevation Of Privilege"
  • Classifications de dépendance de disponibilité - valeurs par défaut : "none", "degraded", "hard", "operational"
  • Classification de dépendance de disponibilité par défaut - valeur par défaut : "none"

Par exemple :```hcl initiative_sizes = ["S", "M", "L"] default_initiative_size = "M" info_classifications = ["1", "2"] default_info_classification = "1" impact_types = ["big", "small"] strides = ["S", "T"] uptime_dep_classifications = ["N", "D"] default_uptime_dep_classification = "N"

Si vous modifiez ces attributs, vous devrez penser à fournir le fichier de configuration pour les autres opérations, car cela peut impacter la validation ou la création du tableau de bord.

## Commandes Cloud

Consultez https://threatcl.dev/cloud/overview/ pour en savoir plus sur les sous-commandes `cloud`.

## Lister et Voir

Les commandes `threatcl list` et `threatcl view` peuvent être utilisées pour lister et visualiser les données à partir des fichiers HCL de la spécification `threatcl`.```bash
$ threatcl list examples/*
#  File              Threatmodel      Author
1  examples/tm1.hcl  Tower of London  @xntrik
2  examples/tm1.hcl  Fort Knox        @xntrik
3  examples/tm2.hcl  Modelly model    @xntrik

Valider

La commande threatcl validate est utilisée pour valider un fichier HCL de spécification threatcl.```bash $ threatcl validate examples/* Validated 3 threatmodels in 3 files

### Invariants

`threatcl validate` peut également appliquer des invariants à l'échelle de l'organisation — des règles vérifiables par machine comme "aucun point de terminaison public ne devrait être non authentifié" ou "toutes les fonctionnalités exposées sur Internet doivent documenter la journalisation d'audit" — contre chaque modèle de menace validé :```bash
$ threatcl validate -invariants=invariants.hcl ./models/
Validated 4 threatmodels in 3 files
Invariant violation [error] 'threats_have_implemented_controls': threat 'Credential theft' in threatmodel 'Payments' (models/payments.hcl): Every threat must have at least one implemented control
Checked 3 invariants against 4 threatmodels: 1 errors, 0 warnings, 1 exemptions

Les invariants résident dans leur propre fichier HCL, ciblent une collection spécifique (menaces, contrôles, processus DFD, flux, ...), et expriment leur condition sous forme d'expression HCL native. Ils prennent en charge les sévérités error/warning et des exemptions par modèle avec justifications. Voir docs/invariants.md.

Export

La commande threatcl export est utilisée pour exporter un modèle de menace (ou plusieurs) threatcl vers la représentation JSON native (par défaut), ou vers la représentation JSON OTM, ou même de retour en hcl (Ce qui est utile pour générer du HCL frais à partir de modèles de menace dynamiques). Vous pouvez également les enregistrer directement dans un fichier avec le flag -output.```bash $ threatcl export -format=otm examples/tm1.hcl [{"assets":[{"description":"including the imperial state crown","id":"crown-jewels","name":"crown jewels","risk":{"availability":0,"confidentiality":0,"integrity":0}}],"mitigations":[{"attributes":{"implementation_notes":"They are trained to be guards as well","implemented":true},"description":"Lots of guards patrol the area","id":"lots-of-guards","name":"Lots of Guards","riskReduction":80}],"otmVersion":"0.2.0","project":{"attributes":{"initiative_size":"Small","internet_facing":true,"network_segment":"dmz","new_initiative":true},"description":"A historic castle","id":"tower-of-london","name":"Tower of London","owner":"@xntrik"},"threats":[{"categories":["Confidentiality"],"description":"Someone who isn't the Queen steals the crown","id":"threat-1","name":"Threat 1","risk":{"impact":0,"likelihood":null}}]},{"assets":[{"description":"Lots of gold","id":"gold","name":"Gold","risk":{"availability":0,"confidentiality":0,"integrity":0}}],"mitigations":[{"attributes":{"implemented":true},"description":"A large wall surrounds the fort","id":"big-wall","name":"Big Wall","riskReduction":80}],"otmVersion":"0.2.0","project":{"attributes":{"initiative_size":"Small","internet_facing":true,"new_initiative":false},"description":"A .. fort?","id":"fort-knox","name":"Fort Knox","owner":"@xntrik"},"threats":[{"categories":["Confidentiality"],"description":"Someone steals the gold","id":"threat-1","name":"Threat 1","risk":{"impact":0,"likelihood":null}}]}]

## Generate

La commande `threatcl generate` est utilisée soit pour générer un fichier HCL de spécification `threatcl` générique `boilerplate`, soit pour poser des questions à l'utilisateur de manière interactive puis générer un fichier HCL de spécification `threatcl`.

### Generate Interactive

Voir l'exemple suivant de :```bash
threatcl generate interactive

Générer l'éditeur interactif

Si vous préférez travailler directement dans votre $EDITOR, exécutez :```bash threatcl generate interactive editor

Cela ouvrira votre éditeur avec un modèle de menace HCL minimal. Si vous souhaitez valider le modèle après sa création, utilisez le drapeau `-validate`.

## MCP

La commande `threatcl mcp` expose un serveur [MCP](https://modelcontextprotocol.io/introduction) local afin que vous puissiez interagir avec les fichiers threatcl hcl via un hôte MCP, par exemple des applications IA/LLM telles que [Claude Desktop](https://claude.ai/download), [Cursor](https://www.cursor.com/), ou toute autre application prenant en charge MCP.

La commande prend un seul argument optionnel, `-dir=<path>`, qui permet à des outils MCP supplémentaires d'interagir avec les fichiers situés dans ce chemin. Sans ce paramètre, les outils MCP peuvent interagir avec des chaînes de caractères, mais dépendront d'autres mécanismes au sein de l'hôte MCP pour interagir avec le système de fichiers sous-jacent.

On peut dire que cette fonctionnalité est encore assez bêta pour le moment.

## LSP (Language Server)

La commande `threatcl lsp` exécute un serveur [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) sur stdio, offrant aux éditeurs compatibles LSP des diagnostics en direct, de l'autocomplétion, des infobulles, des symboles de document et un formatage pour les modèles de menace HCL threatcl.

Il est lancé par le client LSP de votre éditeur plutôt que d'être exécuté manuellement. Comme les fichiers threatcl partagent l'extension `.hcl` avec Terraform et d'autres dialectes HCL, le filtrage sur `*.tm.hcl` (ou la limitation du client à votre espace de travail de modèles de menace) évite les conflits avec un serveur de langage Terraform.

Consultez [docs/lsp.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/lsp.md) pour la configuration des éditeurs (Neovim, Helix, VS Code, Zed) et les limitations actuelles.

## Server (GraphQL API)

La commande `threatcl server` démarre un serveur d'API GraphQL qui expose vos modèles de menace via HTTP pour des requêtes programmatiques et l'intégration.

### Basic Usage```bash
# Start the server
$ threatcl server -dir ./examples

# With file watching for auto-reload
$ threatcl server -dir ./examples -watch

# Custom port
$ threatcl server -dir ./examples -port 3000

Naviguez vers http://localhost:8080 pour accéder au GraphQL Playground interactif.

Exemple de requête```graphql

query { stats { totalThreatModels totalThreats implementedControls }

threatModels(filter: { internetFacing: true }) { name threats { description controls { name implemented } } } }

### Documentation

Pour une documentation complète de l'API, une référence de schéma, des requêtes avancées et des exemples d'intégration, consultez :
- **Documentation complète de l'API** : [docs/graphql-api.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/graphql-api.md)
- **Exemples de requêtes** : [examples/graphql-queries.md](https://github.com/threatcl/threatcl/blob/HEAD/examples/graphql-queries.md)

## Requête (GraphQL CLI)

La commande `threatcl query` exécute des requêtes GraphQL directement depuis la ligne de commande sans démarrer de serveur. C'est idéal pour l'automatisation, les pipelines CI/CD et les scripts shell.

### Utilisation de base```bash
# Get statistics
$ threatcl query -dir ./examples -query '{ stats { totalThreats } }'

# Query from file
$ threatcl query -dir ./examples -file queries/get-stats.graphql

# Use in scripts
$ THREATS=$(threatcl query -dir ./examples \
    -query '{ stats { totalThreats } }' \
    -output compact | jq -r '.data.stats.totalThreats')
$ echo "Found $THREATS threats"

Formats de sortie

  • pretty (par défaut) : JSON formaté avec indentation
  • json : Identique à pretty
  • compact : JSON sur une seule ligne pour les scripts

Requête avec variables```bash

$ threatcl query -dir ./examples
-query 'query($author: String) { threatModels(filter: {author: $author}) { name } }'
-vars '{"author": "John Doe"}'

### Exemple CI/CD```bash
#!/bin/bash
# Check if all controls are implemented before deployment

UNIMPLEMENTED=$(threatcl query -dir ./threatmodels \
  -query '{ stats { totalControls implementedControls } }' \
  -output compact | jq -r '.data.stats.totalControls - .data.stats.implementedControls')

if [ "$UNIMPLEMENTED" -gt 0 ]; then
  echo "ERROR: $UNIMPLEMENTED controls are not yet implemented"
  exit 1
fi

echo "All controls implemented, proceeding with deployment"

Consultez docs/graphql-api.md pour les requêtes disponibles et le schéma GraphQL.

Tableau de bord

La commande threatcl dashboard prend des fichiers HCL de spécification threatcl et génère un certain nombre de fichiers markdown et png, en les déposant dans un dossier sélectionné.```bash $ threatcl dashboard -overwrite -outdir=dashboard-example examples/* Created the 'dashboard-example' directory Writing dashboard markdown files to 'dashboard-example' and overwriting existing files Successfully wrote to 'dashboard-example/tm1-toweroflondon.md' Successfully wrote to 'dashboard-example/tm1-fortknox.md' Successfully wrote to 'dashboard-example/tm2-modellymodel.png' Successfully wrote to 'dashboard-example/tm2-modellymodel.md' Successfully wrote to 'dashboard-example/dashboard.md'

### Modèles Markdown personnalisés

La commande `threatcl dashboard` peut également accepter des flags facultatifs pour spécifier des modèles personnalisés (conformément au [text/template](https://pkg.go.dev/text/template) de Golang).

Pour spécifier un fichier de modèle de tableau de bord, utilisez le flag `-dashboard-template`. Pour un exemple, consultez [dashboard-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/dashboard-template.tpl).

Pour spécifier un fichier de modèle de threatmodel, utilisez le flag `-threatmodel-template`. Pour un exemple, consultez [threatmodel-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/threatmodel-template.tpl).

### Nom de fichier personnalisé pour le fichier d'index du tableau de bord

La commande `threatcl dashboard` peut également accepter un flag facultatif pour spécifier un nom de fichier pour le fichier de tableau de bord généré « index ». Par défaut, ce fichier est `dashboard.md`. Utilisez le flag `-dashboard-filename` sans extension pour modifier ce nom de fichier.

## Diagramme de flux de données

Conformément à la [spec](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl), un `threatmodel` peut inclure des blocs `data_flow_diagram_v2`. Un exemple de DFD simple est disponible [ici](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm2.hcl). L'ancien bloc à usage unique `data_flow_diagram` sera déprécié à un moment donné, il est donc préférable d'utiliser les blocs nommés `data_flow_diagram_v2`, ce qui permet d'avoir plusieurs DFD associés.

La commande `threatcl dfd` prend les fichiers HCL de spec `threatcl`, génère un certain nombre de fichiers png et les place dans un dossier sélectionné.

Si le fichier HCL n'inclut pas un bloc `threatmodel` avec un bloc `data_flow_diagram` ou `data_flow_diagram_v2`, rien n'est produit.

La commande elle-même est très similaire à la commande Dashboard.```bash
$ threatcl dfd -overwrite -outdir testout examples/*
Successfully created 'testout/tm2-modellymodel.png'

Si votre threatmodel n'inclut pas de diagram_link, mais inclut un data_flow_diagram, alors celui-ci sera également rendu lors de l'exécution de threatcl dashboard.

Mermaid

Selon la spécification, un threatmodel peut également inclure des blocs mermaid de forme libre. Contrairement à data_flow_diagram_v2 (que threatcl rend pour vous), un bloc mermaid intègre le source brut mermaid textuellement - mermaid déduit le type de diagramme (séquence, état, organigramme, etc.) à partir de la première ligne du contenu.

La commande threatcl mermaid extrait ce source brut afin qu'il puisse être redirigé vers d'autres outils de rendu. Elle ne rend pas elle-même les images.

Par défaut, le source est affiché sur STDOUT :```bash $ threatcl mermaid examples/tm2.hcl sequenceDiagram User->>App: credentials App->>Auth: verify Auth-->>App: token

Cela permet de le diriger facilement vers un moteur de rendu tel que [mermaid-cli](https://github.com/mermaid-js/mermaid-cli) :```bash
$ threatcl mermaid model.hcl | mmdc -o diagram.svg -i -

S'il y a plusieurs blocs mermaid, sélectionnez-en un avec -index=n, ou écrivez-les tous dans un répertoire avec -outdir (un fichier .mmd par bloc). Vous pouvez également écrire un seul bloc dans un fichier avec -out.```bash $ threatcl mermaid -outdir testout model.hcl Successfully created 'testout/model-mymodelloginsequence.mmd'

## Terraform

La commande `threatcl terraform` peut extraire des ressources de données de la sortie `terraform show -json` [documentation ici](https://www.terraform.io/docs/cli/commands/show.html) des fichiers de plan, ou des fichiers d'état actif, et les convertir en blocs `information_asset` ébauchés pour inclusion dans les fichiers `threatcl`.

Si vous êtes dans un dossier avec un état existant, vous pouvez exécuter la commande suivante :```bash
terraform show -json | threatcl terraform -stdin

Cela produira quelque chose de similaire à ceci :```bash information_asset "aws_rds_cluster default" { description = "cluster_identifier: aurora-cluster-demo, database_name: mydb" information_classification = "" source = "terraform state" } information_asset "aws_s3_bucket example" { description = "bucket: terraform-20211107232017071500000001" information_classification = "" source = "terraform state" }

Vous pouvez également voir une sortie similaire d'un fichier de plan qui n'a pas encore été appliqué avec Terraform en exécutant :```bash
terraform show -json <plan-file> | threatcl terraform -stdin

Si vous souhaitez mettre à jour un fichier de modèle de menace threatcl existant ("threatmodel.hcl"), vous pouvez le faire avec :```bash terraform show -json | threatcl terraform -stdin -add-to-existing=threatmodel.hcl > new-threatmodel.hcl

Avec le flag `-add-to-existing`, vous pouvez également spécifier `-tm-name=<string>` si vous avez besoin de spécifier un modèle de menace particulier du fichier source, s'il y en a plusieurs. Et vous pouvez également appliquer une classification par défaut, avec le flag `-default-classification=Confidential`.

Ces commandes peuvent également prendre un fichier en entrée, auquel cas, omettez le flag `-stdin`.

Les ressources terraform dont `threatcl` a connaissance sont codées en dur dans [pkg/terraform/terraform.go](https://github.com/threatcl/threatcl/blob/HEAD/pkg/terraform/terraform.go). Si vous souhaitez que la commande `threatcl terraform` produise d'autres ressources `information_asset` qui ne s'y trouvent pas, vous pouvez fournir votre propre version de ce json via le flag `-tf-collection=<json file>`.

Catégories