seibel777/tien.app
GitHub: seibel777/tien.app
Tien 是一款本地优先的被动式安全审计 CLI,专注于对 JS/TS 代码仓库和 URL 进行机密检测、依赖漏洞扫描、SAST 分析及 HTTP/TLS 安全配置检查。
Stars: 1 | Forks: 0
# Tien
[](https://github.com/seibel777/tien.app/actions/workflows/ci.yml)
代码仓库:https://github.com/seibel777/tien.app
**Tien** 是一款本地优先的安全 CLI 工具,旨在帮助用户和 AI 编码代理将 AI 构建或随性编写的应用转化为可审查的凭证。它会对以下目标运行 **100% 被动** 的安全检查:
- **代码仓库**(专注于 JS/TS)通过 SAST/SCA/机密检测工具
- **URL** 通过非侵入式的 HTTP/TLS/Header 分析(仅限 GET/HEAD)
它的灵感来源于“流水线式” CLI(扫描 → 编码/合并 → 报告/绘图):扫描器发出结果,其他命令消费这些结果以生成报告或可视化图表。
刚接触安全工具?请从[入门指南](docs/getting-started.md)开始。正在使用 Codex、Claude Code、Cursor、Copilot 或其他编码代理?请查阅 [AI 代理集成指南](docs/ai-agents.md)。
## 目标
- **单一二进制文件**(用于本地运行)
- **仅限被动** URL 检查(无 payload、模糊测试或暴力破解)
- 从第一天起就支持 **仓库 + URL**
- **流式友好** 的工作流(stdin/stdout,文件输出)
- **确定性输出**(便于在不同运行之间进行 diff)
- **本地扩展**(并发、缓存、分片模式)
## Tien 的功能
### 仓库扫描(被动)
- **机密** 检测(意外提交的 token/密钥)
- **依赖项** 漏洞扫描 (SCA)
- 针对不安全模式的 **静态规则** (SAST),专注于 JS/TS
- 将结果标准化为统一的 finding 格式
### URL 扫描(被动)
仅使用 `GET/HEAD` 并进行分析:
- TLS 证书 / HTTPS 配置
- 安全 Header(CSP/HSTS 等)
- 存在时的 Cookie 标志(Secure/HttpOnly/SameSite)
- CORS 配置错误模式
- `/.well-known/security.txt` 是否存在
- 混合内容信号(https 页面引用了 http 资源)
## 硬性限制(不可协商)
- 无主动利用
- 无凭证猜测 / 暴力破解
- 无 payload 注入测试(XSS/SQLi 等)
- 无激进爬取或使用字典爆破
如果你需要进行主动测试,请使用专门的工具。Tien 在设计上始终保持被动。
## 状态(当前)
- 已实现:配置加载器、Finding schema、gob/jsonl IO、合并、编码、报告(text/md/sarif/json)、HTML 绘图、diff、URL 扫描(TLS + headers + cookies + CORS + security.txt + 混合内容)、主机摘要、仓库扫描(gitleaks + osv-scanner + semgrep)、缓存(仓库 + 可选 URL)、运行历史、分片模式、重试 + 单目标超时、优雅取消、插件系统、策略模式、Prometheus 指标、极简 TUI 摘要、自定义 Semgrep 规则包、混合 gitleaks 运行器(CLI 或 Docker 回退)。
## 技术栈
### 核心
- Go(CLI + 流水线 + 存储 + 报告)
### 引擎(由 Tien 调用)
模式:
- hybrid(默认):在可用时使用本地 CLI,回退到 Docker 并发出警告。
- cli:要求已安装的 CLI。
- docker:始终在容器中运行工具。
仓库扫描集成了 gitleaks、osv-scanner 和 semgrep。
### 输出格式(当前)
- `gob`(默认;紧凑 + 快速)
- `jsonl`(调试 + 易于集成)
- `text` 报告
- `md` 报告
- `sarif` 报告
- `json` 报告
- `html` 绘图
## 安装
### Go 安装
```
go install github.com/seibel777/tien.app/cmd/tien@latest
tien --help
```
### Homebrew
```
brew tap seibel777/tien.app https://github.com/seibel777/tien.app
brew install tien
```
需要使用最新发布校验和更新的 tap formula。请查看[公开安装指南](https://tienapp.com/docs/getting-started)以了解当前支持的路径。
### NPM
```
npm i -g @seibel777/tien
tien --help
```
要求已发布 npm 包(参见 `packages/npm`)。
### GitHub(克隆)
```
git clone https://github.com/seibel777/tien.app.git
cd tien.app
go build -o tien ./cmd/tien
./tien --help
```
### Releases(二进制下载)
预构建二进制文件:https://github.com/seibel777/tien.app/releases
Linux amd64 示例:
```
curl -L -o tien https://github.com/seibel777/tien.app/releases/latest/download/tien_linux_amd64
chmod +x tien
./tien --help
```
macOS arm64 示例:
```
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 engine”模式(见下文)。
除非你喜欢调试环境,否则不要混用 A 和 B。
## 用法(当前)
URL 扫描(通过 stdin 传入目标)
```
cat targets.txt | tien scan url --format gob > url.tien
```
URL 扫描(目标文件)
```
tien scan url --targets targets.txt --format jsonl > url.jsonl
```
主机摘要默认打印到 stderr;使用 `--summary=false` 禁用。
URL 扫描(分片模式)
```
tien scan url --targets targets.txt --shard 1/5 --format gob > url_shard_1.tien
```
带策略模式的 URL 扫描
```
tien scan url --targets targets.txt --policy high --format gob > url_policy.tien
```
带 Prometheus 指标的 URL 扫描
```
tien scan url --targets targets.txt --metrics true --metrics-listen 127.0.0.1:9465 --format gob > url.tien
```
合并结果
```
tien merge url.tien other.tien > all.tien
```
报告(text)
```
tien report --type text all.tien
```
报告(Markdown)
```
tien report --type md all.tien > report.md
```
报告(SARIF)
```
tien report --type sarif all.tien > tien.sarif
```
绘图(HTML)
```
tien plot all.tien > report.html
```
编码(JSONL)
```
tien encode --to jsonl all.tien > all.jsonl
```
对比扫描(Diff)
```
tien diff old.tien new.tien
```
历史记录(本地运行索引)
```
tien history --limit 10
```
在配置中启用历史记录,或传递 `--history true` 来记录运行。
仓库扫描(gitleaks + osv-scanner + semgrep)
```
tien scan repo --path . --format gob > repo.tien
```
注意:osv-scanner 和 semgrep 可能需要网络访问以获取安全通报或规则;如有需要,可在配置中禁用它们。
仓库扫描默认按 commit/config/engine 版本进行缓存;使用 `--cache false` 禁用。
URL 缓存是可选的(ETag/Last-Modified),默认禁用。
混合 gitleaks(CLI 或 Docker 回退)
```
tien hybrid --path . > gitleaks.json
```
输出原始 gitleaks JSON(尚未标准化为 Findings)。
注意:发现泄漏时 gitleaks 会返回退出代码 1;`tien hybrid` 将此视为成功,因此你仍能获得输出。
注意:默认情况下,URL 扫描需要所有权证明。请在配置中配置 `safety.proof`,或者针对受信任的范围明确禁用此要求。
## 目标格式(URL 扫描)
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
示例:
repo:
engine_mode: "hybrid" # "cli", "docker", 或 "hybrid"
engines:
semgrep:
enabled: true
config: "p/default" # 或 rules/semgrep/tien-js.yml
max_target_bytes: 2000000
image: "returntocorp/semgrep:latest"
gitleaks:
enabled: true
image: "ghcr.io/gitleaks/gitleaks:latest"
osv:
enabled: true
image: "ghcr.io/google/osv-scanner:latest"
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
retry:
max_attempts: 2
backoff_ms: 200
checks:
tls: true
headers: true
cookies: true
cors: true
securitytxt: true
mixed_content: true
safety:
require_ownership_proof: true
allow_localhost_without_proof: true
allow_private_ips_without_proof: true
proof:
method: "http" # "http" 或 "dns"
token: "YOUR_RANDOM_TOKEN"
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
## 插件(自定义检查)
插件允许你在不派生 Tien 的情况下添加自定义检查。每个插件都是一个输出 JSONL 或 gob 格式 Findings 的外部命令。
插件环境变量:
• `TIEN_PLUGIN_NAME`
• `TIEN_PLUGIN_KIND` (repo|url)
• `TIEN_SCAN_TIME` (RFC3339)
• `TIEN_REPO_PATH` (repo 插件)
• `TIEN_TARGETS_FORMAT=lines` + `TIEN_TARGET_COUNT` (url 插件)
URL 插件通过 stdin 接收目标列表(每行一个 URL)。Repo 插件以仓库路径作为工作目录运行。
## 自定义 Semgrep 规则包
使用 `rules/semgrep/tien-js.yml` 中的捆绑规则包进行专注于 JS/TS 的检查。设置:
```
repo:
engines:
semgrep:
config: "rules/semgrep/tien-js.yml"
```
## 指标、策略和 TUI
- **Prometheus 指标**:`tien scan url --metrics true --metrics-listen 127.0.0.1:9465` 会暴露 `/metrics`。
- **策略模式**:如果 findings >= 严重程度,`tien scan repo --policy high` 将以非零状态退出。
- **极简 TUI**:添加 `--tui` 以在 stderr 上显示实时摘要。
## 所有权证明(URL 扫描安全)
默认情况下,URL 扫描需要提供你控制目标的证明,以减少意外扫描。
支持的方法(推荐):
• HTTP: /.well-known/tien-verification 必须返回一个 token
• DNS TXT: 域名上的 tien=
配置示例:
safety:
require_ownership_proof: true
proof:
method: "http" # "http" 或 "dns"
token: "YOUR_RANDOM_TOKEN"
注意:
• localhost 和私有 IP 可以在配置中免除
• 你可以禁用证明要求,但后果自负
## 设计
流水线模型
Tien 遵循两步模型:
1. scan 命令发出一系列 findings 流(stdout/文件)
2. report/plot/encode/merge 消费 findings 并生成输出
这使得以下操作变得简单:
• 在多台机器上运行扫描
• 稍后合并输出
• 将扫描逻辑与报告/可视化分开
Finding schema(仓库 + url 的单一格式)
每个问题都会被标准化为一个 Finding:
• id: 稳定的检查标识符 (url.headers.hsts_missing, repo.secrets.generic, repo.deps.osv)
• source: url 或 repo
• target: URL 或 path:line
• severity: info|low|med|high|crit
• confidence: low|med|high
• title: 简短的人类可读标题
• description: 检测到了什么以及为何重要
• evidence: 简短、脱敏的证明(headers/片段/包)
• remediation: 直接的修复指导
• tags: 例如 cwe:*, owasp:*, category:*
• fingerprint: 用于在不同运行之间去重的确定性哈希
• timestamp: 检测时间
• run_id: 运行标识符(用于比较)
指纹规则(必须稳定)
• URL findings: (id + normalized_host + normalized_path? + key_evidence_fields) 的哈希
• Repo findings: (id + file_path + line + rule_id/package_id) 的哈希
这能够实现:
• 去重
• 不同运行之间的 diff
• 即使在并发情况下也能保持稳定的报告
请查看 `docs/checks.md` 获取完整的检查 ID 列表。
引擎
Repo 引擎实现:
• 运行外部工具
• 解析工具输出(在可能的情况下使用 JSON/SARIF)
• 标准化为 Finding
URL 检查实现:
• 带有超时和限制的抓取(仅限 GET/HEAD)
• 分析 TLS/headers/body(有界)
• 发出标准化的 Finding
命令概览
tien mcp
通过 stdin/stdout 运行本地 Model Context Protocol 服务器,以便兼容的编码代理可以使用类型化输入和结构化输出调用 Tien。
常用标志:
• --root (仓库边界;默认为当前目录)
• config
• --max-findings
• --enable-url(不带此标志时 URL 工具保持隐藏)
• --max-url-targets
服务器暴露功能、仓库扫描和工件 diff 工具。路径无法逃逸指定的根目录,结果是有界的,默认排除证据,并且 URL 所有权证明仍被强制执行。
请查看 `docs/ai-agents.md` 了解客户端配置和代理操作契约。
tien scan repo
使用配置的引擎扫描仓库路径并发出 findings。
运行已启用的引擎(gitleaks, osv-scanner, semgrep)。
启用时支持基于 commit 的缓存。
常用标志:
• --path
• --format gob|jsonl
• --config
• --cache auto|true|false
• --history auto|true|false
• --policy
• --metrics auto|true|false
• --metrics-listen
• --tui
tien scan url
从 stdin(或 --targets)读取 URL 并发出 findings。
常用标志:
• --targets (可选;默认为 stdin)
• --format gob|jsonl
• --summary=true|false
• --config
• --shard N/M
• --cache auto|true|false
• --history auto|true|false
• --policy
• --metrics auto|true|false
• --metrics-listen
• --tui
配置选项控制并发、单目标运行时、重试、重定向和所有权证明。
tien hybrid
使用本地 CLI 或 Docker 回退运行 gitleaks 并发出原始 JSON。
常用标志:
• --path
• --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
tien encode
转换格式:
• --to gob|jsonl
tien plot
从 findings 生成 report.html。
常用标志:
• --min-severity info|low|med|high|crit
• --only-tags tag1,tag2
tien diff
比较两次扫描并报告新增/修复/更改的 findings。
tien history
显示本地运行历史(在配置中启用时)。
常用标志:
• --format text|json
• --limit
## 路线图
请查看 `roadmap.md` 获取分阶段检查清单和可选扩展。
测试指南:`docs/testing.md`。
项目布局
tien/
cmd/tien/ # CLI 入口
internal/app/ # 配置 + 装配
internal/cache/ # repo/url 缓存 + 历史存储
internal/history/ # 本地运行历史辅助工具
internal/metrics/ # Prometheus 指标收集器
internal/mcpserver/ # 本地 MCP 工具 + 仓库边界强制执行
internal/plugins/ # 用于自定义检查的插件运行器
internal/scan/ # 编排 + URL/repo 扫描
internal/engines/repo/ # semgrep/osv/gitleaks 封装
internal/diff/ # 扫描 diff
internal/store/ # gob/jsonl IO + 合并
internal/report/ # text/md/sarif/json
internal/plot/ # html 绘图
pkg/model/ # 导出的 Finding schema
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 旨在用于扫描:
• 你拥有的代码
• 你被授权评估的系统
被动扫描可降低风险,但遵守法律、政策和范围限制仍是你的责任。
标签:EVTX分析, JavaScript/TypeScript, SAST, TLS/Headers分析, 日志审计, 盲注攻击, 请求拦截