
threatcl v0.6.5
Documentando tus Modelos de Amenazas con HCL
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íajson: Igual que prettycompact: 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>`.