关于 Whiskers
Whiskers 是面向运维人员和 AI Agent 的可自托管基础设施控制平面,可管理 Docker 主机与 Kubernetes 工作负载。它通过细分权限、代码强制护栏、人类审批和操作审计来约束基础设施操作。
主要功能
- 01管理 Docker 与 Kubernetes 工作负载
- 02按 API 密钥和工具配置权限
- 03通过护栏允许、确认或阻止操作
- 04敏感操作支持人工审批
- 05记录 Agent 历史与审计日志
- 06查看日志、部署和 CVE 信息
适用场景
- 01限制 AI Agent 可执行的运维操作
- 02审批容器重启等敏感变更
- 03集中检查多主机的容器状态
- 04审计 Agent 的基础设施操作
MCP 相关
Whiskers 提供经身份验证的 MCP 服务,供外部 AI 客户端调用受权限和护栏约束的基础设施工具。MCP API 密钥可设为只读、写入、管理员或指定工具范围。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm ghcr.io/lupusmalusdeviant/whiskers:0.15.0本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/lupusmalusdeviant/whiskers:0.15.0Streamable HTTP工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍

Whiskers
为人类和 AI Agent 提供受控的基础设施运维。
Whiskers 是面向 Docker 主机和 Kubernetes 工作负载的可自托管控制平面。 它不会让运维人员或 AI Agent 获得不受限制的 SSH 访问权限,而是提供明确的工具, 并通过权限、代码强制的防护措施、审批和完整的操作历史记录进行管控。
只需引导主机一次,之后即可通过网状网络和 mTLS 进行运维,无需长期持有私有 SSH 密钥。
⚠️ Beta 版。 Whiskers 仍在积极开发中,API 尚未稳定。 请在可信网络中运行,查阅安全策略,并做好在
1.0之前遇到破坏性 变更的准备。
为什么选择 Whiskers
AI Agent 可以运维基础设施,但通常的授权方式是交出 SSH 密钥或 Shell,这会赋予其远超任何单项任务所需的权限。Whiskers 在中间加入了受管控的一层:
- 限制运维人员或 Agent 的操作范围。 API 密钥、角色和明确的工具访问权限共同定义可用能力范围,无任意 Shell 访问。
- 在产生影响前要求审批。 代码强制的防护措施可以允许、阻止敏感操作,或暂停操作以等待人工确认。
- 准确了解发生了什么。 Agent 历史记录和审计日志会记录执行者、决策、目标、参数(已隐藏机密)和结果。
同一个控制平面覆盖 Docker、Kubernetes、日志、部署、服务和 CVE 上下文,但这些覆盖范围只是能力证明,而非核心卖点。核心卖点是受管控、可追责的运维。完整的产品定位请参阅 docs/product/POSITIONING.md。
管控机制
flowchart LR
H[Human operator]
A[AI agent]
CP[Whiskers control plane]
AUTH[Authentication & permissions]
GR[Code-enforced guardrails]
AP[Human approval]
TOOLS[Explicit infrastructure tools]
INFRA[Docker / Kubernetes / hosts]
AUDIT[Agent history & audit log]
H --> CP
A --> CP
CP --> AUTH
AUTH --> GR
GR -->|allow| TOOLS
GR -->|confirm| AP
AP -->|approved| TOOLS
GR -->|block| AUDIT
TOOLS --> INFRA
TOOLS --> AUDIT
AP --> AUDIT
目录
快速开始
从 v0.12.0 起,预构建的多架构镜像(amd64 / arm64)会发布到
ghcr.io/lupusmalusdeviant/whiskers。在此版本发布之前,请使用下方的 从源代码开始 方式。
快速方式 — 一条命令
# Installer: pulls the image, writes a small compose file in ./whiskers/, waits until healthy, prints the URL.
curl -fsSL https://raw.githubusercontent.com/LupusMalusDeviant/Whiskers/main/deploy/install.sh | bash
# ...or a bare docker run:
docker run -d --name whiskers -p 127.0.0.1:5100:8080 \
-v whiskers-data:/app/data -v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/lupusmalusdeviant/whiskers:latest
打开 http://127.0.0.1:5100。安装程序接受 --port、--bind、--data、--yes(install.sh --help);重新运行会原地更新(pull + up)。
标准方式 — Docker Compose
从最新版本下载 docker-compose.yml(其中已固定镜像版本),然后运行 docker compose up -d。可选设置放在旁边的 .env 文件中——所有设置都是可选的,Whiskers 无需任何设置即可运行(参见 .env.example)。
应用默认监听 127.0.0.1:5100(HOST_BIND / HOST_PORT),除非更改绑定地址,否则绝不会公开绑定。
首次登录
首次启动时,浏览器中的引导式设置向导会创建管理员账号——无需 .env 或配置文件。由于完成向导的人将成为管理员,向导会先要求输入一次性设置令牌,只有能访问服务器的人才能读取该令牌:docker exec whiskers cat /app/data/setup-token.txt(安装程序会打印该令牌;使用 Helm 的用户可通过 kubectl exec 读取相同路径,或使用 WHISKERS_SETUP_TOKEN 预先设置)。之后,你可以使用该本地登录方式登录(电子邮箱 + 密码;输错密码 5 次后,账号会锁定 15 分钟;登录尝试次数也会按客户端限流)。其他方式:使用 WHISKERS_ADMIN_EMAIL + WHISKERS_ADMIN_PASSWORD_FILE 无人值守地创建管理员;使用 Google 或通用 OIDC(参见配置);或者,在可信网络中进行试用时使用 AUTH_DISABLED=true——此时每个请求都具有管理员权限,因此 Whiskers 只会响应来自专用网络的客户端,并要求主机名为 IP 或 localhost,且不带外部 Origin(参见配置)。
连接 MCP 客户端
Whiskers 是可自托管的:没有托管或云端端点。你的 MCP 客户端通过 /mcp(Streamable HTTP)连接到你自己的实例,并使用在 设置 → MCP 中创建的 API 密钥:
{
"mcpServers": {
"whiskers": {
"type": "http",
"url": "http://localhost:5100/mcp",
"headers": { "Authorization": "Bearer <WHISKERS_MCP_API_KEY>" }
}
}
}
详情、作用域和防护机制行为请参阅 MCP 服务。
更多安装选项
通过 Nginx 反向代理部署
location /whiskers/ {
proxy_pass http://127.0.0.1:5100/whiskers/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /whiskers;
proxy_read_timeout 300s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
}
在子路径下提供服务时,请在 .env 中设置 PATH_BASE=/whiskers。
部署配置(完整模式与加固模式)
- 完整模式(
docker-compose.yml,默认):启用特权模式和主机 PID 命名空间,以便 Whiskers 管理其自身主机(通过nsenter管理防火墙/Nginx/systemd/execute_command),并运行容器内 VPN。 - 加固模式(
docker-compose.hardened.yml):仅用于监控远程主机——以非 root 用户运行、不启用privileged、移除 capabilities、根文件系统设为只读,并通过限制动词的 socket-proxy 访问 Docker。此模式牺牲了本地主机 Shell 管理能力,换取大幅缩小的攻击面。
完整对照表和权衡说明请参阅 docs/container-hardening.md。
Kubernetes(Helm)
在集群中运行 Whiskers,作为远程 Docker 集群(以及 Kubernetes 集群)的控制平面——Pod 会与容器一起显示在仪表板上:
helm install whiskers oci://ghcr.io/lupusmalusdeviant/charts/whiskers \
--set vault.key="$(openssl rand -hex 32)"
kubectl port-forward svc/whiskers 8080:8080 # → http://localhost:8080 (setup wizard)
此部署方式按设计采用单副本(Blazor Server + 有状态循环),以非 root 用户运行,根文件系统设为只读,数据由 PVC 提供支持。所有配置项、Ingress/WebSocket 说明及 Postgres 变体请参阅: deploy/helm/whiskers/README.md。若要从 Whiskers 管理集群,请参阅 deploy/k8s/README.md。
从源码安装(开发)
git clone https://github.com/LupusMalusDeviant/Whiskers.git
cd Whiskers
docker compose up -d # builds the image locally
将 .env.example 复制为 .env,即可覆盖任意默认值。.env 已被 gitignore 忽略——密钥不会进入代码仓库。
核心工作流
定义产品的流程——观察 → 提议 → 检查策略 → 请求审批 → 执行 → 验证 → 审计:
- 某个容器 / 工作负载处于不健康状态。
- Agent 使用仅限 read 权限的密钥分析状态和日志——无需写入权限。
- Agent 提议重启。
- 当前生效的防护规则将重启工具评定为 Confirm,因此此时不会执行任何操作。
- Whiskers 发起审批请求:包含执行者、工具、目标服务、目标工作负载、已脱敏的参数、理由和过期时间。
- 人员批准该请求。
- Whiskers 仅执行已批准的操作,并使用已批准的参数。
- Whiskers 随后验证该工作负载。
- Agent History 和 Audit Log 会显示完整链路,界面还会在结果、审批和历史记录之间提供深层链接。
这是 AI 运维接入的标准工作流,也是治理验收测试。
功能
Docker、Kubernetes 等都是控制平面负责治理的目标——按功能分组如下:
治理
- 按密钥设置权限——MCP API 密钥可限定为 Read / Write / Admin 权限,或限定为明确的工具列表。
- 代码强制执行的防护规则——按工具设置 Allow / Confirm / Block,在工具边界(而非提示词中)进行评估,采用“限制最严格者优先”原则。
- 人工审批——
Confirm工具会暂停执行,直到授权用户批准确切的操作和参数。 - Agent History——记录每次 Agent 工具调用:执行者/密钥、已脱敏的参数、决策、结果、耗时和目标。
- Audit Log——记录每项用户操作,并提供可筛选的历史记录。
运维
- 容器 — 查看所有主机的实时仪表板(CPU / 内存 / 健康状况);启动 / 停止 / 重启 / 移除;日志、统计数据、健康报告;可按服务器、Compose 项目和自由格式的 标签 分组。
- Kubernetes — 通过 kubeconfig 添加 k3s/Kubernetes 集群(加密后存储在保管库中);Pod 与容器并列显示,支持按所属对象分组、查看日志,以及诚实可靠的扩缩容 / 发布操作。
- 主机管理 — 防火墙(ufw)、Nginx 站点、systemd 服务、SSL 证书和集成式 Web 终端(主机和容器)。
- 部署 — 部署表单、Compose 上传、精选应用模板、跨注册表搜索镜像,以及 Git 部署(将仓库克隆 / 构建 / 编排到目标主机;通过 HMAC 签名 Webhook 触发推送后重新部署)。
安全
- CVE 扫描 — 扫描操作系统和容器镜像(Trivy),提供去重后的发现项仪表板,并显示严重程度和发现时间。
- 机密保管库 — 存储的机密采用静态加密(AES-256-GCM);敏感值会在记录日志和持久化之前脱敏。
- 强制要求 HMAC Webhook 密钥(兼容
X-Hub-Signature-256)并采用 默认拒绝授权 — 除非端点明确选择退出,否则所有端点都需要身份验证。 - 每条 SSH 路径都进行 SSH 主机密钥验证(首次使用时信任)。
- 网状网络 + mTLS 稳定运行(参见架构与安全)。
弹性
- Whiskers 自身数据的 备份与恢复 — 可选择使用 VAULT_KEY 加密(AES-256-GCM)、支持定时执行,并通过崩溃安全的延迟交换方式恢复。
- 镜像更新回滚 — 每次更新前创建快照;可在仪表板上一键还原。
- 监控与告警 — 历史 CPU/RAM/磁盘指标、健康报告,以及针对容器不健康 / 停止 / OOM、重启循环、持续负载异常、新 CVE 和可用镜像更新的通知(Mattermost、Matrix、Telegram、ntfy、Discord、Slack、Email/SMTP、通用 Webhook),并提供持久化的应用内动态。
集成
- MCP 服务 — 面向外部 AI 客户端的身份验证接口(参见 MCP 服务)。
- 云控制(带外) — 通过服务商 API 提供与服务商无关的电源控制 / 快照 / 指标(Hetzner、Hostinger),即使 SSH/Docker 暂时无法访问也可使用。
- 注册表 — 私有注册表凭据存储在保管库中,并在通过身份验证拉取时自动使用。
- 数据库 — SQLite(零配置)或通过 Entity Framework Core 使用 PostgreSQL。
- 界面 — 浅色 / 深色 / 跟随系统主题,并提供完整本地化的 英语(默认)/ 德语 界面。
架构与安全
Whiskers 通过三个独立平面管理每台已接入的主机。在稳定运行状态下,这些平面都不使用 SSH,也都不需要存储 SSH 密钥:
| 平面 | 内容 | 传输方式 |
|---|---|---|
| 遥测 | 主机 CPU/RAM/磁盘、容器统计信息 | node_exporter → VictoriaMetrics(通过网状网络拉取) |
| Docker API | 列出/重启/部署/检查 | 通过 mTLS(客户端证书,固定 CN)传输 Docker Engine API,并使用按动词白名单过滤的套接字代理 |
| 主机控制 | execute_command、systemd、journald、编辑 | 一次性特权 nsenter 容器,通过同一 mTLS Docker 通道驱动 |
SSH 仅用于引导。 接入主机时会建立单个 SSH 连接——并验证主机密钥(首次使用时信任,之后固定该密钥)——以将主机加入私有 WireGuard 网状网络(Tailscale/NetBird)、部署 mTLS 证书和 Docker 代理,并安装遥测组件。随后会删除引导凭据(上传的密钥或仅保存在内存中的密码)。从此以后,主机通过这三个 mTLS/网状网络平面进行无密钥管理;Whiskers 不会为其保留长期有效的 SSH 密钥。(如果某台服务器是以普通 SSH 连接方式添加、且从未完成接入,则在迁移前会继续使用 SSH。)
实话实说,这些平面的作用是: Docker API 和主机控制平面在根权限等效的意义上可控制受管主机——创建容器或运行 nsenter 本质上就是以 root 权限操作。mTLS 和网状网络决定谁能够访问这些权限;作用域、护栏和审批则决定特定调用方可以用这些权限做什么。完整设计、PKI(step-ca)、接入流程和权衡取舍详见 docs/ARCHITECTURE.md;威胁模型详见 SECURITY.md。
安全概要
- 稳定运行状态下,受管主机没有长期有效的 SSH 密钥;管理端口仅绑定到网状网络,按设计不会将任何管理相关内容暴露到公共互联网。
- 通过确定性策略实施强制,而非依赖提示词指令。 每次 MCP 工具调用——无论来自已登录的 Web 用户、外部 MCP 客户端还是进程内 Agent——都会通过代码执行相同的作用域检查(Read/Write/Admin,或显式指定的逐密钥工具列表)。随后,每次调用还会通过相同的护栏引擎:操作分类(Allow/Confirm/Block、受保护资源、禁止的参数、只读紧急开关),以及针对
Confirm的人工审批。详见策略层的应用方式。 - MCP API 密钥在 Web UI 中创建时必须指定明确的作用域;ServerWatch 时代的无作用域密钥文件
api-keys.json已不复存在(见 MCP 服务部分)。 - 机密信息(
.env、加密保险库、数据库)存放在/app/data/.env下,这两者都已加入 Git 忽略列表,并通过卷挂载——绝不会打包进镜像或提交到仓库。 - 完整仓库安全审查与修复(见安全修复变更日志):所有严重和高危问题,以及大多数中低危问题,均已修复——每条路径(包括 Agent 和 MCP)都实施逐密钥 RBAC;保险库采用 AES-256-GCM + PBKDF2;通过 EF Core 迁移管理架构;信任关键镜像按摘要固定;限制转发头信任;
/metrics由抓取令牌保护。
供应链
从 v0.12.1 起,每个已发布的镜像都会:
- 在发布前进行扫描 — 发布流水线会构建镜像、运行 Trivy 扫描,并在发现任何 CRITICAL 漏洞时中止整个流程,确保存在漏洞的镜像绝不会被推送;
- 以多架构方式构建,并附带来源证明和 SBOM 证明(将 SLSA 来源证明和 SPDX SBOM 附加到镜像,并将独立 SBOM 作为发布资源提供);
- 使用 cosign 进行无密钥签名(Sigstore)— 签名与发布工作流的 GitHub OIDC 身份绑定,并记录在公开的 Rekor 透明日志中;任何人都不持有签名密钥。
运行前请验证签名:
cosign verify ghcr.io/lupusmalusdeviant/whiskers:0.15.0 \
--certificate-identity-regexp '^https://github.com/LupusMalusDeviant/Whiskers/.github/workflows/release.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
验证结果有效,表示该镜像由此代码库的发布工作流从某个标签构建而成,而非重新构建或遭到篡改。(v0.12.1 之前发布的镜像附带来源证明,但没有经过 cosign 签名。)
如果发现安全问题,请私下报告 — 请参阅 SECURITY.md。
MCP 服务
Whiskers 内置了 MCP 服务(Streamable HTTP,端点为 /mcp),AI Agent(例如 Claude Code)
可通过它操作你的基础设施。请将其添加到 MCP 客户端:
{
"mcpServers": {
"whiskers": {
"type": "http",
"url": "https://whiskers.example.com/mcp",
"headers": { "Authorization": "Bearer <WHISKERS_MCP_API_KEY>" }
}
}
}
在子路径上的反向代理后方运行时(PATH_BASE=/whiskers),URL 会变为
https://example.com/whiskers/mcp;在本地实例中,URL 为 http://localhost:5100/mcp。
API 密钥与权限范围
- 密钥由管理员在 Web UI 中的 Settings → MCP 下创建。 每个密钥恰好具有一个权限范围——Read、Write 或 Admin;也可以不设置权限范围,而是指定明确的允许使用的工具列表。 可以随时在此禁用或删除密钥;被禁用的密钥会在下一次请求时遭到拒绝。
- 每个工具都会在代码中声明其最低权限范围,且每次调用时都会进行检查。权限范围受限的密钥无法调用超出其权限范围的工具;未配置权限级别的工具会被拒绝访问(默认拒绝);管理员可以为所有密钥关闭单个工具。
- 密钥仅以哈希形式存储。 密钥由加密安全的随机数生成器生成,长度为 256 位;Whiskers 只会在创建后显示一次,并且仅持久化其 SHA-256 哈希值及最后四个字符,供识别之用。提交的密钥会经过哈希处理并以恒定时间进行比较。密钥本身或任何被拒绝令牌的部分内容都不会写入日志。读取数据目录或备份的人只能获取哈希值,无法用其进行身份验证。没有有效密钥的请求会在任何工具运行前被拒绝。
旧版索引条目的说明(例如,抓取了 ServerWatch 时代 README 的 MCP 目录): Whiskers 在 v0.12 重新命名前称为 ServerWatch。旧的、无权限范围的扁平密钥文件
/app/data/api-keys.json已彻底移除:最后一项兼容性回退机制已在 v0.15.0 中删除,没有任何代码路径会读取该文件,遗留副本也会在启动时删除。MCP 访问只能使用在 Web UI 中创建的有权限范围的密钥,且这些密钥以 SHA-256 哈希形式存储,绝不会以明文存储。
工具范围:
- 容器:列出/检查/查看日志/查看指标/查看环境变量,启动/停止/重启/更新
- 服务与主机:信息、日志、指标、健康状态摘要、
execute_command(Admin) - 部署:
deploy_app、deploy_compose - 基础设施:防火墙、Nginx、systemd、SSL
- 数据库:检测、列出、架构、查询、备份
- 网络:列出/创建/移除,连接/断开容器
- 日志与告警:搜索、列出/创建日志告警
- 计划任务:列出/创建/删除/运行计划任务
- CVE 与更新:服务/容器 CVE 摘要、更新状态
- 云(带外):Hetzner 与 Hostinger 的电源/快照/指标
- Agent:
instruct_agent(将自然语言任务委派给进程内 Agent)
包含权限级别的完整最新列表见 docs/mcp-tool-catalog.md 以及 Web UI 中的 Settings > MCP。
提示词(可由用户调用的工作流;仅返回说明,其引导的每次工具调用仍会经过权限范围和安全防护检查):
| 提示词 | 功能 |
|---|---|
triage_unhealthy_containers | 只读诊断不健康/已停止/正在重启的容器,并按优先级排列修复方案 |
security_review_server | 只读检查一台服务:CVE、防火墙、TLS 过期情况、意外运行的服务 |
plan_safe_update | 检查镜像更新的风险、影响范围和 CVE,并制定回滚计划——在进行任何更改前停止 |
investigate_host_load | 解释主机负载,包括无法归因于任何容器的负载 |
资源(仅包含 MCP 接口本身的只读上下文,不包含基础设施数据):
| URI | 内容 |
|---|---|
whiskers://tools/catalog | 所有已提供的工具、各自所需的权限级别及启用状态 |
whiskers://me/permissions | 调用方自身的权限范围及其可调用的工具 |
策略层如何生效
Whiskers 的 AI 防护措施是一个确定性的策略执行层(Read / Write / Admin 权限范围、 操作分类和人在环路中的审批),在工具边界处通过代码进行评估——绝不会放在提示词中,因此任何模型输出都无法绕过它。
| 调用方 | 权限范围检查(Read / Write / Admin、工具允许列表) | 防护引擎(Allow / Confirm / Block) | 记录于 |
|---|---|---|---|
| 外部 MCP 客户端,直接调用工具 | ✅ 通过 API key 检查 | ✅ 每次调用都会检查;Confirm 会发起审批,人工批准后,完全相同的调用会执行一次(先批准再重试,有效期为 10 min) | Agent History |
已登录的 Web 用户调用 /mcp | ✅ 按角色检查(Viewer → Read、Operator → Write、Admin → Admin) | ✅ 与上述相同 | Agent History |
进程内 Agent(由 UI 或通过 MCP instruct_agent 触发) | ✅ 权限范围受限于触发用户 / key 的权限范围 | ✅ 每次调用都会检查;Confirm 会暂停运行,直到人工批准确切的操作和参数 | Agent History |
审批在 Approvals 页面处理;批准者必须至少拥有该操作所需的权限级别。 防护引擎属于 Agent 模块(默认开启)。关闭该模块后,Approvals 页面也会一并消失,直接调用仅受其权限范围限制。
AI Agent(可选)
除了 MCP 服务(为外部 Agent 提供服务)外,Whiskers 还内置了一个执行型 Agent:你用自然语言描述一项运维任务,它会使用 Whiskers 自带的工具进行规划和执行。它支持多种 LLM 提供商(OpenAI、OpenRouter、Ollama、Gemini、Anthropic 和 Claude Code),可在 UI 中选择。还提供可选的只读顾问聊天——它会解释并提出建议,但不会执行任何操作。
其安全模型通过代码而非提示词来强制执行:
- 防护措施(单独的、仅限管理员访问的
guardrails.json)是一个确定性的策略执行层:在工具边界处评估 Allow/Confirm/Deny 规则,遵循“限制最严格者优先”原则,无论 Agent 是从 Web UI 启动还是通过 MCP 启动,规则都完全相同。 - Agent 继承触发者的权限(Web 用户或 MCP key),绝不会超出这些权限。
- 混合自主模式:读取操作会自主执行;写入 / 管理员操作需要确认。
请参阅 src/Whiskers/Services/Agent/ 了解实现细节。
配置
Whiskers 完全通过环境变量(.env)配置;所有配置均为可选项。最重要的几组配置:
| 分组 | 键 | 说明 |
|---|---|---|
| 身份验证 | GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET、GOOGLE_ADMIN_EMAIL、AUTH_DISABLED、WHISKERS_SETUP_TOKEN | 设置 AUTH_DISABLED=true 会将每个请求都视为 Admin;此选项用于仅在可信局域网内进行试用。此时仅处理来自环回地址/专用网络的请求(可通过 Auth__DisabledAllowedNetworks__0=… 缩小范围),主机名必须是 IP 或 localhost(可通过 Auth__DisabledAllowedHosts__0=whiskers.lan 添加主机名),且不能包含跨站点 Origin。WHISKERS_SETUP_TOKEN 用于预设首次运行时的设置令牌。 |
| Admin 初始化 | WHISKERS_ADMIN_EMAIL | 首次运行时将该邮箱预设为 Admin(与身份提供商无关;Google 用户可使用 GOOGLE_ADMIN_EMAIL 达到相同效果),确保全新实例始终至少有一个 Admin。一旦存在任何角色,此设置也会让邮箱白名单采用默认拒绝策略。不会影响已有安装(包含 roles.json 的安装)。 |
| 本地登录 | WHISKERS_ADMIN_PASSWORD_FILE、Auth__LocalLogin__Enabled | 无需 IdP 的用户名/密码登录(ASP.NET Identity,在同一数据库中使用独立的数据表)。默认启用;设置 Auth__LocalLogin__Enabled=false 可仅使用联合身份验证。密码策略:至少 12 个字符。 |
| 密钥库 | VAULT_KEY | 用于加密静态存储密钥的密码短语(AES-256-GCM)。留空 = 禁用密钥库。请保持密钥稳定;丢失后将无法解密已存储的密钥 |
| OIDC(可选) | OIDC_ENABLED、OIDC_AUTHORITY、OIDC_CLIENT_ID、OIDC_CLIENT_SECRET、... | 通用 OpenID Connect(Authentik、Keycloak、Authelia、Zitadel 等),可通过 IdP 实现真正的 2FA/通行密钥 |
| 通知 | MATTERMOST_WEBHOOK_URL、MATTERMOST_ENABLED | Matrix 在 UI 中配置 |
| 路由 | PATH_BASE | 通过反向代理部署在子路径下时使用的路径前缀 |
| AI 聊天 | AICHAT_ENABLED、AICHAT_API_KEY、AICHAT_API_URL、AICHAT_MODEL、AICHAT_PROVIDER | 只读顾问聊天 |
| Agent | AGENT_ENABLED、AGENT_PROVIDER、AGENT_MODEL、AGENT_API_KEY、... | 执行操作的 Agent(见上文) |
| Mesh VPN | VPN_PROVIDER、TAILSCALE_AUTHKEY、NETBIRD_SETUP_KEY、... | 可插拔的 VPN 配置(none/tailscale/netbird);留空 = 使用容器内的旧版 Tailscale |
| 镜像搜索 | HARBOR_URL、HARBOR_USERNAME、HARBOR_PASSWORD | 添加可自托管的 Harbor 市场(默认启用 Docker Hub + GHCR) |
| 主机绑定 | HOST_BIND、HOST_PORT | 容器始终在内部监听 8080 |
| 数据目录 | WHISKERS_DATA_DIR | SQLite、JSON 存储、密钥和证书的根目录(默认 /app/data);可指向任意卷/主机路径 |
| 数据库 | WHISKERS_DB_PROVIDER、WHISKERS_DB_CONNECTION、WHISKERS_DB_CONNECTION_FILE | sqlite(默认,无需配置)或 postgres。使用 Postgres 时,请设置连接字符串,或将其挂载为文件并将 _FILE 指向该文件。可直接运行的覆盖配置:deploy/docker-compose.postgres.yml。 |
完整的注释列表请参阅 .env.example。
值得注意的运行时细节
- 邮箱白名单:在 UI 的 Settings > Authentication 下管理;更改无需重启即可生效。
- MCP API 密钥:在 UI 的 Settings > MCP 下创建(每个密钥可设置 Read / Write / Admin 范围)。全新安装中没有密钥。密钥只会在创建时显示一次,且仅以 SHA-256 哈希形式存储 — 请在创建时复制。旧版本的密钥会在首次启动时转换为哈希,并继续有效。仅向确实需要的密钥授予 Write/Admin 权限。
- 数据持久化:指标数据库(默认使用 SQLite,也可使用 PostgreSQL)、JSON 存储和证书均保存在数据目录下(
WHISKERS_DATA_DIR,默认/app/data);不会保存在镜像中。 - 健康探测:提供匿名访问的
/healthz(存活状态)和/readyz(就绪状态)端点;镜像内置 DockerHEALTHCHECK,Kubernetes 也可将它们用作探针。(不带z的/health是应用内状态页面。)
技术栈
| 层级 | 技术 |
|---|---|
| 后端 | C# / .NET 10 / ASP.NET Core |
| 前端 | Blazor Server + MudBlazor |
| Docker API | Docker.DotNet |
| 数据库 | SQLite(默认无需配置)或 PostgreSQL(Entity Framework Core)+ JSON 文件存储 |
| 身份验证 | 本地账户(ASP.NET Identity)、Google OAuth 2.0 或通用 OIDC + 角色和电子邮件白名单 |
| 实时通信 | SignalR |
| MCP | ModelContextProtocol.AspNetCore |
| 指标 | VictoriaMetrics(兼容 Prometheus) |
截图
以下界面展示了完整的治理模型——受控访问、强制治理、完整问责。项目网站 whiskers.app.lupusmalus.dev 提供核心工作流的实时演示(工作负载异常 → Agent 分析 → 护栏决策 → 审批 → 执行 → 审计追踪),应用内手册(帮助)则包含每个区域的截图。
护栏——强制治理。 在代码中强制执行、不可绕过的策略,在工具边界进行检查(而非在提示词中):只读紧急停止开关、无需确认时允许的最高级别、受保护资源以及禁止的参数模式。

Agent 历史记录——受控访问。 每次 Agent/MCP 工具调用的记录,包含执行者、权限级别(读取 / 写入 / 管理)、护栏判定(允许 / 确认 / 拒绝)、耗时和结果。

审计日志——完整问责。 审批与执行追踪:谁批准了什么、护栏阻止了哪项操作,以及由此产生的变更。

安全 AI 运维——受治理的起点。 连接客户端、创建遵循最小权限原则的只读密钥,并启用入门护栏预设(仅观察 / 安全操作 / 需要审批)。

仪表板——管理范围。 实时查看 Docker 主机和 Kubernetes 工作负载的状态,以及主机实时指标——治理模型所覆盖的管理界面。

截图基于匿名化的演示数据集。有关脚本化演示流程,请参阅 docs/product/demo-script.md;有关如何重现各张图片,请参阅 docs/product/screenshots.md。
路线图与 Beta 版
Beta 版功能丰富,但尚未完成。计划中/尚未实现的功能:
账户与角色
- 为本地登录添加 2FA(TOTP)和通行密钥;细化每个服务的角色/团队权限。
监控与触发器
- 完善流量/异常检测,并添加专用的“极端流量”触发器(目前采用持续 CPU/RAM/磁盘阈值,以及简单的滚动 z 分数异常检测)。
集群与部署
- 实时接收 Docker 事件(而非轮询);支持直接编辑资源限制;提供更丰富的 Compose 模板。
- Kubernetes 路线 B.3:Pod exec 终端、Pod 的 MCP 工具、metrics-server 统计信息(管理 k3s 集群及通过 Helm 在 Kubernetes 上运行已于 0.12 版本发布)。
Agent 治理(基于已发布的 Agent-History、审批/人在回路机制和丰富的聊天小组件)
- 将审批范围扩展到 阻止外部/直接 MCP 调用——目前人在回路的关卡仅适用于进程内 Agent;直接的
tools/call请求会被记录,但不会暂停等待审批。 - 在审批卡片中显示真正的每工具 差异(准确展示写入操作会造成的更改)。
- 提供更全面的 富小组件/MCP-Apps 目录,不再局限于精选图表和状态卡片。
安全加固与弹性
- 紧急访问/灾难恢复:通过 step-ca 签发短期 SSH 证书,在常规控制平面不可用时作为可审计的紧急访问途径。
- 为加固配置提供 Distroless/chiseled“远程”镜像(受限容器配置以及可插拔的 Tailscale/NetBird VPN 已发布——请参阅 docs/container-hardening.md)。
有需求?欢迎提交 issue。
项目结构
每个源代码文件夹都有自己的 README.md,用于介绍其中的文件。整体概览:
Whiskers/
├── src/
│ ├── Whiskers/ # the application
│ │ ├── Components/ # Blazor UI (Pages, Layout, Shared)
│ │ ├── Configuration/ # strongly-typed settings classes
│ │ ├── Hubs/ # SignalR hubs (container + terminal streams)
│ │ ├── Mcp/ # MCP server tools + permission layer
│ │ ├── Models/ # data models (Agent, Cloud, Cve, Hetzner, Hostinger)
│ │ ├── Services/ # all business logic (see Services/README.md)
│ │ ├── Utils/ # small helpers (secret redaction, shell quoting)
│ │ ├── wwwroot/ # static assets
│ │ └── Program.cs # composition root (DI, middleware, MCP, auth)
│ └── Whiskers.Tests/ # xUnit test suite
├── deploy/telemetry/ # mesh/mTLS deploy templates (node_exporter, VictoriaMetrics, Tailscale ACL)
├── docs/ARCHITECTURE.md # architecture, security-critical areas & change control
├── docs/product/ # product positioning (see docs/product/POSITIONING.md)
├── Dockerfile
├── docker-compose.yml
└── README.md
Services/ 目录树是应用的核心——请参阅 src/Whiskers/Services/README.md 了解详细介绍。
代码规范
- 接口优先:服务通过
IFoo接口定义并注册到 DI 中;使用方依赖接口。 - 代码注释和 XML 文档始终使用英语;面向用户的 UI 已本地化(默认英语,另提供德语)。
开发
要求:.NET 10 SDK。
# build
dotnet build src/Whiskers/Whiskers.csproj
# run tests
dotnet test src/Whiskers.Tests/Whiskers.Tests.csproj
# run locally (listens on :8080)
dotnet run --project src/Whiskers/Whiskers.csproj
贡献
欢迎提交 issue 和 pull request。请:
- 遵循接口优先原则,并在
src/Whiskers.Tests/下添加/扩展测试; - 在提交 PR 前运行
dotnet build(0 条警告)和dotnet test; - 使用英语编写代码注释和文档。
许可证
Apache License 2.0,详见 LICENSE。
版权所有 © 2026 Whiskers Contributors
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。