Volver a actualizaciones
Nuevo releaseAug 1, 2026

threatcl v0.6.5

Documentando tus Modelos de Amenazas con HCL

Compartir

threatcl

Modelado de Amenazas con HCL

¿Qué pasó con hcltm?

hcltm ha sido renombrado a threatcl. ¡Bienvenido!

Resumen

[!TIP] ¿Quieres leer la nueva documentación? Dirígete a threatcl.dev

Hay muchas formas diferentes de documentar un modelo de amenazas. Desde un archivo de texto simple, hasta documentos de Word más detallados, hasta modelos de amenazas completamente instrumentados en una solución centralizada. Dos de los atributos más valiosos de un modelo de amenazas son poder documentar claramente las amenazas y poder impulsar cambios valiosos.

threatcl tiene como objetivo proporcionar un enfoque DevOps-first para documentar un modelo de amenazas del sistema centrándose en los siguientes objetivos:

  • Formato de archivo de texto simple
  • Experiencia de usuario simple basada en CLI
  • Integración en sistemas de control de versiones (VCS)

Este repositorio es el hogar del software CLI threatcl. La especificación de threatcl se basa en HCL2, el Lenguaje de Configuración de HashiCorp, que tiene como objetivo ser 'agradable de leer y escribir para humanos, y una variante basada en JSON que es más fácil para que las máquinas generen y analicen'. La especificación de threatcl se encuentra en github.com/threatcl/spec. La combinación del software CLI threatcl y la especificación threatcl permite a los profesionales definir un modelo de amenazas del sistema en HCL, por ejemplo:```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 }

}

Consulte el [Diagrama de flujo de datos](#data-flow-diagram) para obtener más información sobre cómo construir diagramas de flujo de datos que puedan convertirse automáticamente a PNG.

Para ver un ejemplo de cómo hacer referencia a bibliotecas de control predefinidas para los [Controles Proactivos de OWASP](https://owasp.org/www-project-proactive-controls/) y la [Lista de Verificación de Seguridad de AWS](https://d1.awsstatic.com/whitepapers/Security/AWS_Security_Checklist.pdf), consulte [examples/tm3.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm3.hcl). También tenemos los [Controles MITRE ATT&CK](https://attack.mitre.org/mitigations/enterprise/) [aquí](https://github.com/threatcl/threatcl/blob/HEAD/examples/MITRE_ATTACK_controls.hcl).

También puede incluir un modelo de amenazas externo en el suyo propio, para hacer referencia y utilizar toda su información. Puede ver [examples/including-example/corp-app.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/including-example/corp-app.hcl) como un ejemplo.

Para ver una descripción completa de la especificación, consulte [aquí](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl) o ejecute:```bash
threatcl generate boilerplate

threatcl también procesará archivos JSON, pero la única advertencia es que los módulos de importación y las variables no funcionarán. Puedes ver examples/tm1.json como ejemplo.

¿Por qué HCL?

HCL es el lenguaje de configuración principal utilizado en los productos de HashiCorp, en particular Terraform, su software de Infraestructura como Código de código abierto. Trabajé en HashiCorp por un tiempo y el lenguaje realmente me gustó; además, si los ingenieros de DevOps y Software ya usan el lenguaje, simplificar la forma en que documentan los modelos de amenazas está alineado con los objetivos de threatcl.

Puedes usar threatcl con JSON, pero pierdes algunas funcionalidades. Para más información, consulta la carpeta examples/.

¿Por qué no documentarlos simplemente en MD?

Me gustó la idea de usar un formato que pudiera ser manipulado mediante programación.

Agradecimientos y Referencias

Una de las características de threatcl es la generación automática de diagramas de flujo de datos a partir de archivos HCL. Esto aprovecha el paquete go-dfd de Marqeta y Blake Hitchcock. Definitivamente revisa su artículo en el blog sobre Threat models at the speed of DevOps.

Además, me gustaría agradecer a Jamie Finnigan y Talha Tariq de HashiCorp por permitirme seguir trabajando en esta herramienta de código abierto incluso después de haber terminado mi relación con HashiCorp.

También agradezco a la gente de IriusRisk por la especificación OpenThreatModel.

threatcl cli

Instalación

Descarga la última versión desde releases y mueve el binario threatcl a tu PATH.

Instalar con Homebrew

Instala threatcl con Homebrew — la fórmula se encuentra en homebrew-core:```bash brew install threatcl

## Ejecutar con Docker```bash
docker run --rm -it ghcr.io/threatcl/threatcl:latest

Verificación de lanzamientos (procedencia de la compilación)

Cada lanzamiento etiquetado incluye procedencia de compilación SLSA — atestaciones sin claves firmadas por Sigstore, generadas por el pipeline de lanzamiento de GitHub Actions (GitHub OIDC → Fulcio, sin claves de firma). Puede verificar que un binario o la imagen de contenedor se haya compilado genuinamente a partir del flujo de trabajo de lanzamiento de este repositorio usando GitHub CLI (gh attestation verify — sin herramientas adicionales ni claves de confianza que gestionar).

Verifique un archivo descargado (o el archivo SHA256SUMS):```bash gh attestation verify threatcl_.tar.gz --repo threatcl/threatcl

Verifica la imagen del contenedor (la etiqueta se resuelve automáticamente a su digest):```bash
gh attestation verify oci://ghcr.io/threatcl/threatcl:<version> --repo threatcl/threatcl

Para fijar la imagen exacta que ejecutas, resuelve el digest tú mismo y verifica (y pull) por 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

Consulte [docs/SLSA.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/SLSA.md) para conocer la postura completa de la cadena de suministro.

## Ejecutar con GitHub Actions

`threatcl` se puede integrar directamente en tus repositorios de GitHub con https://github.com/threatcl/threatcl-action. Este es uno de los métodos ideales para gestionar tus modelos de amenazas y ayuda a cumplir el objetivo de integrarse en tus sistemas de control de versiones.

## Compilar desde el código fuente

1. Clona este repositorio.
2. Cambia al directorio `threatcl`
3. `make bootstrap`
4. `make build`

Para obtener más ayuda sobre cómo contribuir a `threatcl`, consulta [CHANGELOG.md](https://github.com/threatcl/threatcl/blob/HEAD/CHANGELOG.md).

## Uso

Para obtener ayuda sobre cualquier subcomando, usa el flag `-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)

(Opcional) Archivo de configuración

La mayoría de los comandos de threatcl tienen una bandera -config que permite especificar un archivo config.hcl. El HCL dentro de este archivo puede usarse para sobrescribir algunos de los atributos predeterminados de threatcl. Estos se enumeran a continuación:

  • Tamaños de Iniciativa - por defecto son "Indefinido", "Pequeño", "Mediano", "Grande"
  • Tamaño de Iniciativa Predeterminado - por defecto es "Indefinido
  • Clasificaciones de Información - por defecto son "Restringido", "Confidencial", "Público"
  • Clasificación de Información Predeterminada - por defecto es "Confidencial"
  • Tipos de Impacto - por defecto son "Confidencialidad", "Integridad", "Disponibilidad"
  • Elementos STRIDE - por defecto son "Suplantación", "Alteración", "Divulgación de Información", "Denegación de Servicio", "Elevación de Privilegios"
  • Clasificaciones de Dependencia de Tiempo de Actividad - por defecto son "ninguno", "degradado", "duro", "operacional"
  • Clasificación de Dependencia de Tiempo de Actividad Predeterminada - por defecto es "ninguno"

Por ejemplo:```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 modificas estos atributos, deberás recordar proporcionar el archivo de configuración para otras operaciones, ya que esto puede afectar la validación o la creación del panel de control.

## Comandos de Cloud

Visita https://threatcl.dev/cloud/overview/ para obtener más información sobre los subcomandos `cloud`.

## List y View

Los comandos `threatcl list` y `threatcl view` se pueden usar para listar y ver datos de archivos HCL de especificación `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

Validar

El comando threatcl validate se utiliza para validar un archivo HCL de especificación threatcl.```bash $ threatcl validate examples/* Validated 3 threatmodels in 3 files

### Invariants

`threatcl validate` también puede hacer cumplir invariantes a nivel de organización — reglas verificadas por máquina como "ningún endpoint público debe ser no autenticado" o "todas las funciones expuestas a internet deben documentar el registro de auditoría" — contra cada modelo de amenaza validado:```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

Los invariantes viven en su propio archivo HCL, se dirigen a una colección específica (amenazas, controles, procesos DFD, flujos, ...) y expresan su condición como una expresión HCL nativa. Soportan severidades de error/warning y exenciones por modelo con justificaciones. Consulta docs/invariants.md.

Export

El comando threatcl export se utiliza para exportar un modelo de amenazas (o varios) de threatcl a la representación JSON nativa (por defecto), o a la representación JSON de OTM, o incluso de vuelta a hcl (lo cual es útil para generar HCL nuevo a partir de modelos de amenazas dinámicos). También puedes guardarlos directamente en un archivo con la bandera -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

El comando `threatcl generate` se utiliza para generar un archivo HCL de especificación `threatcl` `boilerplate` genérico, o bien, para preguntar interactivamente al usuario preguntas y luego generar un archivo HCL de especificación `threatcl`.

### Generate Interactive

Vea el siguiente ejemplo de:```bash
threatcl generate interactive

Generar Editor Interactivo

Si prefieres trabajar directamente en tu $EDITOR entonces ejecuta:```bash threatcl generate interactive editor

Esto abrirá tu editor con un modelo de amenazas HCL básico. Si deseas validar el modelo después de crearlo, usa la bandera `-validate`.

## MCP

El comando `threatcl mcp` expone un servidor [MCP](https://modelcontextprotocol.io/introduction) local para que puedas interactuar con archivos HCL de threatcl a través de un host MCP, por ejemplo aplicaciones de IA/LLM como [Claude Desktop](https://claude.ai/download), [Cursor](https://www.cursor.com/) o cualquier otra aplicación que soporte MCP.

El comando acepta un argumento opcional, `-dir=<ruta>`, que permite que las herramientas MCP adicionales interactúen con archivos dentro de esa ruta. Sin esta configuración, las herramientas MCP pueden interactuar con cadenas, pero dependerán de otros mecanismos dentro del host MCP para interactuar con el sistema de archivos subyacente.

Es justo decir que esta funcionalidad está bastante en beta en este momento.

## LSP (Servidor de Lenguaje)

El comando `threatcl lsp` ejecuta un servidor del [Protocolo de Servidor de Lenguaje](https://microsoft.github.io/language-server-protocol/) sobre stdio, proporcionando a los editores con capacidad LSP diagnósticos en vivo, autocompletado, información al pasar el cursor, símbolos del documento y formato para modelos de amenazas HCL de threatcl.

Lo lanza el cliente LSP de tu editor, no se ejecuta manualmente. Debido a que los archivos de threatcl comparten la extensión `.hcl` con Terraform y otros dialectos HCL, hacer coincidir `*.tm.hcl` (o delimitar el cliente a tu espacio de trabajo de modelos de amenazas) evita conflictos con un servidor de lenguaje de Terraform.

Consulta [docs/lsp.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/lsp.md) para la configuración del editor (Neovim, Helix, VS Code, Zed) y las limitaciones actuales.

## Servidor (API GraphQL)

El comando `threatcl server` inicia un servidor de API GraphQL que expone tus modelos de amenazas a través de HTTP para consultas programáticas e integración.

### Uso Básico```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

Navega a http://localhost:8080 para acceder al GraphQL Playground interactivo.

Ejemplo de Consulta```graphql

query { stats { totalThreatModels totalThreats implementedControls }

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

### Documentación

Para obtener la documentación completa de la API, la referencia del esquema, consultas avanzadas y ejemplos de integración, consulte:
- **Documentación completa de la API**: [docs/graphql-api.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/graphql-api.md)
- **Ejemplos de consultas**: [examples/graphql-queries.md](https://github.com/threatcl/threatcl/blob/HEAD/examples/graphql-queries.md)

## Consulta (CLI de GraphQL)

El comando `threatcl query` ejecuta consultas GraphQL directamente desde la línea de comandos sin iniciar un servidor. Esto es ideal para automatización, pipelines de CI/CD y scripting de shell.

### Uso básico```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"

Formatos de salida

  • pretty (default): JSON formateado con sangría
  • json: Igual que pretty
  • compact: JSON de una sola línea para scripting

Consulta con variables```bash

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

### Ejemplo de 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"

Consulte docs/graphql-api.md para consultas disponibles y el esquema GraphQL.

Panel de control

El comando threatcl dashboard toma archivos HCL de especificación threatcl y genera varios archivos markdown y png, colocándolos en una carpeta seleccionada.```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'

### Plantillas Markdown Personalizadas

El comando `threatcl dashboard` también puede tomar flags opcionales para especificar plantillas personalizadas (según el [text/template](https://pkg.go.dev/text/template) de Golang).

Para especificar un archivo de plantilla de dashboard, use la bandera `-dashboard-template`. Para un ejemplo, vea [dashboard-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/dashboard-template.tpl).

Para especificar un archivo de plantilla de threatmodel, use la bandera `-threatmodel-template`. Para un ejemplo, vea [threatmodel-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/threatmodel-template.tpl).

### Nombre de Archivo Personalizado para el Archivo de Índice del Dashboard

El comando `threatcl dashboard` también puede tomar una bandera opcional para especificar un nombre de archivo para el archivo de dashboard generado "index". Por defecto este archivo es `dashboard.md`. Use la bandera `-dashboard-filename` sin extensión para cambiar este nombre de archivo.

## Diagrama de Flujo de Datos

Según la [especificación](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl), un `threatmodel` puede incluir bloques `data_flow_diagram_v2`. Un ejemplo de un DFD simple está disponible [aquí](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm2.hcl). El antiguo bloque de un solo uso `data_flow_diagram` será obsoleto en algún momento, por lo que es mejor usar bloques nombrados `data_flow_diagram_v2`, de esa manera puede tener múltiples DFDs asociados.

El comando `threatcl dfd` toma archivos HCL de especificación `threatcl`, y genera varios archivos png, colocándolos en una carpeta seleccionada.

Si el archivo HCL no incluye un bloque `threatmodel` con un bloque `data_flow_diagram` o `data_flow_diagram_v2`, entonces no se genera nada.

El comando en sí es muy similar al comando Dashboard.```bash
$ threatcl dfd -overwrite -outdir testout examples/*
Successfully created 'testout/tm2-modellymodel.png'

Si tu threatmodel no incluye un diagram_link, pero sí incluye un data_flow_diagram, entonces esto también se renderizará al ejecutar threatcl dashboard.

Mermaid

Según la especificación, un threatmodel también puede incluir bloques mermaid de forma libre. A diferencia de data_flow_diagram_v2 (que threatcl renderiza por ti), un bloque mermaid incrusta el código fuente raw de mermaid textualmente - mermaid infiere el tipo de diagrama (secuencia, estado, diagrama de flujo, etc.) a partir de la primera línea del contenido.

El comando threatcl mermaid extrae ese código fuente raw para que pueda ser canalizado a otras herramientas de renderizado. No renderiza imágenes por sí mismo.

Por defecto, el código fuente se imprime en STDOUT:```bash $ threatcl mermaid examples/tm2.hcl sequenceDiagram User->>App: credentials App->>Auth: verify Auth-->>App: token

Esto facilita hacer pipe hacia un renderizador como [mermaid-cli](https://github.com/mermaid-js/mermaid-cli):```bash
$ threatcl mermaid model.hcl | mmdc -o diagram.svg -i -

Si hay múltiples bloques mermaid, selecciona uno con -index=n, o escríbelos todos en un directorio con -outdir (un archivo .mmd por bloque). También puedes escribir un solo bloque en un archivo con -out.```bash $ threatcl mermaid -outdir testout model.hcl Successfully created 'testout/model-mymodelloginsequence.mmd'

## Terraform

El comando `threatcl terraform` es capaz de extraer recursos de datos de la salida `terraform show -json` [documentación aquí](https://www.terraform.io/docs/cli/commands/show.html) de archivos de plan, o archivos de estado activos, y convertirlos en bloques `information_asset` redactados para su inclusión en archivos `threatcl`.

Si te encuentras en una carpeta con un estado existente, puedes ejecutar lo siguiente:```bash
terraform show -json | threatcl terraform -stdin

Esto generará algo similar a esto:```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" }

También puedes ver una salida similar de un archivo de plan que aún no se ha aplicado con Terraform ejecutando:```bash
terraform show -json <plan-file> | threatcl terraform -stdin

Si deseas actualizar un archivo de modelo de amenazas threatcl existente ("threatmodel.hcl"), puedes hacerlo con:```bash terraform show -json | threatcl terraform -stdin -add-to-existing=threatmodel.hcl > new-threatmodel.hcl

Con la bandera `-add-to-existing`, también puede especificar `-tm-name=<string>` si necesita especificar un modelo de amenaza particular del archivo fuente, si hay varios. Y también puede aplicar una clasificación predeterminada, con la bandera `-default-classification=Confidential`.

Estos comandos también pueden aceptar un archivo como entrada, en cuyo caso, omita la bandera `-stdin`.

Los recursos de terraform que `threatcl` conoce están codificados en [pkg/terraform/terraform.go](https://github.com/threatcl/threatcl/blob/HEAD/pkg/terraform/terraform.go). Si desea que el comando `threatcl terraform` genere otros recursos `information_asset` que no están allí, puede proporcionar su propia versión de este json a través de la bandera `-tf-collection=<json file>`.

Categorías