内容
# 天
[](https://github.com/seibel777/tien.app/actions/workflows/ci.yml)
代码仓库:https://github.com/seibel777/tien.app
**天** 是一个本地优先的安全命令行工具,帮助人们和人工智能编码代理将人工智能构建或草率编码的应用程序转换为可审查的证据。其**内置检查是被动的**,检查内容包括:
- **代码仓库**(主要关注JavaScript/TypeScript)通过SAST/SCA/密钥工具
- **网址** 通过非侵入性HTTP/TLS/头部分析(仅限GET/HEAD请求)
它灵感来自“管道风格”的命令行工具(扫描 → 编码/合并 → 报告/绘图):扫描器发出结果,其他命令使用这些结果生成报告或可视化。
> 天不会尝试利用漏洞。被动发现是*信号* + *证据*,而不是妥协的证明。
刚接触安全工具?从[入门指南](docs/getting-started.md)开始。如果使用Codex、Claude Code、Cursor、Copilot或其他编码代理,请使用[人工智能代理集成指南](docs/ai-agents.md)。
---
## 目标
- **单一二进制文件**(本地使用)
- **被动式内置**网址检查(无有效载荷、模糊测试、暴力破解)
- **代码仓库 + 网址** 从一开始
- **流式友好**工作流程(标准输入/标准输出、文件输出)
- **确定性输出**(易于在运行之间进行差异比较)
- **本地扩展**(并发、缓存、分片模式)
---
## 天的作用
### 代码仓库扫描(被动式)
- **密钥**检测(错误提交的令牌/密钥)
- **依赖项**漏洞扫描(SCA)
- **静态规则**用于不安全模式(SAST),主要关注JavaScript/TypeScript
- 将结果标准化为单一的发现格式
### 网址扫描(被动式)
仅限`GET/HEAD`请求和分析:
- TLS证书 / HTTPS状态
- 安全头部(CSP/HSTS等)
- Cookie标志(Secure/HttpOnly/SameSite)存在时
- CORS错误配置模式
- `/.well-known/security.txt`存在
- 混合内容信号(https页面引用http资源)
---
## 行为安全边界
- 无主动利用
- 无凭证猜测/暴力破解
- 无有效载荷注入测试(XSS/SQLi等)
- 无激进爬取或词典攻击
天不会提供主动测试或渗透测试行为。其内置检查设计为被动式。外部插件是操作员信任的进程,不在沙盒中运行;请单独审查它们并强制执行只读文件系统和网络策略。
天不会对目标数量、发现数量或代码仓库文件大小施加任意限制。可配置的超时、响应体大小、重定向、重试和并发性仍然是资源预算,因此扫描不会消耗无限制的本地或远程资源。
---
## 状态(当前)
- 已实现:配置加载、发现模式、gob/jsonl IO、合并、编码、报告(文本/md/sarif/json)、HTML绘图、差异、网址扫描(TLS + 头部 + Cookie + CORS + security.txt + 混合内容)、主机摘要、代码仓库扫描(gitleaks + osv-scanner + semgrep)、缓存(代码仓库 + 可选网址)、运行历史、分片模式、重试 + 目标超时、优雅取消、插件系统、策略模式、Prometheus指标、最小TUI摘要、自定义Semgrep规则包、混合gitleaks运行器(CLI或Docker回退)。
---
## 技术栈
### 核心
- Go(CLI + 管道 + 存储 + 报告)
### 引擎(由天调用)
模式:
- 混合(默认):在可用时使用本地CLI,带有警告时回退到Docker。
- cli:需要已安装的CLI。
- docker:始终在容器中运行工具。
代码仓库扫描集成gitleaks、osv-scanner和semgrep。
### 输出格式(当前)
- `gob`(默认;紧凑 + 快速)
- `jsonl`(调试 + 容易集成)
- `text`报告
- `md`报告
- `sarif`报告
- `json`报告
- `html`绘图
---
## 安装
### Go安装
```bash
go install github.com/seibel777/tien.app/cmd/tien@latest
tien --help
```
### Homebrew
```bash
brew tap seibel777/tien.app https://github.com/seibel777/tien.app
brew install tien
```
需要更新tap公式以获取最新的发布校验和。请查看[公共安装指南](https://tienapp.com/docs/getting-started)以获取当前支持的路径。
### NPM
```bash
npm i -g @seibel777/tien
tien --help
```
需要发布npm包(参见`packages/npm`)。
### GitHub(克隆)
```bash
git clone https://github.com/seibel777/tien.app.git
cd tien.app
go build -o tien ./cmd/tien
./tien --help
```
### 发布(二进制下载)
预编译二进制文件:https://github.com/seibel777/tien.app/releases
Linux amd64示例:
```bash
curl -L -o tien https://github.com/seibel777/tien.app/releases/latest/download/tien_linux_amd64
chmod +x tien
./tien --help
```
macOS arm64示例:
```bash
curl -L -o tien https://github.com/seibel777/tien.app/releases/latest/download/tien_darwin_arm64
chmod +x tien
./tien --help
```
校验和以`*.sha256`的形式发布在每个二进制文件旁边。
### 引擎依赖项(代码仓库扫描)
选项A - 已安装的CLI
确保这些命令在$PATH中可用:
- gitleaks
- semgrep
- osv-scanner
选项B - Docker
安装Docker并在配置中启用“docker引擎”模式(参见下文)。
不要混合选项A和B,除非你喜欢环境调试。
---
## 用法(当前)
网址扫描(通过标准输入传递目标)
```bash
cat targets.txt | tien scan url --format gob > url.tien
```
网址扫描(目标文件)
```bash
tien scan url --targets targets.txt --format jsonl > url.jsonl
```
主机摘要默认打印到标准错误流;使用`--summary=false`禁用。
网址扫描(分片模式)
```bash
tien scan url --targets targets.txt --shard 1/5 --format gob > url_shard_1.tien
```
网址扫描与策略模式
```bash
tien scan url --targets targets.txt --policy high --format gob > url_policy.tien
```
网址扫描与Prometheus指标
```bash
tien scan url --targets targets.txt --metrics true --metrics-listen 127.0.0.1:9465 --format gob > url.tien
```
合并结果
```bash
tien merge url.tien other.tien > all.tien
```
报告(文本)
```bash
tien report --type text all.tien
```
报告(Markdown)
```bash
tien report --type md all.tien > report.md
```
报告(SARIF)
```bash
tien report --type sarif all.tien > tien.sarif
```
绘图(HTML)
```bash
tien plot all.tien > report.html
```
编码(JSONL)
```bash
tien encode --to jsonl all.tien > all.jsonl
```
差异扫描
```bash
tien diff old.tien new.tien
```
历史(本地运行索引)
```bash
tien history --limit 10
```
在配置中启用历史记录或传递`--history true`以记录运行。
代码仓库扫描(gitleaks + osv-scanner + semgrep)
```bash
tien scan repo --path . --format gob > repo.tien
```
注意:osv-scanner和semgrep可能需要网络访问获取建议或规则;如果需要,可以在配置中禁用它们。
代码仓库扫描默认按提交/配置/引擎版本缓存;使用`--cache false`禁用。
网址缓存是可选的(ETag/Last-Modified),默认禁用。
混合gitleaks(CLI或Docker回退)
```bash
tien hybrid --path . > gitleaks.json
```
输出原始gitleaks JSON(尚未规范化为发现结果)。
注意:gitleaks在发现泄漏时返回退出代码1;`tien hybrid`将视为成功,以便您仍然可以获取输出。
注意:每个公共网址目标都需要其确切主机名的范围限定、过期授权。使用`tien authorize dns`生成DNS TXT授权;公共目标授权不能被扫描调用者禁用。
---
## 目标格式(网址扫描)
targets.txt(一行一个):
https://example.com
https://app.example.com
https://api.example.com
您也可以从另一个工具通过管道传递:
some-generator | tien scan url > url.tien
---
## 配置
默认路径:
- macOS/Linux: `~/.config/tien/config.yaml`
当您明确传递`--config <path>`时,该文件是必需的。缺少、无法读取或无效的选定文件将导致命令失败,而不是回退到默认路径或内置默认值。
示例:
```yaml
repo:
engine_mode: "hybrid" # "cli", "docker", 或 "hybrid"
engines:
semgrep:
enabled: true
config: "p/default" # 或 rules/semgrep/tien-js.yml
# max_target_bytes 是可选的;Tien传递 0 以禁用 Semgrep 的隐式文件大小过滤器
# timeout_seconds 和 timeout_threshold 是可选的;0 禁用隐式跳过阈值
image: "semgrep/semgrep:<reviewed-version>" # 或不可变 @sha256 摘要
gitleaks:
enabled: true
image: "ghcr.io/gitleaks/gitleaks:<reviewed-version>"
osv:
enabled: true
image: "ghcr.io/google/osv-scanner:<reviewed-version>"
exclude:
- "node_modules/**"
- "dist/**"
- ".next/**"
- "build/**"
- "**/*.min.js"
url:
concurrency: 20
timeout_ms: 8000
max_target_ms: 15000
max_body_kb: 256
follow_redirects: true
max_redirects: 5
retry:
max_attempts: 2
backoff_ms: 200
checks:
tls: true
headers: true
cookies: true
cors: true
securitytxt: true
mixed_content: true
safety:
allow_localhost_without_proof: false
allow_private_ips_without_proof: false
allow_resolved_private_hosts: [] # 仅限精确主机;私有答案需要 HTTPS + DNS TXT 授权
proof:
method: "dns" # DNS TXT 是唯一支持的授权方法
hosts:
app.example.com: "GENERATED_HOST_SPECIFIC_256_BIT_CHALLENGE"
scope: "url-scan"
max_validity_minutes: 1440
output:
default_format: "gob"
redact_secrets_in_evidence: true
cache:
dir: "~/.cache/tien" # 可选覆盖
repo:
enabled: true
url:
enabled: false
history:
enabled: false
policy:
enabled: false
min_severity: "high"
metrics:
enabled: false
listen: "127.0.0.1:9465"
plugins:
- name: "custom-check"
kind: "repo" # 或 "url"
command: "/path/to/plugin"
args: ["--flag"]
format: "jsonl"
timeout_ms: 20000
enabled: false
```
在实际使用之前,请将每个`<reviewed-version>`占位符替换为已审查的不可变标签或镜像摘要。
---
## 插件(自定义检查)
插件允许您在不分叉天的情况下添加自定义检查。每个插件都是一个外部命令,输出JSONL或gob格式的发现结果。
插件环境变量:
• `TIEN_PLUGIN_NAME`
• `TIEN_PLUGIN_KIND`(repo|url)
• `TIEN_SCAN_TIME`(RFC3339)
• `TIEN_REPO_PATH`(仓库插件)
• `TIEN_TARGETS_FORMAT=lines` + `TIEN_TARGET_COUNT`(网址插件)
仓库插件在仓库路径下运行为工作目录。网址插件通过标准输入接收目标列表(一行一个网址),但`url-scan`授权范围仅覆盖内置的`GET`/`HEAD`检查。包含任何公共目标的批次在启用网址插件时关闭。网址插件目前只能针对明确豁免的本地主机或私有IP开发目标运行。
---
## 自定义Semgrep规则包
使用`rules/semgrep/tien-js.yml`中的捆绑规则包进行JavaScript/TypeScript焦点检查。设置:
```yaml
repo:
engines:
semgrep:
config: "rules/semgrep/tien-js.yml"
```
---
## 指标、策略和TUI
- **Prometheus指标**:`tien scan url --metrics true --metrics-listen 127.0.0.1:9465` 暴露 `/metrics`。
- **策略模式**:`tien scan repo --policy high` 如果发现结果 >= 严重性,则退出非零。
- **最小TUI**:添加 `--tui` 以在标准错误流上显示实时摘要。
---
## 范围限定授权(网址扫描安全)
每个公共网址目标都需要其确切主机名的授权。使用256位挑战和过期授权代替重用永久令牌:
```bash
tien authorize dns --domain app.example.com --valid-for 24h
```
在单个命令中重复 `--domain` 以获取多主机批次;天会发出一个精确主机授权和一个不同挑战每个域名,形成操作员的显式主机允许列表。
在命令打印的DNS名称上发布结构化值,例如:
```text
_tien-authorization.app.example.com. TXT "v=tien1;host=app.example.com;scope=url-scan;challenge=...;issued=2026-07-15T12:00:00Z;expires=2026-07-16T12:00:00Z"
```
`example.com`的授权不会授权`app.example.com`。天会验证主机名、`url-scan`范围、挑战、颁发时间、过期时间和操作员配置的最大有效期。
配置示例:
```yaml
safety:
allow_localhost_without_proof: false
allow_private_ips_without_proof: false
allow_resolved_private_hosts: [] # 私有DNS答案需要HTTPS + DNS TXT授权
proof:
method: "dns"
hosts:
app.example.com: "GENERATED_HOST_SPECIFIC_256_BIT_CHALLENGE"
scope: "url-scan"
max_validity_minutes: 1440
```
DNS TXT是天唯一支持的网址授权方法。旧版`http`和`dns+http`配置会关闭并必须迁移到`method: "dns"`。
`url-scan`授权是天内置`GET`/`HEAD`检查的合作操作范围信号。它不是合法或合同授权,不会取代书面许可或参与规则,不会阻止修改后的二进制或分支删除防护栏。
天在启动工作线程、缓存读取或内置网络请求之前授权完整的目标批次。未经授权的目标会停止完整的批次。 如果最早的授权在执行期间过期,天会中止运行并报告授权失败;MCP返回工具错误,而不是部分成功。公共网址插件关闭,因为它们在`url-scan`能力之外;只有明确豁免的本地主机或私有IP目标目前可以访问网址插件。重定向必须保持在相同的方案、主机名和有效端口上。解析为RFC 1918或IPv6 ULA地址的主机名必须精确出现在`allow_resolved_private_hosts`中,使用`https://`目标,并呈现其精确的DNS TXT授权;解析的地址为运行固定。 通过非本地名称、链路本地、CGNAT、组播、未指定和元数据地址的环路仍然被阻止。 本地和私有开发目标需要明确的操作员豁免。
## 设计
Pipeline 模型
Tien 遵循一个两步模型:
1. 扫描命令发出一系列发现(stdout/文件)
2. 报告/绘图/编码/合并 消费发现并产生输出
这使得以下操作变得容易:
* 在多台机器上运行扫描
* 稍后合并输出
* 将扫描逻辑与报告/可视化分开
发现模式(存储库 + URL 的单一格式)
每个问题都标准化为一个发现:
* id:稳定的检查标识符(url.headers.hsts_missing,repo.secrets.generic,repo.deps.osv)
* source:URL 或存储库
* target:URL 或路径:行
* severity:info|low|med|high|crit
* confidence:low|med|high
* title:简短的人类标题
* description:检测到的内容及其重要性
* evidence:简短的、编辑过的证明(标头/片段/包)
* remediation:直接修复指导
* tags:例如 cwe:*,owasp:*,category:*
* fingerprint:确定性哈希,用于跨运行去重
* timestamp:检测时间
* run_id:运行标识符(用于比较)
指纹规则(必须稳定)
* URL 发现:(id + 规范化主机 + 规范化路径? + 关键证据字段) 的哈希
* 存储库发现:(id + 文件路径 + 行 + 规则 ID/包 ID) 的哈希
这使得以下操作成为可能:
* 去重
* 运行之间的差异
* 即使存在并发,报告也稳定
有关检查 ID 的完整列表,请参见 `docs/checks.md`。
引擎
存储库引擎实现:
* 运行外部工具
* 解析工具输出(尽可能使用 JSON/SARIF)
* 标准化为发现
URL 检查实现:
* 使用超时和限制获取(仅 GET/HEAD)
* 分析 TLS/标头/正文(有界)
* 发出规范化的发现
---
命令概述
tien mcp
在 stdin/stdout 上运行本地模型上下文协议服务器,以便兼容的编码代理可以使用类型化输入和结构化输出调用 Tien。
常见标志:
- `--root <dir>` (存储库边界;默认为当前目录)
- `--config <path>` (操作员拥有的策略字段在服务器启动时加载;缺少选定的路径会导致启动失败)
服务器公开了功能、存储库扫描、URL 扫描和工件差异工具。路径不能超出选定的根目录,证据默认情况下被排除,操作员拥有的引擎、插件、参数和 URL 授权的策略字段在启动时加载。明确选择缺少、不可读或无效的 `--config` 路径会导致启动失败,而不是回落到默认值。扫描工具都不接受代理控制的替换配置。引用的规则文件、插件二进制文件、忽略文件和可变镜像标签不会快照,可以独立漂移;请保护它们免受代理写入,并固定版本或摘要。每个 URL 批次都会关闭,除非启动策略授权所有确切的主机,并且公共 URL 插件保留在 `url-scan` 范围之外。MCP 不施加目标计数或发现计数上限;调用者仍可以请求使用可选的 `max_findings` 工具参数进行更小的演示。
有关客户端配置和代理操作合同,请参见 `docs/ai-agents.md`。
tien scan repo
使用配置的引擎扫描存储库路径并发出发现。
运行启用的引擎(gitleaks、osv-scanner、semgrep)。
支持启用时基于提交的缓存。
常见标志:
* `--path <dir>`
* `--format gob|jsonl`
* `--config <path>`
* `--cache auto|true|false`
* `--history auto|true|false`
* `--policy <severity|off>`
* `--metrics auto|true|false`
* `--metrics-listen <addr>`
* `--tui`
tien scan url
从 stdin(或 --targets)读取 URL 并发出发现。
常见标志:
* `--targets <file>` (可选;默认为 stdin)
* `--format gob|jsonl`
* `--summary=true|false`
* `--config <path>`
* `--shard N/M`
* `--cache auto|true|false`
* `--history auto|true|false`
* `--policy <severity|off>`
* `--metrics auto|true|false`
* `--metrics-listen <addr>`
* `--tui`
配置选项控制并发性、每个目标的运行时、响应正文大小、重试、重定向和作用域授权。这些资源预算不限制目标或发现计数。
tien hybrid
使用本地 CLI 或 Docker 回退运行 gitleaks 并发出原始 JSON。
常见标志:
* `--path <dir>`
* `--image <docker-image>`
tien merge
将多个 .tien 文件合并为一个。
tien report
生成报告:
* `--type text|md|sarif|json`
* `--min-severity info|low|med|high|crit`
* `--group-by source|severity|target|none`
* `--only-tags tag1,tag2`
* `--top <n>`
tien encode
转换格式:
* `--to gob|jsonl`
tien plot
从发现中生成 report.html。
常见标志:
* `--min-severity info|low|med|high|crit`
* `--only-tags tag1,tag2`
tien diff
比较两次扫描并报告新的/固定的/更改的发现。
tien history
显示本地运行历史(在配置文件中启用时)。
常见标志:
* `--format text|json`
* `--limit <n>`
---
## 路线图
有关分阶段检查清单和可选扩展,请参见 `roadmap.md`。
测试指南:`docs/testing.md`。
---
项目布局
tien/
cmd/tien/ # CLI 入口点
internal/app/ # 配置 + 接线
internal/cache/ # 存储库/URL 缓存 + 历史存储
internal/history/ # 本地运行历史助手
internal/metrics/ # Prometheus 指标收集器
internal/mcpserver/ # 本地 MCP 工具 + 存储库边界强制执行
internal/plugins/ # 自定义检查的插件运行器
internal/scan/ # 协调 + URL/存储库扫描
internal/engines/repo/ # semgrep/osv/gitleaks 包装器
internal/diff/ # 扫描差异
internal/store/ # gob/jsonl IO + 合并
internal/report/ # text/md/sarif/json
internal/plot/ # html 绘图
pkg/model/ # 导出的发现模式
pkg/version/
docs/
examples/
rules/semgrep/
.github/workflows/
---
许可证
Apache-2.0。参见 `LICENSE`。
---
链接
- 存储库:https://github.com/seibel777/tien.app
- 版本:https://github.com/seibel777/tien.app/releases
- 问题:https://github.com/seibel777/tien.app/issues
- 文档:`docs/README.md`
- 标志:`tien --help`
- 更新日志:`CHANGELOG.md`
- 许可证:`LICENSE`
- 安全:`SECURITY.md`
- 贡献:`CONTRIBUTING.md`
---
免责声明
Tien 旨在扫描:
* 您拥有的代码
* 您有权评估的系统
被动扫描降低了风险,但您仍有责任获得书面授权并遵守法律法规、政策、参与规则和范围限制。Tien 的 DNS TXT 证明是一种合作的运营护栏,而不是法律或合同许可。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器