MindStone-Agent/aegis-dashboard

GitHub: MindStone-Agent/aegis-dashboard

一款 OT/ICS 威胁情报只读仪表板,将 AI Agent 生成的结构化数据渲染为六大操作面板并集成实时 AI 分析师聊天。

Stars: 1 | Forks: 0

# AEGIS — OT/ICS 威胁情报仪表板 一个暗黑模式的战术界面,用于展示可操作的 OT/ICS 威胁情报,并配有实时的 AI 分析师聊天面板。作为 MindStone 平台 Phase 1 的一部分构建。 **版本:** 1.0 — Phase 1 前端原型(交付于 2026-03-18) **状态:** 生产级前端;Phase 2(后端代理 + WebSocket)已规划。 ## 功能简介 Aegis Dashboard 是一个单页应用,它读取由 MindStone Threat Analyst AI Agent 生成的五个结构化 JSON 文件,并将它们渲染到六个专门设计的操作面板中。其美学和信息密度源自专业的 SIEM/SOC 工具:Dragos Platform、暗黑模式 Splunk、Elastic Security。右侧聊天面板连接到 Open WebUI API(通过 SSE token 流式传输),并在未配置 API 时优雅降级到演示模式。 仪表板是只读的。不会向 JSON 文件写入任何数据。 ## 技术栈 | 层级 | 技术 | 版本 | |-------|-----------|---------| | 框架 | React | 18.3 | | 构建工具 | Vite | 6.x | | 语言 | TypeScript | 5.7 strict | | UI 状态 | Zustand | 5.x | | 服务端状态 / 轮询 | TanStack Query | 5.x | | 样式 | Tailwind CSS | 3.x | | Schema 验证 | Zod | 3.x | | Markdown 渲染 | react-markdown + rehype-highlight | 9.x / 7.x | | 图标 | lucide-react | 0.469 | | 日期格式化 | date-fns | 4.x | | ID 生成 | uuid | 11.x | 没有使用外部组件库。所有面板组件均基于 Aegis 设计 token 系统定制构建。 ## 快速开始 ### 前置条件 - Node.js 18+ 和 npm - 现代浏览器(推荐使用 Chrome 或 Edge;Phase 1 不支持 Safari) ### 安装与运行 ``` # 从项目根目录 npm install # 启动开发服务器 (http://localhost:5173) npm run dev ``` 仪表板会立即在演示模式下打开——无需配置。所有五个面板将使用 `public/data/` 中真实的 OT/ICS 模拟数据进行渲染。 ### 生产环境构建 ``` npm run build ``` 输出到 `dist/`。使用任何静态文件服务器提供服务,或运行 `npm run preview` 进行生产环境包的本地预览。 ## 配置 复制示例环境文件并根据需要进行编辑: ``` cp .env.example .env.local ``` | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `VITE_OPENWEBUI_URL` | _(空)_ | Open WebUI / MindStone 实例的 Base URL(例如 `http://localhost:3000`)。**留空将以演示模式运行。** | | `VITE_OPENWEBUI_API_KEY` | _(空)_ | Open WebUI API 的 Bearer token。仅在开发环境中使用;Vite 代理会注入它,因此在生产环境中该密钥永远不会到达浏览器。 | | `VITE_MODEL_ID` | `threat-analyst` | 在聊天补全请求中传递的 Model ID。 | 此处设置的环境变量仅为开发环境的默认值。在运行时,这三个值也可以通过应用内的 Settings 面板进行配置(持久化存储在 `localStorage` 中 `aegis-ui-store` 键下)。 ## 项目结构 ``` aegis-dashboard/ ├── public/ │ └── data/ # Mock JSON data files (served as static assets) │ ├── intel-feed.json │ ├── threat-groups.json │ ├── investigations.json │ ├── daily-summary.json │ └── system-health.json ├── src/ │ ├── App.tsx # TanStack Query provider + AppShell root │ ├── main.tsx # React DOM entry point │ ├── index.css # Global styles (scanline texture, animations) │ ├── schemas/ # Zod schemas — single source of truth for all types │ │ ├── intel-feed.ts │ │ ├── threat-groups.ts │ │ ├── investigations.ts │ │ ├── daily-summary.ts │ │ └── system-health.ts │ ├── hooks/ # Custom React hooks │ │ ├── useIntelFeed.ts │ │ ├── useThreatGroups.ts │ │ ├── useInvestigations.ts │ │ ├── useDailySummary.ts │ │ ├── useSystemHealth.ts │ │ └── useStreamingChat.ts │ ├── store/ │ │ └── uiStore.ts # Zustand store (chatOpen, settingsPanelOpen, settings) │ ├── lib/ │ │ ├── sort.ts # Sorting and deduplication utilities │ │ ├── staleness.ts # Staleness badge computation │ │ └── demoConversation.ts # Pre-loaded demo chat messages │ └── components/ │ ├── layout/ │ │ ├── AppShell.tsx # Root layout; keyboard shortcuts; offline detection │ │ ├── TopNav.tsx # 48px header; last-updated timestamp; refresh/settings │ │ ├── MainCanvas.tsx # Left intel column + right chat pane split │ │ └── FooterBar.tsx # 40px fixed footer; system health widget │ ├── panels/ │ │ ├── IntelFeedPanel.tsx + IntelFeedItem.tsx │ │ ├── ThreatGroupPanel.tsx + ThreatGroupCard.tsx │ │ ├── InvestigationsPanel.tsx + InvestigationCard.tsx │ │ └── DailySummaryPanel.tsx │ ├── chat/ │ │ ├── ChatPane.tsx │ │ ├── MessageThread.tsx │ │ ├── MessageInput.tsx │ │ ├── AgentMessage.tsx │ │ ├── UserMessage.tsx │ │ └── DemoModeOverlay.tsx │ └── shared/ │ ├── PriorityBadge.tsx │ ├── StatusBadge.tsx │ ├── ConfidenceBadge.tsx │ ├── StalenessBadge.tsx │ ├── SourceChip.tsx │ ├── CveTag.tsx │ ├── SkeletonPanel.tsx │ ├── ErrorBoundary.tsx │ ├── OfflineBanner.tsx │ └── SettingsPanel.tsx ├── .env.example ├── tailwind.config.ts ├── vite.config.ts ├── tsconfig.json └── package.json ``` ## 六大面板 ### 1. 威胁情报流 (`IntelFeedPanel`) 渲染来自 `intel-feed.json` 的条目,按 HIGH → MEDIUM → LOW 优先级排序。每个条目都可以展开以显示完整的 OT 相关性评估和分析师笔记。CVE 标签直接链接到 NVD 条目。在新的轮询周期中出现的条目会闪烁简短的高亮动画。 **数据结构概览:** `id`、`priority` (HIGH/MEDIUM/LOW)、`title`、`source`、`url`、`publishedAt`、`vendors[]`、`cves[]`、`otRelevance`、`analystNote`、`updatedAt`。 ### 2. 威胁组织追踪器 (`ThreatGroupPanel`) 被追踪威胁组织的卡片网格。在大屏幕上为两列,在小屏幕下为单列。每张卡片显示 nexus、状态 (ACTIVE/SILENT/PREPOSITIONING)、目标行业、ICS ATT&CK TTPs(带有“+N 更多”切换)、置信度评级以及可选的分析师笔记。 **数据结构概览:** `name`、`nexus`、`status`、`lastActivityDate`、`targetSectors[]`、`ttps[]`、`confidence` (HIGH/MEDIUM/LOW)、`notes`。 ### 3. 活跃调查 (`InvestigationsPanel`) 仅显示来自 `investigations.json` 的 ACTIVE 调查。每张卡片包含一个 9 阶段的 MITRE ATT&CK for ICS 阶段追踪器(从 INITIAL_ACCESS 到 IMPACT)、一个 fill/current/future 视觉进度条、带有置信度评级的假设,以及建议的后续行动列表。 **数据结构概览:** `id`、`scenarioName`、`sector`、`stage`(9 个 ATT&CK ICS 阶段之一)、`hypotheses[]`(hypothesis + confidence + notes)、`nextActions[]`、`analystNotes`、`status` (ACTIVE/CLOSED)。 ### 4. 每日情报摘要 (`DailySummaryPanel`) 显示 AI Agent 的每日摘要报告。通过 Previous/Next 导航浏览 `daily-summary.json` 中的历史记录(按最新优先排序,纯内存操作——导航时不会触发网络重新获取)。显示已检查的来源、按相关性排名前 3 的发现,以及当天触发的任何警报。 **数据结构概览:** `date` (YYYY-MM-DD)、`sourcesChecked[]`、`sourceCount`、`topFindings[]`(rank 1–3,description,source)、`alertsTriggered[]`(title,severity,triggeredAt)。 ### 5. 系统健康小组件 (`SystemHealthWidget`) 固定在 40px 的页脚处。一览显示 MindStone 平台的运行状态:上次 dream cycle 运行、向量库文档计数、剩余的 Brave Search 配额(归零时变红),以及 Anthropic 和 OpenAI 的 API 状态点。悬停或聚焦任何状态点会显示一个工具提示,其中包含上次检查的时间戳和错误信息(如果存在)。可以通过 Tab 焦点使用键盘访问工具提示。 **数据结构概览:** `lastDreamCycle` (runAt, chunksStored, status)、`vectorStore` (totalDocuments, lastUpdated)、`braveSearch` (estimatedQueriesRemaining, dailyQuota, queriesUsedToday)、`apis.anthropic`、`apis.openai`、`updatedAt`。 ### 6. 实时聊天面板 (`ChatPane`) 可折叠的右侧聊天界面。在大屏幕断点处宽度为 `w-80` (320px),在 xl 断点处为 `w-96` (384px)。在移动设备(`md` 断点以下)上隐藏。使用 `fetch()` + `ReadableStream` 通过 SSE 流连接到 Open WebUI API —— 不使用 EventSource 是因为它不支持 POST 请求。折叠时,面板会显示一个向右的箭头(指示展开方向)、一个放大的“ANALYST CHAT”标签,以及当会话包含消息时的脉冲活动指示器圆点。 面板顶部的会话选择下拉菜单列出了最近的会话。在演示模式下,提供三个预加载且包含完整消息历史的会话。在实时模式下,会从 `GET /api/v1/chats/` 获取会话。 ## 模拟数据 所有五个 JSON 文件都位于 `public/data/` 中,并作为 Vite 静态资源提供服务。它们包含相对于参考日期 2026-03-18 的真实的 OT/ICS 领域情报: | 文件 | 内容 | |------|----------| | `intel-feed.json` | 来自 CISA、Dragos、CloudSEK、Claroty 等的 11 条公告。包含多个 HIGH 优先级项目,包括 CVE-2024-43647 (Siemens S7-1500)。 | | `threat-groups.json` | 6 个被追踪的组织:VOLTZITE、ELECTRUM、KAMACITE、AZURITE、PYROXENE、SYLVANITE —— 源自公开的 Dragos 威胁组织命名约定。 | | `investigations.json` | 4 项调查:2 个 ACTIVE(一个早期阶段,一个晚期阶段),1 个 CLOSED,以及 1 个用于增加多样性的额外调查。 | | `daily-summary.json` | 截至 2026-03-18 的连续 7 份每日摘要。 | | `system-health.json` | 反映 MindStone 平台状态的单对象文件。 | 要使用真实的 Agent 输出仪表板,请用 MindStone Threat Analyst AI Agent 生成的 JSON 替换这些文件。这些文件必须继续通过 `src/schemas/` 中的 Zod schema 验证。 轮询间隔默认为 30 秒,可在 Settings 面板中进行配置(范围:10–300 秒)。 ## Open WebUI 聊天集成 ### 演示模式(默认) 当未设置 `VITE_OPENWEBUI_URL`,或 Settings 面板中的 Open WebUI URL 字段为空时,会自动激活演示模式。在演示模式下: - 显示分析师与 AI Agent 之间的预加载对话 (`src/lib/demoConversation.ts`) - 会话下拉菜单中提供三个演示会话(VOLTZITE 分析、GRAPHITE IOC、公告审查) - 发送消息会触发模拟的逐字流式响应,解释如何连接实时 endpoint - 不会向任何 API 发起网络调用 ### 连接到实时的 Open WebUI 实例 1. 点击顶部导航栏中的 **SETTINGS**(或在输入框外任意位置按 `S` 键) 2. 输入您的 Open WebUI URL(例如 `http://localhost:3000`) 3. 输入您的 API key 4. (可选)更改 Model ID(默认:`threat-analyst`) 5. 点击 **SAVE SETTINGS** Vite 开发服务器将所有 `/api` 请求代理到配置的 Open WebUI URL,并在服务端注入 Authorization 标头,因此 API key 不会暴露在浏览器的网络请求中。 设置会持久化存储在 `localStorage`(键:`aegis-ui-store`)中,并在页面重新加载后依然保留。 ### SSE 流协议 聊天 hook (`useStreamingChat`) 发送 `POST /api/chat/completions` 请求并带有 `"stream": true`。它将响应体作为 `ReadableStream` 读取,解析 `data:` 行,并在到达时将 delta token 追加到 Agent 消息状态中。收到 `data: [DONE]` 时,它会触发 `POST /api/chat/completed` 来持久化会话(即发即弃,带有一次静默重试)。在流错误或用户取消时,该消息会被标记为 `[stream interrupted]`,并跳过 completed 调用。 ## 键盘快捷键 | 快捷键 | 操作 | |----------|--------| | `R` | 刷新所有数据(使所有 TanStack Query 缓存失效) | | `C` | 切换聊天面板的打开/关闭状态 | | `Ctrl+Enter` | 发送聊天消息(当输入框获得焦点时) | | `Escape` | 关闭 Settings 面板 | 当焦点位于 `INPUT` 或 `TEXTAREA` 元素内时,快捷键 `R` 和 `C` 会被禁用。 ## 无障碍设计 仪表板致力于符合 WCAG 2.1 AA 标准。作为原型后 UX 审查 (2026-03-18) 的一部分,实现了以下功能: - **非颜色徽章编码**:所有四个徽章组件(`PriorityBadge`、`StatusBadge`、`ConfidenceBadge`、`StalenessBadge`)除了颜色外,还包含图标和形状的冗余。没有状态信号仅依赖于颜色。这确保了色盲分析师(例如,绿色弱视影响约 8% 的男性)能够正确读取 HIGH/MEDIUM/LOW、ACTIVE/SILENT/PREPOSITIONING 和 staleness 状态。 - **Settings 面板焦点陷阱**:Settings 面板 (`SettingsPanel`) 实现了完全的键盘焦点陷阱,符合 ARIA Modal Dialog 模式(WCAG 2.1 SC 2.1.2)。打开时,焦点移动到对话框内的第一个可聚焦元素;关闭时,焦点返回到 TopNav 中触发它的 Settings 按钮。 - **文本对比度 — `aegis-text-muted`**:弱化文本颜色从 `#4b5563`(对比度约 3.1:1)提高到了 `#6b7280`(与 `#0d1117` 的对比度约 4.6:1),满足 WCAG AA 普通文本 .5:1 的要求。该 token 贯穿应用于时间戳、元数据行、TTP 项目符号、会话标签和系统健康指标。 - **TopNav 警报徽章**:当轮询周期中出现新的 HIGH 优先级情报项时,TopNav 中的盾牌图标上会出现一个闪烁的红色徽章。徽章计数反映了自分析师上次访问 Intel Feed 面板以来未读的 HIGH 项目。通过 `uiStore` 的未读追踪实现。 - **聊天面板折叠状态**:修正了折叠状态下聊天面板箭头的方向(现在指向右侧,即展开方向)。增加了“ANALYST CHAT”垂直标签的字体大小以提高可读性。当前会话包含消息时会出现一个脉冲活动指示器圆点,这为分析师提供了一个无需事先了解其存在即可打开面板的理由。 - **System Health 工具提示 — 键盘访问**:`SystemHealthWidget` 中的 `Tooltip` 包装器现在可以通过 `tabIndex={0}` 获得 `onFocus`/`onBlur` 处理程序聚焦,镜像了现有的 `onMouseEnter`/`onMouseLeave` 行为。工具提示内容(上次检查时间戳、配额值、错误消息)可供仅使用键盘和屏幕阅读器的用户访问。 ## 弹性与边缘情况 - **面板级 Error boundaries**:每个面板将其内容包装在 `ErrorBoundary` 中。一个面板中的 Zod 解析失败或网络错误不会影响其他面板。 - **加载骨架**:在获取数据时显示结构性微光骨架(而不是加载转圈)。 - **离线横幅**:当 `navigator.onLine` 为 false 时,会在 TopNav 上方渲染一个 `OfflineBanner` 组件,并带有最后一次检测到连接的时间戳。 - **Staleness 徽章**:在渲染时使用 `Date.now()` 与每个 JSON 条目中的 `updatedAt` 字段进行对比计算 —— 不存储 staleness 状态。 - **减少动态效果**:所有动画均通过 Tailwind 的 `motion-safe:` 变体遵循 `prefers-reduced-motion` 设置。 ## 数据文件 Schema 参考 所有 TypeScript 类型均从 Zod schema 推断 —— 从不手动复制。这些 schema 位于 `src/schemas/` 中,是 JSON 文件必须包含什么内容的权威事实来源。 ``` IntelFeed = z.array(IntelFeedEntrySchema) ThreatGroups = z.array(ThreatGroupEntrySchema) Investigations = z.array(InvestigationEntrySchema) DailySummary = z.array(DailySummaryEntrySchema) SystemHealth = SystemHealthSchema (single object, not array) ``` 解析失败(无效的 JSON 或 schema 不匹配)会触发面板级 Error boundary,该边界会渲染一个内联错误状态,而不会导致仪表板的其余部分崩溃。 ## Phase 2 路线图 以下内容明确不在 Phase 1 的范围内,已规划在 Phase 2 实现: - Node.js/Express 后端代理(移除了对 Vite 开发代理的需求;在生产环境中保护 API key) - REST 推送 endpoint 以取代文件轮询 - WebSocket 实时更新 (Phase 3) - Docker Compose 部署配置 - 身份验证 / 登录界面 - Vitest 单元测试、React Testing Library 组件测试和 Playwright E2E 测试(从 Phase 1 推迟) ## 相关文档 | 文档 | 路径 | |----------|------| | 插件 / 安装指南 | `PLUGIN.md` | | 数据契约 (Zod schemas) | `src/schemas/` | | 配套角色包 | `mindstone/cti-analyst-lite` |
标签:PKINIT, React, SIEM/SOC, Syscalls, 仪表盘, 前端可视化, 威胁情报, 工控安全, 开发者工具, 自动化攻击