buzz39/beforeship
GitHub: buzz39/beforeship
BeforeShip 是一个开源的部署前检查关卡,为 AI 辅助构建的 SaaS 应用提供认证、密钥、支付安全等方面的自动化扫描与上线判定。
Stars: 5 | Forks: 0
# BeforeShip
**你的 AI 编程助手表示应用已完成。BeforeShip 负责检查它是否可以安全部署。**
BeforeShip 是一个开源的发布关卡,专为独立创始人和使用 Cursor、Claude Code、Codex、Replit、Lovable、Bolt、v0 等 AI 编程工具构建应用的氛围编码者(vibe coder)设计。
它会扫描 AI 构建的 SaaS 应用,检查那些编程助手经常忽略的生产级基础项:
- auth 和授权漏洞
- 暴露的密钥和不安全的 env 使用
- Supabase RLS/数据库隔离问题
- Stripe/Razorpay webhook 安全性
- 速率限制、CORS、验证和安全标头
- 缺失的冒烟测试和部署就绪性
- 有风险的 AI 助手差异(如删除测试、大规模重写,或未经核实的 auth/支付更改)
目标很简单:
```
Run one command before deploy. Know if your vibe-coded app is safe to ship.
```
## 状态
BeforeShip 目前是一个本地优先的 CLI 测试版。
```
npm install
npx beforeship scan
```
当前检查项:
- 针对 Next.js、Supabase、Stripe/Razorpay、Vercel 和 env 文件的基础技术栈检测
- 已提交 env 文件警告
- 针对 OpenAI、Supabase JWT 风格密钥、Stripe 和 Razorpay 的类密钥 token 检测
- Next.js API 路由 auth 守卫和受信任用户 ID 启发式检查
- Stripe/Razorpay webhook 签名和幂等性启发式检查
- Supabase service-role、RLS、owner-policy 和 public-bucket 启发式检查
- 针对 CORS 通配符、auth 路由速率限制和输入验证的 API 安全检查
- 针对 tests、health 路由和 `.env.example` 的 Next.js 部署就绪检查
- 评分/判定引擎
- 位于 `.beforeship/` 下的 markdown 和 JSON 报告
- 具有命名终止状态和循环记忆的有界验证循环
- 适配 AI 助手的修复 prompt
演示样例:
```
npx beforeship scan examples/flawed-next-supabase-app --no-report
```
该样例应返回 `DO NOT SHIP`,并显示 BeforeShip 旨在捕获的发布阻碍因素。
仓库级别的扫描会遵循 `.beforeshipignore`,该文件会特意排除这个有缺陷的样例。
预期的 MVP 是:
```
CLI first + MCP server + optional GitHub Action
```
初始目标技术栈:
```
Next.js + Supabase + Stripe/Razorpay + Vercel
```
## 为什么选择 BeforeShip?
AI 编程工具让创建可运行的应用变得容易,但验证其是否具备生产就绪状态却很困难。
一个氛围编码(vibe-coded)的应用可能看起来完成了 90%,但却缺少危险且不可见的关键部分:
- 支付 webhook 签名验证
- 数据库行级安全
- 服务端 auth 检查
- 安全的 API key 处理
- 速率限制
- 回滚和冒烟测试
- 部署环境变量隔离
BeforeShip 是缺失的部署前关卡,位于:
```
"It works locally"
```
和:
```
"It is safe to launch"
```
## 产品理念
BeforeShip 并非旨在取代 Semgrep、Snyk、CodeQL、Gitleaks 或人工审查。
它旨在编排并解释独立创始人在部署 AI 构建的 SaaS 应用之前真正需要的检查。
## CLI
```
npx beforeship init
npx beforeship scan
npx beforeship scan --json
npx beforeship scan --output .beforeship
npx beforeship fix-prompts
npx beforeship loop --max-iterations 3
npx beforeship --version
```
### 从此仓库使用
```
npm install
npm test
npx beforeship --version
npx beforeship init .
npx beforeship scan . --no-report
npx beforeship scan . --json --no-report
npx beforeship scan . --output .beforeship
npx beforeship fix-prompts examples/flawed-next-supabase-app
npx beforeship loop . --max-iterations 3
```
### 命令
| 命令 | 用途 |
|---|---|
| `init [path] --name ` | 创建 `beforeship.config.yml` |
| `scan [path]` | 扫描本地应用并生成报告 |
| `scan [path] --no-report` | 打印结果而不生成报告文件 |
| `scan [path] --json --no-report` | 打印机器可读的 JSON |
| `scan [path] --output ` | 将报告写入自定义目录 |
| `fix-prompts [path]` | 打印用于修复问题的针对性 prompt |
| `loop [path] --max-iterations 3` | 运行有界验证循环 |
| `--version` | 打印 CLI 版本 |
退出码:
```
0 SHIP / command succeeded
1 tool error
2 launch gate blocked
```
创建配置:
```
npx beforeship init /path/to/app --name my-app
```
配置示例:
```
project:
name: my-app
stack:
- nextjs
- supabase
scan:
exclude:
- "node_modules/**"
- ".next/**"
- "dist/**"
verdict:
fail_on_critical: true
minimum_score: 70
caution_score: 90
output:
directory: ".beforeship"
formats:
- markdown
- json
```
由 `scan` 生成的报告:
```
.beforeship/
launch-report.md
findings.json
fix-prompts.md
loop-memory.json
```
输出示例:
```
BeforeShip launch gate
Score: 42/100
Verdict: DO NOT SHIP
Stack: nextjs, supabase, stripe
Top findings:
- [CRITICAL] Stripe webhook does not verify its signature
app/api/stripe/webhook/route.ts
- [CRITICAL] Supabase service role appears in client-reachable code
lib/supabase-client.ts
Counts: 2 critical, 3 high, 4 medium, 1 low
Next steps:
1. Run `beforeship fix-prompts` to generate focused agent prompts.
2. Fix critical findings one at a time.
3. Rerun `beforeship scan` before deploy.
```
## 计划中的 MCP 工具
BeforeShip 应该提供少量高杠杆的 MCP 工具,而不是庞大且臃肿的工具列表。
```
before_ship_scan
before_ship_explain
before_ship_fix_plan
before_ship_gate_deploy
```
可选项:
```
before_ship_agent_policy
```
## 计划中的检查
### 密钥
- `.env` 被提交
- 前端 bundle 中包含 API key
- `NEXT_PUBLIC_` 误用
- Supabase service-role 暴露
- OpenAI/Anthropic/GitHub 密钥暴露
- Stripe/Razorpay 密钥暴露
- Cursor/agent 上下文包含机密文件
### 认证
- 缺少 session/auth 守卫的 API 路由
- 缺少服务端保护的 admin 页面
- 从 body/query 中信任用户 ID
- IDOR 模式
- auth middleware 存在但未使用
- 角色检查仅在客户端执行
### Supabase / 数据库
- RLS 被禁用
- 包含用户数据但缺少 owner-policy 的表
- 在服务器之外使用 service-role
- public anon key 误用
- 迁移漂移
- 不安全的存储桶
### 支付
- 缺少 Stripe/Razorpay webhook 签名
- 缺少幂等性
- 从前端信任订阅状态
- 在客户端选择价格/计划
- 账单国家/货币未经服务端验证
- 缺少权限表
- 支付成功页在未验证 webhook 的情况下授予访问权限
### API 安全
- 通配符 CORS
- 无速率限制
- 无输入验证
- cookie auth 流程缺少 CSRF
- 冗长的错误信息
- 不安全的文件上传
- 缺少安全标头
- SSRF 模式
### 部署就绪
- 无 health endpoint
- 无冒烟测试
- 无回滚说明
- 缺少环境变量
- Vercel serverless 超时风险
- 关键路由缺少日志
- 无 staging/prod 隔离
### 特定于 AI 助手的检查
- 庞大的 AI 生成文件
- 重复的全文件重写
- 删除测试
- 无故添加新依赖
- 在没有测试的情况下更改 auth/payment/db 文件
- 破坏性脚本/迁移
- 无 `AGENTS.md` / `CLAUDE.md`
- agent 修改了声明范围之外的文件
- diff 包含临时的 auth 绕过
- 修改测试以适应损坏的代码
## 计划中的报告文件
```
.beforeship/
config.yml
launch-report.md
findings.json
fix-prompts.md
evidence/
```
问题示例:
```
{
"id": "payment.webhook.signature_missing",
"severity": "critical",
"file": "web/src/app/api/razorpay/webhook/route.ts",
"title": "Razorpay webhook does not verify signature",
"why_it_matters": "Anyone can fake a payment success event and unlock access.",
"fix_prompt": "Add Razorpay webhook signature verification using RAZORPAY_WEBHOOK_SECRET. Reject unsigned or invalid payloads. Add a regression test."
}
```
## OpenAI 的契合点
BeforeShip 应优先使用确定性检查,其次使用 OpenAI 推理。
OpenAI 可以协助:
- 感知技术栈的风险分级
- 对创始人友好的解释
- 修复 prompt 生成
- 测试计划生成
- 减少误报
- 针对 AI agent 的部署关卡推理
它不应仅依赖 LLM 来进行安全判断。
## 仓库结构
当前仓库以文档优先。
计划的实现形态:
```
beforeship/
packages/
cli/
core/
mcp/
github-action/
docs/
research.md
product-spec.md
roadmap.md
examples/
flawed-next-supabase-app/
```
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:CI/CD检查, MCP, MITM代理, SaaS, SOC Prime, 代码安全审计, 开发工具, 文档结构分析, 自定义脚本