
threatcl v0.6.5
使用HCL记录您的威胁模型
threatcl
使用 HCL 进行威胁建模
hcltm 发生了什么?
hcltm 已更名为 threatcl。欢迎!
概述
[!TIP] 想阅读新的文档?请访问 threatcl.dev
威胁模型可以通过多种方式进行记录。从简单的文本文件,到更深入的 Word 文档,再到完全仪表化的集中式解决方案中的威胁模型。威胁模型的两个最有价值的属性是能够清晰记录威胁,并能够推动有价值的变更。
threatcl 旨在通过关注以下目标,提供一种 DevOps 优先的方法来记录系统威胁模型:
- 简单的文本文件格式
- 简单的 CLI 驱动用户体验
- 集成到版本控制系统(VCS)中
此仓库是 threatcl CLI 软件的所在地。threatcl 规范 基于 HCL2,即 HashiCorp 配置语言,其目标是“对于人类而言易于阅读和编写,以及一种基于 JSON 的变体,更便于机器生成和解析”。threatcl 规范位于 github.com/threatcl/spec。结合 threatcl CLI 软件和 threatcl 规范,实践者可以用 HCL 定义系统威胁模型,例如:```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 }
}
有关如何构建可自动转换为 PNG 的数据流图的更多信息,请参阅[数据流图](#data-flow-diagram)。
要了解如何引用 [OWASP 主动控制](https://owasp.org/www-project-proactive-controls/) 和 [AWS 安全清单](https://d1.awsstatic.com/whitepapers/Security/AWS_Security_Checklist.pdf) 的预定义控制库的示例,请参阅 [examples/tm3.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm3.hcl)。我们也提供了 [MITRE ATT&CK 控制](https://attack.mitre.org/mitigations/enterprise/) [此处](https://github.com/threatcl/threatcl/blob/HEAD/examples/MITRE_ATTACK_controls.hcl)。
您还可以将外部威胁模型包含到您自己的模型中,以引用和使用其所有信息。您可以查看 [examples/including-example/corp-app.hcl](https://github.com/threatcl/threatcl/blob/HEAD/examples/including-example/corp-app.hcl) 作为示例。
要查看规范的完整描述,请参阅[此处](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl)或运行:```bash
threatcl generate boilerplate
threatcl 也会处理 JSON 文件,但唯一的限制是导入模块和变量将无法工作。你可以参考 examples/tm1.json 作为示例。
为什么使用 HCL?
HCL 是 HashiCorp 产品中使用的主要配置语言,特别是 Terraform——他们的开源基础设施即代码软件。我曾在 HashiCorp 工作过一段时间,这种语言逐渐让我喜欢上了它,此外,如果 DevOps 和软件工程师正在使用这种语言,那么简化他们记录威胁模型的方式与 threatcl 的目标是一致的。
你可以将 threatcl 与 JSON 一起使用,但会失去一些功能。更多信息请参见 examples/ 文件夹。
为什么不直接用 Markdown 记录?
我喜欢使用一种可以以编程方式交互的格式的想法。
致谢与参考
threatcl 的功能之一是自动从 HCL 文件生成数据流图。这利用了 Marqeta 和 Blake Hitchcock 的 go-dfd 包。一定要看看他们关于威胁模型迈向 DevOps 的速度的博客文章。
此外,我要感谢 HashiCorp 的 Jamie Finnigan 和 Talha Tariq,允许我在离开 HashiCorp 后继续开发这个开源工具。
还要感谢 IriusRisk 团队提供的 OpenThreatModel 规范。
threatcl 命令行工具
安装
从 releases 下载最新版本,并将 threatcl 二进制文件移动到你的 PATH 中。
通过 Homebrew 安装
使用 Homebrew 安装 threatcl——该公式位于 homebrew-core 中:```bash
brew install threatcl
## 使用 Docker 运行```bash
docker run --rm -it ghcr.io/threatcl/threatcl:latest
验证发布版本(构建来源证明)
每个标记的发布版本都附带 SLSA 构建来源证明 —
Sigstore 签名、无密钥证明,由 GitHub Actions 发布流水线生成(GitHub OIDC → Fulcio,无需签名密钥)。您可以使用 GitHub CLI(gh attestation verify — 无需额外工具或管理的受信任密钥)验证二进制文件或容器镜像确实是从此仓库的发布工作流构建的。
验证下载的归档文件(或 SHA256SUMS 文件):```bash
gh attestation verify threatcl_.tar.gz --repo threatcl/threatcl
验证容器镜像(标签会自动解析为其摘要):```bash
gh attestation verify oci://ghcr.io/threatcl/threatcl:<version> --repo threatcl/threatcl
要固定到你所运行的确切镜像,请自行解析摘要,并通过摘要进行验证(和拉取):```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
See [docs/SLSA.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/SLSA.md) 了解完整的供应链安全状况。
## 通过 GitHub Actions 运行
`threatcl` 可以直接集成到您的 GitHub 仓库中,使用 https://github.com/threatcl/threatcl-action。这是管理威胁模型的理想方法之一,并有助于实现集成到版本控制系统的目标。
## 从源码构建
1. 克隆此仓库。
2. 进入目录 `threatcl`
3. `make bootstrap`
4. `make build`
有关对 `threatcl` 贡献的更多帮助,请参阅 [CHANGELOG.md](https://github.com/threatcl/threatcl/blob/HEAD/CHANGELOG.md)。
## 使用方法
有关任何子命令的帮助,请使用 `-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)
(可选)配置文件
大多数 threatcl 命令都带有 -config 标志,允许你指定一个 config.hcl 文件。该文件中的 HCL 可用于覆盖 threatcl 的部分默认属性。以下是可覆盖的属性列表:
- 威胁类型规模 - 默认值为“未定义”、“小型”、“中型”、“大型”
- 默认威胁类型规模 - 默认值为“未定义”
- 信息分类 - 默认值为“受限”、“机密”、“公开”
- 默认信息分类 - 默认值为“机密”
- 影响类型 - 默认值为“机密性”、“完整性”、“可用性”
- STRIDE 元素 - 默认值为“欺骗”、“篡改”、“信息泄露”、“拒绝服务”、“权限提升”
- 运行时间依赖分类 - 默认值为“无”、“降级”、“硬依赖”、“运营依赖”
- 默认运行时间依赖分类 - 默认值为“无”
例如:```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"
如果您修改这些属性,则需要记住为其他操作提供配置文件,因为这可能会影响验证或仪表盘创建。
## 云命令
访问 https://threatcl.dev/cloud/overview/ 了解更多关于 `cloud` 子命令的信息。
## 列表与查看
`threatcl list` 和 `threatcl view` 命令可用于列出和查看来自 `threatcl` 规范 HCL 文件的数据。```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
Validate
threatcl validate 命令用于验证 threatcl 规范 HCL 文件。```bash
$ threatcl validate examples/*
Validated 3 threatmodels in 3 files
### Invariants
`threatcl validate` 还可以强制实施组织级的不变性——即机器可检查的规则,例如“公共端点不应未经身份验证”或“所有面向互联网的功能必须记录审计日志”——针对每个经过验证的威胁模型:```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
不变条件存在于它们自己的 HCL 文件中,针对特定集合(威胁、控制、DFD 进程、数据流……),并以原生 HCL 表达式的形式表达其条件。它们支持 error/warning 严重级别以及带有理由的每模型豁免。参见 docs/invariants.md。
Export
threatcl export 命令用于将一个或多个 threatcl 威胁模型导出为原生 JSON 表示(默认),或导出为 OTM JSON 表示,甚至导出回 hcl(这对于从动态威胁模型输出新的 HCL 很有用)。你也可以使用 -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}}]}]
## 生成
`threatcl generate` 命令用于输出一个通用的 `boilerplate` `threatcl` spec HCL 文件,或者交互式地向用户提问,然后输出一个 `threatcl` spec HCL 文件。
### 交互式生成
请参考以下示例:```bash
threatcl generate interactive
生成交互式编辑器
如果你更喜欢直接在 $EDITOR 中工作,请运行:```bash
threatcl generate interactive editor
这将打开你的编辑器,并创建一个基础的 HCL 威胁模型。如果你想在创建后验证模型,请使用 `-validate` 标志。
## MCP
`threatcl mcp` 命令暴露一个本地 [MCP](https://modelcontextprotocol.io/introduction) 服务器,以便你可以通过 MCP 主机与 threatcl hcl 文件进行交互,例如 AI/LLM 应用程序,如 [Claude Desktop](https://claude.ai/download)、[Cursor](https://www.cursor.com/),或任何其他支持 MCP 的应用程序。
该命令接受一个可选的参数 `-dir=<path>`,允许额外的 MCP 工具与该路径内的文件进行交互。没有此设置时,MCP 工具可以与字符串交互,但将依赖 MCP 主机内的其他机制与底层文件系统进行交互。
可以说,这个功能目前还处于相当初级的测试阶段。
## LSP (语言服务器)
`threatcl lsp` 命令通过 stdio 运行一个 [语言服务器协议](https://microsoft.github.io/language-server-protocol/) 服务器,为支持 LSP 的编辑器提供 threatcl HCL 威胁模型的实时诊断、补全、悬停、文档符号和格式化功能。
它由编辑器的 LSP 客户端启动,而不是手动运行。由于 threatcl 文件与 Terraform 和其他 HCL 方言共享 `.hcl` 扩展名,匹配 `*.tm.hcl`(或将客户端限定在你的威胁模型工作区内)可以避免与 Terraform 语言服务器冲突。
参见 [docs/lsp.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/lsp.md) 了解编辑器配置(Neovim、Helix、VS Code、Zed)以及当前限制。
## Server (GraphQL API)
`threatcl server` 命令启动一个 GraphQL API 服务器,通过 HTTP 暴露你的威胁模型,以供程序化查询和集成。
### 基本用法```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
导航到 http://localhost:8080 以访问交互式 GraphQL Playground。
示例查询```graphql
query { stats { totalThreatModels totalThreats implementedControls }
threatModels(filter: { internetFacing: true }) { name threats { description controls { name implemented } } } }
### 文档
关于完整的 API 文档、模式参考、高级查询和集成示例,请参阅:
- **完整 API 文档**:[docs/graphql-api.md](https://github.com/threatcl/threatcl/blob/HEAD/docs/graphql-api.md)
- **查询示例**:[examples/graphql-queries.md](https://github.com/threatcl/threatcl/blob/HEAD/examples/graphql-queries.md)
## 查询 (GraphQL CLI)
`threatcl query` 命令直接从命令行执行 GraphQL 查询,无需启动服务器。这非常适合自动化、CI/CD 流水线和 shell 脚本。
### 基本用法```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"
输出格式
pretty(默认):带缩进的格式化 JSONjson:与 pretty 相同compact:适合脚本处理的单行 JSON
带变量的查询```bash
$ threatcl query -dir ./examples
-query 'query($author: String) { threatModels(filter: {author: $author}) { name } }'
-vars '{"author": "John Doe"}'
### 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"
有关可用查询和GraphQL模式,请参阅 docs/graphql-api.md。
仪表盘
threatcl dashboard 命令接受 threatcl 规范的 HCL 文件,并生成许多 markdown 和 png 文件,将它们放入选定的文件夹中。```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'
### 自定义 Markdown 模板
`threatcl dashboard` 命令还可以使用可选标志来指定自定义模板(遵循 Go 语言的 [text/template](https://pkg.go.dev/text/template))。
要指定仪表盘模板文件,请使用 `-dashboard-template` 标志。示例请参阅 [dashboard-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/dashboard-template.tpl)。
要指定威胁模型模板文件,请使用 `-threatmodel-template` 标志。示例请参阅 [threatmodel-template.tpl](https://github.com/threatcl/threatcl/blob/HEAD/examples/threatmodel-template.tpl)。
### 仪表盘索引文件的自定义文件名
`threatcl dashboard` 命令还可以使用一个可选标志来指定生成的“索引”仪表盘文件的文件名。默认情况下,此文件名为 `dashboard.md`。使用 `-dashboard-filename` 标志(不带扩展名)可更改此文件名。
## 数据流图
根据 [规范](https://github.com/threatcl/threatcl/blob/HEAD/spec.hcl),一个 `threatmodel` 可能包含 `data_flow_diagram_v2` 块。一个简单 DFD 的示例可在 [这里](https://github.com/threatcl/threatcl/blob/HEAD/examples/tm2.hcl) 找到。旧的单次使用块 `data_flow_diagram` 将在某个时候被弃用,因此最好使用 `data_flow_diagram_v2` 命名块,这样你可以拥有多个关联的 DFD。
`threatcl dfd` 命令接受 `threatcl` 规范的 HCL 文件,并生成多个 png 文件,将它们放入所选文件夹中。
如果 HCL 文件不包含带有 `data_flow_diagram` 或 `data_flow_diagram_v2` 块的 `threatmodel` 块,则不会输出任何内容。
该命令本身与仪表盘命令非常相似。```bash
$ threatcl dfd -overwrite -outdir testout examples/*
Successfully created 'testout/tm2-modellymodel.png'
If your threatmodel doesn't include a diagram_link, but does include a data_flow_diagram, then this will also be rendered when running threatcl dashboard.
Mermaid
As per the spec, a threatmodel may also include free-form mermaid blocks. Unlike data_flow_diagram_v2 (which threatcl renders for you), a mermaid block embeds raw mermaid source verbatim - mermaid infers the diagram type (sequence, state, flowchart, etc.) from the first line of the content.
The threatcl mermaid command extracts that raw source so it can be piped into other rendering tools. It does not render images itself.
By default the source is printed to STDOUT:```bash $ threatcl mermaid examples/tm2.hcl sequenceDiagram User->>App: credentials App->>Auth: verify Auth-->>App: token
这使得可以轻松地通过管道传递给渲染器,例如 [mermaid-cli](https://github.com/mermaid-js/mermaid-cli):```bash
$ threatcl mermaid model.hcl | mmdc -o diagram.svg -i -
如果有多个 mermaid 块,可以使用 -index=n 选择一个,或者使用 -outdir 将它们全部写入一个目录(每个块一个 .mmd 文件)。你也可以使用 -out 将单个块写入一个文件。```bash
$ threatcl mermaid -outdir testout model.hcl
Successfully created 'testout/model-mymodelloginsequence.mmd'
## Terraform
`threatcl terraform` 命令能够从 `terraform show -json` [文档在此](https://www.terraform.io/docs/cli/commands/show.html) 输出的计划文件或活跃状态文件中提取数据资源,并将这些资源转换为草稿形式的 `information_asset` 块,以便包含在 `threatcl` 文件中。
如果你位于包含现有状态的文件夹中,可以执行以下命令:```bash
terraform show -json | threatcl terraform -stdin
这将会输出类似以下内容:```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" }
你也可以通过运行以下命令,查看尚未通过 Terraform 应用的计划文件中的类似输出:```bash
terraform show -json <plan-file> | threatcl terraform -stdin
如果你想要更新一个已有的 threatcl 威胁模型文件 ("threatmodel.hcl"),你可以使用:```bash
terraform show -json | threatcl terraform -stdin -add-to-existing=threatmodel.hcl > new-threatmodel.hcl
使用 `-add-to-existing` 标志时,如果源文件中有多个威胁模型,还可以通过指定 `-tm-name=<string>` 来选择特定的威胁模型。此外,你还可以通过 `-default-classification=Confidential` 标志应用默认分类。
这些命令也可以直接将文件作为输入,在这种情况下,省略 `-stdin` 标志。
`threatcl` 所识别的 Terraform 资源已硬编码在 [pkg/terraform/terraform.go](https://github.com/threatcl/threatcl/blob/HEAD/pkg/terraform/terraform.go) 中。如果你希望 `threatcl terraform` 命令输出其他不在该文件中的 `information_asset` 资源,可以通过 `-tf-collection=<json file>` 标志提供你自己的 JSON 版本。