glenlouis8/remedi
GitHub: glenlouis8/remedi
基于 LangGraph 的 AI 驱动 AWS 安全扫描与自动修复平台,覆盖八项核心服务的 CIS Benchmark 合规检查,带人工审批安全门的完整扫描-修复-验证闭环。
Stars: 0 | Forks: 0
# Remedi
**基于 AI 驱动的 AWS 安全扫描器与自动修复工具。**
**在线演示:** https://remedi-kohl-seven.vercel.app/
Remedi 会扫描您 AWS 账户中的 8 项服务,生成结构化的调查结果报告,暂停并等待人工审批,然后自动修复其发现的所有漏洞。随后会进行一轮验证,确认修复措施是否生效。



## 工作原理
建立在 LangGraph 之上的五阶段流水线,带有强制性的人工干预 安全门:
```
orchestrator → report_generator → safety_gate ─[your approval]─► remediator → verifier → done
```
1. **扫描** — 8 个专门的 AI 代理并行运行(每个 AWS 服务对应一个)。每个代理都有其独立的 LLM 调用循环、专用工具集和结构化的输出格式。
2. **报告** — 调查结果会被合成为一份修复计划。每个漏洞都会映射到用于修复它的具体工具上。CIS Benchmark 控制项会同步更新。
3. **安全门** — 执行暂停。您可以在控制台中审查该计划,并决定批准或中止。未经您的签字许可,不会进行任何更改。
4. **修复** — 所有获批的修复措施将并行运行。每项操作都会记录其持续时间和结果。
5. **验证** — 代理仅重新审计它修复过的资源,确认修复措施是否生效,然后关闭此次扫描。
## 覆盖的服务
| 服务 | 检查内容 | 自动修复 |
|---------|---------------|----------|
| **IAM** | 拥有 `AdministratorAccess` 或 `PowerUserAccess` 权限的用户 | 剥离所有策略,附加 `ReadOnlyAccess` |
| **S3** | 启用了公有访问权限的存储桶 | 启用所有 4 项“阻止公有访问”标志 |
| **VPC** | 未启用流日志的 VPC | 创建 CloudWatch 日志组 + IAM 角色 + 启用流日志 |
| **安全组** | 向 `0.0.0.0/0` 开放入站规则的组 | 撤销特定的公有规则(保持私有规则不变) |
| **EC2** | 启用了 IMDSv1;未加密的根卷 | 强制使用 IMDSv2;停止实例(隔离) |
| **RDS** | 可公开访问的数据库实例 | 立即将 `PubliclyAccessible` 设置为 `false` |
| **Lambda** | 执行角色拥有 `AdministratorAccess` 或通配符 `Action: *` | 分离过度授权的策略,附加 `AWSLambdaBasicExecutionRole` |
| **CloudTrail** | 日志记录已禁用或不存在跟踪 | 创建跟踪 + 具有正确策略的 S3 存储桶;启动日志记录 |
## 架构
```
┌──────────────────────────────────────────────────┐
│ frontend/ │
└───────────────────┬──────────────────────────────┘
│ HTTP / StreamingResponse
┌───────────────────▼──────────────────────────────┐
│ server.py │
│ FastAPI · ProcessManager │
│ Clerk JWT auth · Fernet encryption · PostgreSQL │
└───────────────────┬──────────────────────────────┘
│ subprocess (stdin/stdout)
┌───────────────────▼──────────────────────────────┐
│ main.py │
│ LangGraph agent pipeline (5 phases) │
│ orchestrator · report_generator · safety_gate │
│ remediator · verifier │
└───────────────────┬──────────────────────────────┘
│ MCP JSON-RPC over stdio
┌───────────────────▼──────────────────────────────┐
│ mcp_server/main.py │
│ FastMCP · boto3 · All AWS API calls │
└──────────────────────────────────────────────────┘
```
**关键设计决策:**
- **MCP 子进程隔离** — 所有 boto3 调用都位于单独的进程 (`mcp_server/main.py`) 中。代理通过 stdio 上的 JSON-RPC(即模型上下文协议)进行通信。AWS 凭证永远不会接触到主进程。
- **并行模型** — 编排器通过 `ThreadPoolExecutor` 同时触发所有 8 个专门代理。单个代理内的工具调用是顺序执行的(MCP 管道是单线程的)。修复器也支持并行化——所有获批的修复将并发运行。
- **修复阶段无 LLM 解析步骤** — 修复器直接使用正则表达式解析报告 (`🔴 [CRITICAL] is vulnerable -> ACTION: I will call \`tool_name\``)。无需额外的 LLM 调用,无需处理 JSON,也没有延迟。
- **Token 优化** — 报告生成器仅接收审计员的最终总结,而不是完整的工具调用历史。与传递整个消息链相比,可节省约 80% 的 token。
## 技术栈
**后端:** Python · FastAPI · LangGraph · Google Gemini · MCP · PostgreSQL · Clerk
**前端:** Next.js 15 · TypeScript · Tailwind CSS · Clerk
**基础设施:** Railway · CloudFormation · Terraform (测试环境)
## 开始使用
**[remedi-kohl-seven.vercel.app](https://remedi-kohl-seven.vercel.app/)** — 登录,连接您的 AWS 账户,然后运行扫描。
## CIS Benchmark 合规性
每项检查都映射到一个 CIS AWS Foundations Benchmark 控制项。控制台会跟踪每个控制项的通过/失败状态,并显示在每次扫描后实时更新的整体合规性评分。
| CIS 控制项 | 检查内容 |
|-------------|-------|
| 1.16 | IAM 策略未直接附加到用户 |
| 2.1.5 | S3 已配置阻止公有访问 |
| 2.3.3 | RDS 实例无法公开访问 |
| 3.1 | 在所有区域中启用 CloudTrail |
| 3.9 | 启用 VPC 流日志 |
| 5.2 | 没有具有 unrestricted access 的安全组 |
| 5.4 | Lambda 执行角色遵循最小权限原则 |
| 5.6 | EC2 实例使用 IMDSv2 和加密卷 |
## 凭证安全
AWS 凭证永远不会以明文形式存储:
- **静态 Fernet 加密** — 访问密钥和秘密密钥在写入 PostgreSQL 之前会被加密
- **30 分钟不活动清除** — 后台线程会删除闲置超过 30 分钟的凭证
- **登出时显式删除** — 用户登出时,凭证会立即被清除
- **自动保护** — 其凭证正在被使用的 IAM 用户始终会被添加到保护列表中,永远不会被修复操作改动
## 已知限制
- **单一区域** — 仅扫描 `us-east-1`。扫描器无法查看其他区域中的资源。
- **EC2 根卷重新加密** — 尚未自动化。具有未加密根卷的实例将被隔离(停止),而不是进行重新加密。完整的重新加密需要手动快照工作流。
- **`AegisFlowLogRole`** — 在 VPC 流日志修复期间创建的 IAM 角色将在您的账户中跨扫描保留。如果您需要彻底清理,请手动删除它。
- **每个账户每天限扫 3 次** — 平台强制执行的速率限制。
## 测试
包含 25 个涵盖关键路径的测试——无需外部服务。
```
# 安装 test dependencies
uv add pytest "moto[s3,iam,ec2,rds,cloudtrail,logs]" httpx --dev
# 运行
.venv/bin/python -m pytest tests/ -v
```
**`tests/test_accounts.py`** — Fernet 凭证加密
| 测试 | 验证内容 |
|------|-----------------|
| `test_encrypt_decrypt_roundtrip` | 加密的 AWS 凭证能解密回原始值 |
| `test_secret_key_roundtrip` | 秘密密钥在经历加密 → 解密循环后保持完好 |
| `test_missing_encryption_key_raises` | 缺少 `ENCRYPTION_KEY` 环境变量时会抛出错误,而不是静默失败 |
| `test_different_keys_cannot_decrypt` | 使用一个密钥加密的凭证无法用另一个不同的密钥解密 |
**`tests/test_mcp_tools.py`** — AWS 修复工具(对 moto 内存中的 AWS 运行生产环境的 boto3 代码)
| 测试 | 验证内容 |
|------|-----------------|
| `test_remediate_s3_blocks_all_public_access` | 修复公有存储桶会启用所有 4 项“阻止公有访问”标志 |
| `test_audit_s3_detects_public_bucket` | 审计程序能正确标记启用了公有访问的存储桶 |
| `test_audit_s3_detects_secure_bucket` | 审计程序不会标记已经安全的存储桶 |
| `test_audit_s3_no_buckets` | 审计程序能无误地处理没有 S3 存储桶的账户 |
| `test_restrict_iam_user_strips_inline_policies` | 修复权限过高的 IAM 用户会剥离所有内联策略 |
| `test_list_iam_users_returns_all` | IAM 用户列表工具能返回账户中的每一个用户 |
| `test_revoke_security_group_ingress_removes_public_rule` | 撤销工具会从安全组中移除 `0.0.0.0/0` 入站规则 |
| `test_revoke_idempotent_when_already_clean` | 对已清理的安全组运行撤销工具不会报错(幂等性) |
| `test_audit_security_groups_flags_open_world` | 审计程序会标记具有 unrestricted 入站访问权限的安全组 |
| `test_enforce_imdsv2` | *(xfail)* 已跳过 — moto 未实现 `modify_instance_metadata_options` |
| `test_audit_ec2_finds_running_instances` | 审计程序能正确枚举正在运行的 EC2 实例 |
| `test_remediate_rds_disables_public_access` | 修复合有的 RDS 实例会将其 `PubliclyAccessible` 设置为 `false` |
| `test_audit_rds_detects_public_instance` | 审计程序会标记启用了公有访问的 RDS 实例 |
**`tests/test_remediator.py`** — 报告解析器(通过正则表达式从 AI 报告中提取修复任务)
| 测试 | 验证内容 |
|------|-----------------|
| `test_single_finding_parse` | 单行 `🔴 [CRITICAL]` 恰好生成一个修复任务 |
| `test_multiple_findings_parse` | 一份报告中的多个发现分别生成独立的任务 |
| `test_secure_system_returns_no_tasks` | 没有关键行的干净报告生成零个任务 |
| `test_all_nine_tools_are_recognized` | 修复器支持的每个工具名都能被正则表达式正确匹配 |
| `test_resource_name_with_hyphens_and_numbers` | 类似 `my-bucket-123` 的资源名能无误解析 |
| `test_resource_name_with_dots` | 带有英文句号的资源名(如 `prod.db`)能无误解析 |
| `test_zero_tasks_from_empty_string` | 空报告字符串生成零个任务且不会导致崩溃 |
| `test_manual_review_line_not_parsed` | 标记为需要人工复查的行不会被错误地排入自动化任务队列 |
**结果: 24 项通过,1 项预期失败 (符合预期 — moto 限制)**
## 部署
部署在 Railway 上。后端 (`uvicorn server:app`) 和前端 作为独立的 Railway 服务运行。`railway.toml` 设置了启动命令。`frontend/Dockerfile` 负责处理容器化的前端构建。
标签:AI安全, Anthropic, AWS安全, Chat Copilot, CIS基准, DevSecOps, DLL 劫持, EC2安全, FTP漏洞扫描, IAM安全, JSONLines, LangGraph, OSV, PE 加载器, Python, S3安全, Vercel, VPC流日志, 上游代理, 云计算, 人机协同, 加密, 大语言模型, 安全组, 安全编排, 态势管理, 插件系统, 无后门, 测试用例, 漏洞扫描器, 网络安全, 自动修复, 自动化与响应, 自动化攻击, 规则引擎, 逆向工具, 隐私保护, 零信任