kenlacroix/palisade

GitHub: kenlacroix/palisade

一款攻击面监控工具,通过仅在主机本地运行扫描的拉取式 agent 与 FastAPI 控制面,为自托管和 AI 基础设施提供保护数据隐私的 CVE 检测与安全态势管理。

Stars: 0 | Forks: 0

# Palisade **针对自托管和 AI 基础设施服务的攻击面监控。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e65d275fd8065638.svg)](https://github.com/kenlacroix/palisade/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/kenlacroix/palisade?sort=semver&color=2da44e)](https://github.com/kenlacroix/palisade/releases) [![Agent: Go](https://img.shields.io/badge/agent-Go%201.22-00ADD8?logo=go&logoColor=white)](agent/) [![Control plane: FastAPI](https://img.shields.io/badge/control%20plane-FastAPI-009688?logo=fastapi&logoColor=white)](control-plane/) [![Web: React + TS](https://img.shields.io/badge/web-React%20%2B%20TS-61DAFB?logo=react&logoColor=white)](web/) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) **[trypalisade.dev](https://trypalisade.dev)** · [在线演示](https://app.trypalisade.dev) · [快速开始](#quickstart-zero-infra-sqlite) · [架构](#architecture) · [设计决策](docs/design-decisions.md) ![Palisade 演示](https://raw.githubusercontent.com/kenlacroix/palisade/main/docs/screenshots/demo.gif)
**仅拉取** 的 agent 注册一次,在本地发现监听服务,并在本地运行 CVE 检测 —— **只有标准化后的 findings 会离开主机**。 FastAPI control plane 提供签名的检测目录,接收 findings,评估安全态势(包含真实的 30 天趋势),针对新增/复发的 findings 发出警报,并利用 LLM 从 CVE 公告中生成新检测草案。 - **Agent 留在主机,数据不外泄** — 发现和扫描均在本地运行;主机的原始攻击面永远不会外泄。 - **签名的检测目录** — agent 在运行*任何*检测之前,会验证 Ed25519 签名的 bundle;验证失败则默认拒绝。 - **版本感知匹配** — 检测基于服务*和*版本范围触发,因此 `litellm <1.40.2` 会跳过 `1.41.0`。 - **态势、趋势与警报** — 真实的 30 天安全态势评分,并带有针对新增和复发 findings 的频道/规则告警。 - **AI 介入** — 根据 CVE 公告起草检测草案,并在请求路径之外对 findings 进行分类。 - **原生多租户** — 用户、组织、会话认证、RBAC,以及 Postgres 基于 `org_id` 的行级隔离。 ## 架构 | 组件 | 路径 | 技术栈 | |-----------|------|-------| | **Control plane** | `control-plane/` | FastAPI + SQLAlchemy + Alembic(默认 sqlite,compose 中为 Postgres) | | **Agent** | `agent/` | Go 1.22,仅依赖标准库,运行在每个受监控的主机上 | | **Web UI** | `web/` | React + TypeScript + Vite + Tailwind | | **Detections** | `detections/` | 根据 `detection.schema.json` 验证的 YAML 规格 | 完整循环:agent **注册 (enroll)** → **心跳 (heartbeat)** → control plane 下发 **发现 (discover)** 任务 → agent 上报 **资产 (assets)** → 心跳下发 **扫描 (scan)** 任务(通过服务 **和** 版本范围匹配检测) → agent 拉取 **签名的目录 bundle**,进行验证并在主机上运行检测 → 上报 **findings** → control plane 对 **安全态势** 进行评分,评估 **告警规则**(在后台传递匹配的告警),并(可选地)通过 **AI** 在请求路径之外对每个 finding 进行分类。 Web UI 是多租户的:登录(演示中为 `demo@palisade.local` / `palisade`),所有 `/v1` 读取端点都将限定于您当前活跃的组织,并具备基于角色的访问权限(owner/admin/member/viewer)。 ## 一键体验 在您自己的环境中查看整个产品运行的最快方式。它会启动 control plane、Web UI、Postgres 以及一个自动注册并扫描内置故意暴露漏洞目标的 agent —— 构建于一个预置的组织之上,因此每个屏幕(Dashboard、Assets、Findings、Detections、Alerts)在加载瞬间即有数据填充。 ``` make demo # docker compose: api + web + postgres + agent + target # 打开 http://localhost:8080 — 使用 demo@palisade.local / palisade 登录 make demo-down # tear down (removes volumes for a clean re-run) ``` 在大约 20-40 秒内,agent 会完成注册、发现目标,并出现一个真实的严重 finding(`litellm-proxy-preauth-sqli`,CVE-2026-42208)与预置数据并列 —— 完整的 **注册 → 发现 → 扫描 → finding → 态势** 循环,端到端,无需手动步骤。 有两个标志位驱动演示(由 `make demo` 自动设置): | 变量 | 效果 | |-----|--------| | `PALISADE_SEED_DEMO=1` | 在引导时为演示组织填充逼真的资产、findings、30 天安全态势趋势、告警和审计历史(幂等)。 | | `PALISADE_DEMO_MODE=1` | 使公开演示对已登录用户变为 **只读**(agent 摄取仍可写入);在 UI 中展示“在线演示”横幅。 | 两者默认关闭,因此除非您主动开启,开发和自托管生产环境的行为将与之前完全一致。要在不使用 Docker 的情况下填充本地 sqlite 运行,请在启动 control plane 之前设置 `PALISADE_SEED_DEMO=1`。 要监控您 **自己** 的主机而不是内置目标:在 UI 中生成一个注册 token(**Add agent**),然后在该主机上运行 agent 二进制文件(`palisade enroll --token --server ` → `palisade run`)。 ## 界面展示 使用了 `PALISADE_SEED_DEMO=1`(每个屏幕均已填充)和 `PALISADE_DEMO_MODE=1`(只读的“在线演示”横幅)的门户。 | | | |---|---| | **Dashboard** — 安全态势评分、30 天趋势、需关注项 | **Finding 详情** — 证据、指纹、修复建议、参考 | | [![Dashboard](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/ff074a4273065709.png)](docs/screenshots/01-dashboard.png) | [![Finding 详情](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/bc1ddd5e6e065711.png)](docs/screenshots/02-finding-detail.png) | | **Assets** — 发现的服务、版本、暴露情况、findings | **Detections** — 带有 CVSS 和租户命中数的签名 CVE 目录 | | [![Assets](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/e49ba83256065712.png)](docs/screenshots/03-assets.png) | [![Detections](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/9282a326e7065714.png)](docs/screenshots/04-detections.png) | | **Alerts** — 频道、规则、免打扰时段、历史记录 | | | [![Alerts](https://raw.githubusercontent.com/kenlacroix/palisade/main/docs/screenshots/05-alerts.png)](docs/screenshots/05-alerts.png) | | ## 快速开始(零基础设施,sqlite) 需要 Go 1.22+、Python 3.12、Node 18+。 ``` # 1. control plane make venv # create control-plane/.venv + install deps make migrate # apply migrations (sqlite:///./palisade.db) cd control-plane && PALISADE_ENROLL_TOKENS=PLS-DEMO \ ./.venv/bin/uvicorn app.main:app --reload # http://127.0.0.1:8000/docs # 2. web UI(单独的终端)— vite 将 /v1 代理到 control plane cd web && npm install && npm run dev # http://127.0.0.1:5173 ``` 或者在 Docker 中运行整个技术栈(FastAPI + Postgres): ``` cd control-plane && cp .env.example .env && docker compose up --build ``` ## 端到端演示 `DEMO.md` 演练了完整的本地主机循环:启动 control plane,在 4000 端口暴露一个模拟易受攻击的 LiteLLM 目标,注册并运行 agent,通过读取 API 观察真实的严重 finding(`litellm-proxy-preauth-sqli`,CVE-2026-42208)出现,然后将其静音并观察态势如何恢复。 ``` make smoke # enroll → discover → assets → scan → findings → posture (temp DB) ``` ## 签名的目录 bundle Control plane 通过规范清单使用 Ed25519 对检测 bundle 进行签名;agent 重建相同的清单,并在运行 **任何** 检测之前根据锁定的公钥对其进行验证 —— 确保不受信任通道上的完整性。`.env.example` 中提供了一对演示密钥。 ``` # control plane:启用使用 demo key 进行签名 cd control-plane PALISADE_SIGNING_KEY=70kJtI1NajTd1yQXFHVRuBVQfc6P2CAtRroaLCmYYbY= \ ./.venv/bin/uvicorn app.main:app --reload ``` Agent 锁定了匹配的公钥(可通过 `PALISADE_CATALOG_PUBKEY` 覆盖);内置的默认值与演示种子相匹配。验证策略: - 空签名 → 拒绝扫描; - `"stub"`(未设置签名密钥) → 在开发模式下继续并给出警告; - 其他 → 进行验证,如果失败则拒绝运行检测。 生成您自己的密钥对: ``` cd control-plane && ./.venv/bin/python -c "import os,base64;from app import _ed25519 as e;s=os.urandom(32);print('PALISADE_SIGNING_KEY=',base64.b64encode(s).decode());print('pubkey =',base64.b64encode(e.publickey(s)).decode())" ``` 将打印出的 seed 设为 control plane 的 `PALISADE_SIGNING_KEY`,并将 pubkey 设为 agent 的 `PALISADE_CATALOG_PUBKEY`。 ## 起草 → 审查 → 接受(闭环) 在 **Detections** 屏幕中,**+ New from CVE URL** 会利用 LLM 根据公告起草检测(需要在 control plane 上设置 `ANTHROPIC_API_KEY`;否则端点返回 503)。审查草案,然后点击 **Accept & ship** 将其持久化 —— 这会增加目录版本号,以便 agent 在下次拉取 bundle 时获取它。等效的 API 调用(需要 admin+ 会话 bearer token;有关 `$TOKEN` 详情请参见 DEMO.md): ``` curl -s -X POST http://127.0.0.1:8000/v1/detections \ -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' -d '{ "id":"acme-rce","title":"ACME RCE","cve":"CVE-2026-9999","severity":"high", "category":"web","engine":"nuclei","match":{"service":"acme","versions":"<2.0.0"}, "http":[{"method":"GET","path":"/x","matchers":[{"type":"status","status":[200]}]}], "remediation":"upgrade to >=2.0.0","references":["https://example.com"],"cvss":7.5 }' # -> {"id":"acme-rce","version":} ``` ## 版本感知的扫描匹配 检测通过服务 **和** 版本范围来定位资产。`match.versions` 接受逗号/空格分隔的约束条件(`<1.40.2`,`>=11.1.4 <15.2.3`);一个针对 `litellm <1.40.2` 的检测会在 `1.39.0` 上触发,但不会在 `1.41.0` 上触发。未知/缺失的资产版本会 **放行**(依然进行扫描),因此漏洞永远不会被默默跳过。 ## AI 分类 设置 `ANTHROPIC_API_KEY` 后,新的 findings 会在摄取后被评分(`triage_priority` / `triage_score` / `triage_rationale`,展示在 finding 读取 API 中)。这是尽最大努力执行的,并在摄取请求路径之外的后台任务中运行 —— 它永远不会阻塞或导致摄取失败,如果没有设置密钥则不执行任何操作。`PALISADE_TRIAGE_MODEL` 可覆盖模型(默认为 `claude-haiku-4-5-20251001`)。 ## 告警 从 **Alerts** 屏幕或 API 定义 **频道**(telegram / 电子邮件 / webhook)和 **规则**(`min_severity` + `on_events` `[new|regressed]` → 频道)。在摄取 finding 时,匹配的规则会触发,告警会在后台任务中传递;告警历史记录将被保留并展示在 `GET /v1/alerts`。频道密钥在读取时会被隐藏。 ``` BASE=http://127.0.0.1:8000; UAUTH="Authorization: Bearer $TOKEN" # see DEMO.md for $TOKEN # webhook channel + 一条在任何 high+ 新增/回归 finding 上触发的规则 CH=$(curl -s -X POST $BASE/v1/alert-channels -H "$UAUTH" -H 'content-type: application/json' \ -d '{"type":"webhook","name":"local","config":{"url":"http://127.0.0.1:9000/hook"}}' \ | python3 -c "import sys,json;print(json.load(sys.stdin)['id'])") curl -s -X POST $BASE/v1/alert-rules -H "$UAUTH" -H 'content-type: application/json' \ -d "{\"name\":\"high+\",\"min_severity\":\"high\",\"on_events\":[\"new\",\"regressed\"],\"channel_id\":\"$CH\"}" ``` ## 测试 ``` make test # Go agent tests + smoke + detection validation cd control-plane && ./.venv/bin/python -m app.api_test # new endpoint coverage (signed path) cd control-plane && ./.venv/bin/python -m app.smoke_test # full loop (unsigned path) cd agent && go test ./... # agent unit tests incl. manifest verify ``` `pytest` 是可选的;两个 Python 测试模块都通过 `python -m` 作为普通脚本运行。 ## 配置 所有配置项均位于 `control-plane/app/config.py` 中,从环境变量读取 —— 有关完整的配置表,请参见 `control-plane/.env.example` 和 `control-plane/README.md`。 关键变量: | 变量 | 默认值 | 备注 | |-----|---------|-------| | `DATABASE_URL` | `sqlite:///./palisade.db` | Compose 会设置 Postgres URL。 | | `PALISADE_ENROLL_TOKENS` | `PLS-DEMO` | 逗号分隔、一次性使用的注册 token(每个 token 生成一个 agent 加入该 token 对应的组织)。 | | `PALISADE_DEMO_USER_EMAIL` | `demo@palisade.local` | 在引导时植入的演示组织 owner。 | | `PALISADE_DEMO_USER_PASSWORD` | `palisade` | 演示用户密码。 | | `PALISADE_SESSION_TTL_S` | `604800` (7天) | Web UI bearer-session 的生命周期(秒)。 | | `PALISADE_SIGNING_KEY` | 未设置(演示密钥) | 用于 bundle 签名的 Ed25519 seed(base64)。未设置时会使用 **公开的** 演示密钥进行签名并发出警告 —— 在生产环境中请务必设置此项。 | | `PALISADE_CATALOG_PUBKEY` | 演示密钥 | Agent 端锁定的 bundle 公钥(base64);必须与签名密钥匹配。 | | `PALISADE_ALLOW_UNSIGNED` | 未设置 | Agent 的开发环境逃生舱 —— 如果设置,将运行未签名/`stub` 的 bundle 而不是拒绝。在生产环境中绝对不能设置。 | | `ANTHROPIC_API_KEY` | 未设置 | 启用 AI 起草 + finding 分类。 | | `PALISADE_DETECTIONS_DIR` | 仓库的 `detections/` 目录 | 植入检测 YAML 的来源。 | ## 状态 已实现:注册/心跳/扫描循环,**Ed25519 签名的目录 bundle**(agent 在运行任何检测前会进行验证,失败即终止;`detections/README.md` 涵盖了密钥生成/轮换),版本感知匹配,AI 起草及接受循环,CVSS,后台 AI 分类,包含真实 30 天趋势的安全态势评分,多租户(用户/会话/组织 + RBAC,一次性注册 token,基于 `org_id` 的 Postgres 行级安全),告警(频道/规则/历史记录),agent **mTLS**(注册时从内部 CA 颁客户端证书;在 TLS 终结代理处验证,并将 bearer `agent_secret` 作为纯文本演示的备选方案),以及一个 `SECURITY DEFINER` 路径,确保在 Postgres 的 RLS 下跨租户目录聚合(`tenants_hit` / `tenants_total`)数据正确,一个持久的 **Arq + Redis** 队列/worker 用于 AI 分类和告警传递(当未设置 `REDIS_URL` 时,使用进程内的 `BackgroundTasks` 作为备选),以及一个可插拔的 **`module`** 检测引擎(agent 中编译好的 `spec_ref` 注册表;第一个模块是 Next.js middleware 绕过,CVE-2025-29927),**基于每个组织的静态证据加密**(AES-256-GCM,基于按组织封装的数据密钥,migration 0005),以及 **基于规则的告警免打扰时段**(推迟传递,在窗口关闭时释放,migration 0007)。尚未构建(参见 `SPEC.md`):生产运维层 —— IaC、实时部署、公开状态页面、可观测性仪表盘和运维手册。 ## License [Apache License 2.0](LICENSE) — © 2026 Kenneth Lacroix.
由 [Kenneth Lacroix](https://kennethlacroix.me) 构建 · [trypalisade.dev](https://trypalisade.dev)
标签:AI基础设施安全, AV绕过, FastAPI, Go, React, Ruby工具, Syscalls, 安全态势管理, 实时处理, 插件系统, 攻击面监控, 无线安全, 日志审计, 测试用例, 请求拦截