Skip to main content

AgentMoss

AgentMoss 是一个可被任意 AI Agent 调用的独立通用安全分析服务。基于 OS Profile 机制,自动适配 Linux/Windows 的 syscall 检测模式,提供三层防御安全分析(特征匹配 → 逻辑规则 → LLM 语义分析)。

v2 更新:新增 OS Profile 系统(Linux/Windows 自适应)、两级快速放行白名单、rm 命令分级检测、脚本内容预扫描、LLM 结果缓存、Provider 自动识别与 Header 注入、fail-closed 安全原则。

v0.4.0 新增:非交互式密码修改检测(passwd/chpasswd/newusers/lnewusers 等)、密码修改授权检测(ask_user_question 前置检查)、内置安全 Skill 白名单(xiaoo-guardian 直接放行)、系统信息命令快速放行(whoami/id/hostname 等 12 个命令)、shell 重定向写入检测、AcTrail 执法事件上报。

v0.5.0 新增:L1/L2 规则收窄减少误杀(sudo 只拦截危险命令、rm -rf /tmp 不拦截、dd/mkfs/format 收窄、/etc/passwd 仅从 L1 移除、git push --force 降级为 medium)、nmap/masscan/zmap 网络扫描检测、lnewusers 批量用户添加检测、L2 通配符删除排除临时目录、用户/组删除授权检测、chgpasswd/lpasswd/gpasswd 检测。

目录

架构

┌─────────────────────────────────────────────────────────────┐
│          调用入口 (HTTP / Unix Socket / Hook)                 │
│  POST /api/v1/analyze                                        │
│  GET  /api/v1/health                                         │
├─────────────────────────────────────────────────────────────┤
│               ObservableAdapter                               │
│  AgentOS 可观测服务 syscall → 标准格式                       │
├─────────────────────────────────────────────────────────────┤
│                OS Profile 选择                                │
│     ┌──────────┐    ┌──────────┐                             │
│     │  Linux   │    │ Windows  │                             │
│     │ Profile  │    │ Profile  │                             │
│     └──────────┘    └──────────┘                             │
├─────────────────────────────────────────────────────────────┤
│          两级快速放行白名单                                    │
│  完全安全 (ls/pwd/echo/whoami/hostname...) → 跳过 L2+L3     │
│  只读敏感 (cat/grep/head...) → 跳过 L3,保留 L2              │
│  内置安全 Skill (xiaoo-guardian) → 跳过 L2+L3                │
│  ★ agent 定制白名单 (按 agent_id 加载,如 opendesk 的       │
│    memory-*/todomgr-* 纯数据操作) → 跳过 L2+L3               │
│  ★ 安全兜底: 完整命令管道尾部扫描,防止白名单绕过             │
├─────────────────────────────────────────────────────────────┤
│          安全分析引擎 (三层防御)                               │
│                                                              │
│  层1: 特征匹配静态检测 (<1ms)                                   │
│    ├── 用户自定义规则匹配                                     │
│    ├── 危险命令正则 (38+ 模式,rm 分级检测,sudo 只拦截危险命令) │
│    ├── 非交互式密码修改检测 (| passwd/chpasswd/newusers/lnewusers 等) │
│    ├── → high/critical → 直接 Deny                            │
│    ├── → 内联脚本 file_access 转层3                            │
│    │     (避免 'python -c "cat /etc/shadow"' 假阳性)         │
│    └── Prompt 注入检测 (62 个中英关键词,9 类)                 │
│                                                              │
│  层2: 逻辑规则检测 (<1ms)                                     │
│    ├── Rule 1: read-before-write 原则 (含 shell 重定向检测)    │
│    ├── Rule 2: 意图偏离检测                                   │
│    ├── Rule 3: 敏感路径访问 (含凭据 6 条目,                  │
│    │          \b 边界匹配避免部分匹配误报)                     │
│    ├── Rule 4: 危险操作模式 (通配符删除/重定向覆盖, 临时目录排除) │
│    ├── Rule 5: 密码修改授权检测 (非交互式需 ask_user_question) │
│    ├── Rule 6: 用户/组删除授权检测 (需 ask_user_question)     │
│    ├── Rule 7: 提权检测 (sudo+危险命令/su/chmod u+s)          │
│    └── Rule 8: 横向移动检测 (ssh/scp/rsync)                   │
│                                                              │
│  层3: LLM + Skill 深度分析 (2-5s)                            │
│    ├── 脚本内容预扫描 (18 个可疑模式,4 组合风险)              │
│    ├── Skill 规则匹配 (12 个 Skill,关键词加权评分)            │
│    ├── LLM 结果缓存 (200 条 FIFO)                            │
│    ├── Provider 自动识别 (15+ Provider)                       │
│    └── LLM 语义安全判断 (fail-closed)                         │
├─────────────────────────────────────────────────────────────┤
│          AcTrail 事件上报 (fire-and-forget)                    │
│  Allow/Deny 决策 → AcTrail SQLite Enforcement 事件            │
└─────────────────────────────────────────────────────────────┘

设计原则

  • 适配在 OS 层,不在 Agent 层 — 不同 Agent 最终都会调用操作系统的 syscall,这是确定性的
  • 标准化 I/O 契约 — 任何 Agent 遵循 API 格式即可接入,无需关心内部实现
  • fail-closed 安全原则 — LLM 调用失败时默认拒绝,不确定时拒绝
  • 两级快速放行 — 完全安全命令跳过 L2+L3,只读敏感命令跳过 L3,降低性能开销
  • 安全兜底 — 白名单放行前扫描完整命令管道尾部,防止 echo ... | passwd 等绕过
  • 内置 Skill 信任 — 系统安全 Skill(如 xiaoo-guardian)加载时直接放行,不走 LLM 审计
  • rm 命令分级检测 — 根据 flag 危险度 + 目标路径敏感度分级,/tmp 等临时目录不再拦截
  • sudo 收窄 — 不再一刀切拦截所有 sudo,只拦截 sudo 后跟的危险命令(rm/chmod/dd/mkfs 等)
  • 内联脚本假阳性防护python -c "x = 'cat /etc/shadow'; print(x)" 等字符串字面量中的敏感路径不立即拦截,转层3 LLM 语义判断
  • 目录遍历动态文件访问检测 — 检测 os.listdir() + open() 等通过目录遍历动态发现文件并读写的行为,防止绕过静态路径匹配
  • 敏感路径读写区分 — 凭据文件(credentials.yml、.env、SSH 密钥等)读写均拦截;系统配置文件(/etc/hosts、/boot/ 等)仅写拦截;特殊设备(/dev/random)仅读拦截
  • Shell 重定向智能识别 — 识别 2>/dev/null 等丢弃写法不计入写操作,lsblk/blockdev 等只读系统工具后的重定向也不判定为写入
  • 凭据文件边界匹配credentials.yml.env 等使用 \b 边界匹配避免非文件名拼接(如 something_credentials_yml)误报
  • 密码修改授权 — 非交互式密码修改(| passwdchpasswd 等)必须有 ask_user_question 用户授权
  • Shell 重定向写入检测echo data > file 等重定向操作识别为写入,纳入 read-before-write 规则

快速开始

安装

Python (PyPI)

pip install agent-moss

TypeScript (npm)

npm install @kenhkl/agent-moss

如需从源码安装:

git clone git@gitcode.com:kenhkl/AgentMoss.git
cd AgentMoss

# Python 版
pip install -e .

# TypeScript 版
cd ts && npm install && npm run build

CLI 使用

# 生成输入模板 (v2: 含 os_type 和 cwd 字段)
agent-moss init -o input.json

# 运行安全分析
agent-moss analyze input.json

# 安装 systemd service(有 sudo 时)
# 自动创建 /etc/systemd/system/agent_moss.service,--enable 开机自启
agent-moss install --enable

# 无 sudo 时跳过 systemd,提示手动启动:
#   agent-moss server --port 0
agent-moss install

# 查看服务状态(端口、版本、Console URL、三层开关)
agent-moss status

# 启动 HTTP 服务 (TCP)
# 端口被占时自动 findFreePort 往上找空闲端口(9090→9091→…,扫 100 个)
agent-moss server --port 0
# 消费方(xiaoO bridge.py)探测 9090-9095 的 /api/v1/health 自动连上实际端口。

# 启动 Unix Domain Socket 服务(同机部署推荐)
agent-moss server --mode socket --socket /var/run/agent_moss/agent_moss.sock

# 指定配置文件
agent-moss server --mode socket --config /etc/agent_moss/agent_moss.yaml

API 调用

HTTP TCP 方式:

curl -X POST http://127.0.0.1:9090/api/v1/analyze \
  -H 'Content-Type: application/json' \
  -d '{
    "session_id": "test-001",
    "prompt_session": "列出系统文件",
    "action_history": [],
    "a_next": {
      "action_type": "bash",
      "action_detail": "ls -la /tmp"
    },
    "reason": "查看临时目录",
    "os_type": "",
    "cwd": "/home/user"
  }'

Unix Domain Socket 方式(同机低延迟):

curl --unix-socket /var/run/agent_moss/agent_moss.sock \
  -X POST http://localhost/api/v1/analyze \
  -H 'Content-Type: application/json' \
  -d '{
    "session_id": "test-001",
    "a_next": {
      "action_type": "bash",
      "action_detail": "ls -la /tmp"
    }
  }'

响应示例 (Allow)

{
  "decision": "Allow",
  "risk_level": "low",
  "risk_type": "",
  "violated_layers": [],
  "confidence": 100,
  "analysis_duration_ms": 10.8
}

TypeScript / Node.js 调用

import { createApp } from '@kenhkl/agent-moss';

const app = createApp();
// 通过 Hono app.fetch 在 Node.js / Bun / Electron 中调用
// 或启动独立服务: npx agent-moss server --port 9090

也可以直接 HTTP 调用:

const resp = await fetch('http://127.0.0.1:9090/api/v1/analyze', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        session_id: 'sess-001',
        a_next: { action_type: 'bash', action_detail: 'ls -la' },
        os_type: 'linux',
        cwd: '/home/user',
    }),
});
const result = await resp.json();
// → { decision: 'Allow'|'Deny', risk_level: 'low'|'...', ... }

响应示例 (Deny)

{
  "decision": "Deny",
  "reason": "检测到递归强制删除关键路径 (rm -rf /...)",
  "risk_level": "critical",
  "risk_type": "script_execution",
  "violated_layers": ["1.1"],
  "confidence": 95,
  "analysis_duration_ms": 1.2
}

LLM 配置

AgentMoss 的三层防御中,层3(LLM 语义分析)是可选的。层1+层2 的静态规则可以独立运行。

L3 输入构成与 token 消耗(为什么不会上下文爆炸)

客户常有的顾虑:最坏情况下一个 session 里的每个 tool call 都会走到 L3 LLM 分析,会不会像 Agent 主循环那样把历史会话不断叠加导致上下文爆炸?不会。AgentMoss 的 L3 每次调用都是有界的独立请求,输入只包含当前这次判定的必要上下文,不随 session 长度无限累积。

每次 L3 调用的输入构成(固定模板 + 当前判定要素):

组成部分 内容 是否有界
固定 prompt 模板 安全审计员角色 + 判定维度 + JSON 输出格式 ✓ 固定
原始用户 prompt prompt_session(本次 session 的用户意图) 有界(用户单次输入)
待执行动作 action_type + action_detail(当前这一次 tool call) ✓ 单次动作
执行理由 reason ✓ 当前动作的理由
历史动作序列 action_history(本次 session 已执行的动作,每条仅 name + action_detail) 有界(本次 session 的有限动作)
安全检测规则 最多 3 个 Skill(按关键词相关度从全集选 top-3,每个 Skill 29-39 行) ✓ 最多 3 个
前置检测结果 L1/L2 的命中提示(仅命中时才有) ✓ 按需
脚本内容分析 内联脚本/管道的静态分析(仅脚本类动作才有) ✓ 按需

关键边界

  • Skill 最多 3 个:L3 从全部安全 Skill 中按关键词相关度评分取 top-3 注入 prompt(无匹配时兜底 general_tool_risk_guard 1 个),不会把全部 Skill 都塞进去。每个 Skill 文件 29-39 行。
  • 每次调用独立:L3 是"判定单个待执行动作 a_next"的独立请求,不是把 agent 的全部历史对话叠加进上下文。每次输入 = 固定模板 + 本次 a_next + 本次 session 的历史动作 + ≤3 个 Skill,彼此之间无累积。
  • 实测输入大小:典型 L3 调用 prompt 长度约 3500-3700 字符(~1k-1.5k token),多次调用稳定在该量级,不随 session 延长而膨胀。
  • 与 Agent 主循环的区别:Agent 主循环调 LLM 时通常把全部历史对话(user/assistant 往返)叠加进上下文,session 越长 token 越大;AgentMoss L3 每次只判一个动作,历史只传"已执行动作的摘要"(name + action_detail),且本次判定完即丢弃,不在 L3 侧累积。

最坏情况(session 内每个 tool call 都走 L3)下,单次 L3 的输入 token 仍有界(~1.5k token 量级),代价是调用次数 × 单次 token,而非单次 token 随历史爆炸。结果缓存(200 条 FIFO)会进一步消减重复调用的实际 LLM 消耗。

启用 LLM

方式 1:环境变量(推荐)

export AGENT_MOSS_LLM_API_KEY="sk-your-key"
# 可选:自定义模型和 API 端点
export AGENT_MOSS_LLM_MODEL="glm-5.0"
export AGENT_MOSS_LLM_BASE_URL="https://api.nextapi.store/v1"

方式 2:配置文件

首次运行 AgentMoss 时,会自动在 ~/.config/agentmoss/config.json 创建默认配置文件。编辑该文件:

{
  "llm": {
    "api_key": "sk-your-key",
    "model": "glm-5.0",
    "base_url": "https://api.nextapi.store/v1"
  }
}

配置文件优先级

  1. 环境变量(AGENT_MOSS_LLM_API_KEY 等)— 最高优先级
  2. AGENT_MOSS_CONFIG_PATH 环境变量指定的路径
  3. ~/.config/agentmoss/config.json — 首次运行自动创建
  4. 包内默认配置

方式 3:YAML 配置文件

通过 --configAGENT_MOSS_CONFIG_PATH 指定 YAML 文件:

agent-moss server --config /etc/agent_moss/agent_moss.yaml

编辑 config/agent_moss.yaml

llm:
  provider: "zhipu"
  model: "glm-5.0"
  base_url: "https://api.nextapi.store/v1"
  api_key_env: "AGENT_MOSS_LLM_API_KEY"
  temperature: 0.1
  max_tokens: 4096

security:
  llm_analysis:
    enabled: true

禁用 LLM(仅静态规则)

export AGENT_MOSS_DISABLE_LLM=1

支持的 LLM Provider

Provider URL 匹配 Provider Hint 说明
OpenAI api.openai.com openai 默认模型
Anthropic anthropic.com claude / anthropic Claude 系列
Google generativelanguage.googleapis.com google / gemini Gemini 系列
DeepSeek api.deepseek.com deepseek DeepSeek 系列
智谱 (GLM) open.bigmodel.cn zhipu / glm-cn / bigmodel GLM / CogView
智谱 Coding Plan api.z.ai zai-coding-plan 智谱编程套餐
OpenRouter openrouter.ai openrouter 多模型中转
Groq api.groq.com groq 高速推理
Mistral api.mistral.ai mistral Mistral 系列
Together api.together.xyz together 开源模型聚合
xAI api.x.ai xai / xai-grok Grok 系列
MiniMax api.minimaxi.com minimax MiniMax 系列
GitCode api-ai.gitcode.com gitcode GitCode AI
Ollama :11434 ollama 本地模型
任意兼容 other / custom / local 任何 OpenAI 兼容 API

自动识别 Provider 后,OpenRouter 和 xAI 会注入特定 HTTP Header(Referer、Title),确保平台正确计费。

AcTrail 集成

AgentMoss 可以将每次安全分析的 allow/deny 决策作为 Enforcement 事件写入 AcTrail 的存储,实现统一的 agent 行为审计。

启用

# 环境变量方式
export ACTRAIL_ENABLED=1
export ACTRAIL_STORAGE_PATH=/tmp/actrail.sqlite  # 默认路径

# 启动 AgentMoss
agent-moss server --port 9090

Policy Console(策略管控台)

AgentMoss 自带浏览器策略管控台,可视化调整三层开关、规则启停、deny_mode、skill 开关,查看 token 用量统计。Python 版和 TS 版功能对等(同一套前端 SPA,同一套 HTTP API 契约)。

访问:服务启动后,浏览器打开 http://127.0.0.1:9090/console(端口随服务实际监听端口)。

鉴权:默认本机(127.0.0.1)免鉴权,便于 iframe 嵌入;如需远程访问,设 AGENT_MOSS_CONSOLE_TOKEN 环境变量,请求带 Authorization: Bearer <token>

Console API(前端 SPA 调用,也可直接 curl):

方法 路径 说明
GET /console 返回 SPA index.html
GET / PUT /console/api/layers 查/改三层开关(L1/L2/L3 启停)
GET /console/api/rules 查全量规则(L1/L2,含 builtin + 自定义)
PUT /console/api/rules/enabled 翻转规则启停
PUT /console/api/rules/deny_mode 改 deny_mode(deny_write/deny_read/deny_both)
PUT /console/api/rules/skip_l3 改规则禁用时是否跳过 L3
PUT /console/api/categories/enabled 改分类开关
POST / DELETE /console/api/rules 增/删自定义规则(builtin 不可删)
GET /console/api/skills 查 L3 skill 全集
PUT /console/api/skills/enabled 翻转 skill 启停
PUT /console/api/skill-categories/enabled 改 skill 分类开关
POST / DELETE /console/api/skills 增/删自定义 skill(写 markdown 文件)
GET /console/api/skills/{id}/content 查 skill markdown 内容
GET /console/api/agents 查 agent 定制规则(按 agent_id 分区,含 enabled 状态)
PUT /console/api/agents/rules/enabled 翻转某 agent 某条规则启停
POST / DELETE /console/api/agents/rules 增/删 agent 定制规则条目
GET /console/api/config 查完整 runtime config + 路径
GET /console/api/env-overrides 查被环境变量接管的开关(灰色不可改)
POST /console/api/reset 重置为出厂默认
GET /console/api/token-stats token 用量统计
GET /console/api/token-stats/recent 最近 N 条调用记录
GET /console/api/token-stats/trend 趋势(日期×模型)
POST /console/api/token-stats/reset 清空统计

Console UI 采用 OpenDesk --ag- 设计 token + 暗色模式,为后续原生嵌入 OpenDesk 安全网关新页面预留视觉对齐。

runtime_config(运行时持久化配置)

runtime config 是 AgentMoss 的运行时策略持久化层,区别于启动时读的 YAML 配置:

  • 存储~/.config/agentmoss/agent_moss_runtime.jsonAGENT_MOSS_RUNTIME_CONFIG_PATH 覆盖)
  • 内容:三层开关、L1/L2 规则启停状态、deny_mode、skip_l3、L3 skill 开关
  • seed:首次加载时若文件不存在,自动从源码常量 seed 出厂默认(含全部 builtin 规则)并落盘
  • merge:每次加载时与源码默认 merge——保留用户开关,补入新 builtin,源码已删的 builtin 标记 source_removed+禁用(指纹去重,跨 id 变更识别同一规则)
  • 优先级AGENT_MOSS_DISABLE_* env > runtime JSON > agent_moss_settings.json > 默认。env 永远最高(Console 会展示被 env 接管的开关为灰色不可改)
  • 热生效is_layer_enabled 每次判定现读 runtime JSON,Console 改完立刻生效,无需重启服务
  • query 写操作:Python 和 TS 均实现全套(seed/merge/CRUD/update_*/_or_default 回退),双栈行为一致

Console UI 即是对 runtime config 的可视化操作层;直接编辑 JSON 或用 env 覆盖是另外两个入口,三者最终都落到同一份 runtime JSON。

配置

环境变量 说明 默认值
ACTRAIL_ENABLED 设为 1 启用上报 未设置(禁用)
ACTRAIL_STORAGE_PATH AcTrail SQLite 数据库路径 /tmp/actrail.sqlite
ACTRAIL_TIMEOUT_MS 写入超时(毫秒) 100

事件格式

AgentMoss 写入 AcTrail 的 events 表,payload 格式为 Enforcement 类型:

{
  "backend": "agent-moss",
  "operation": "tool_call",
  "decision": "allow|deny",
  "result": "allowed|denied",
  "tool.name": "bash",
  "tool.command": "cat /var/log/syslog",
  "agent.session_id": "session-001",
  "agent.prompt": "read log file",
  "risk.level": "low",
  "risk.type": "",
  "reason": "...",
  "violated_layers": "1,2",
  "confidence": "100",
  "duration_ms": "2.3"
}

架构

AgentMoss (Python HTTP)          AcTrail (eBPF daemon)
┌─────────────────┐             ┌─────────────────┐
│ POST /analyze   │             │                 │
│   ↓             │             │  SQLite 存储     │
│ 三层防御分析     │             │  (events 表)    │
│   ↓             │  fire-and-  │                 │
│ Allow/Deny      │──forget────▶│ Enforcement     │
│   ↓             │  写入 SQLite │ 事件落库        │
│ 返回给调用方     │             │                 │
└─────────────────┘             └─────────────────┘
                                        ↓
                               actrailviewer / actrailweb
                               统一查看 agent 行为审计

openEuler 部署

前提

  • openEuler 22.03 LTS+
  • Python 3.10+
  • root 权限

一键安装

sudo dnf install -y python3 python3-pip python3-devel
git clone <repo-url> agent_moss
cd agent_moss
sudo bash scripts/install.sh

配置 LLM(生产环境)

# 写入 API Key(文件权限 600)
echo "AGENT_MOSS_LLM_API_KEY=sk-your-key" | sudo tee /etc/agent_moss/agent_moss.env
sudo chmod 600 /etc/agent_moss/agent_moss.env

# 编辑 LLM model / base_url
sudo vim /etc/agent_moss/agent_moss.yaml

启动方式

# HTTP TCP 模式(默认,适合跨机/调试)
sudo systemctl enable --now agent_moss

# Unix Socket 模式(同机部署推荐,更低延迟)
# 编辑 /etc/agent_moss/agent_moss.yaml 中 server.mode: "socket"
# 或修改 /etc/systemd/system/agent_moss.service 中的 ExecStart

启动与验证

sudo systemctl enable --now agent_moss

# HTTP 模式验证
curl http://127.0.0.1:9090/api/v1/health
# {"status":"healthy","version":"<当前版本,见 pyproject.toml / ts/package.json>"}

# Socket 模式验证
curl --unix-socket /var/run/agent_moss/agent_moss.sock \
  http://localhost/api/v1/health

管理命令

命令 说明
systemctl start agent_moss 启动
systemctl stop agent_moss 停止
systemctl restart agent_moss 重启
systemctl status agent_moss 查看状态
journalctl -u agent_moss -f 查看日志
systemctl disable agent_moss 取消开机启动

多实例(instance 归属)

同机可并存多套 agentmoss(如 xiaoO 与 OpenDesk 各自起一个),通过 AGENT_MOSS_INSTANCE 环境变量区分归属。status 命令严格按此字段过滤,只认属于自己 instance 的服务:

# 不带 instance → 期望匹配空串。若 9091 上是 xiaoo 的实例,会报"未运行"并提示检测到其他实例
agent-moss status
# ❌ AgentMoss 服务未运行(instance=(空))
#    ⚠️ 检测到其他 agent 的 agentmoss 实例: 端口 9091 (instance=xiaoo)

# 带 instance → 精确匹配,正常显示运行中
AGENT_MOSS_INSTANCE=xiaoo agent-moss status
# ✅ AgentMoss 服务运行中
#    Instance: xiaoo
#    端口:     9091

instance 隔离「进程识别 + token 消耗」,不隔离规则配置。 同机所有实例共享同一份 ~/.config/agentmoss/agent_moss_runtime.json(除非显式设 AGENT_MOSS_RUNTIME_CONFIG_PATH 指向不同文件)。通用 L1/L2/L3 规则全局一致;不同 agent 的定制规则在文件内按 agent_rules.<agent_id> 分区天然隔离。任意 console 修改都写入共享文件,其他实例同步生效。

token 消耗按实例隔离:设了 AGENT_MOSS_INSTANCE=<name> 时,token 统计文件落在 <data_root>/<instance>/agent_moss_token_stats.json(如 opendesk~/.config/agentmoss/opendesk/...),各 agent 只读写自己实例的文件;未设则用默认 ~/.config/agentmoss/agent_moss_token_stats.json。「最近调用」(console token-stats/recent) 读同一文件,随之隔离。详见 docs/ENV_VARS.md

防火墙(HTTP 模式需要)

sudo firewall-cmd --add-port=9090/tcp --permanent
sudo firewall-cmd --reload

API 参考

方法 路径 说明
GET /api/v1/health 健康检查
POST /api/v1/analyze 安全分析

POST /api/v1/analyze

请求体 (v2)

{
  "session_id": "会话ID (必填)",
  "prompt_session": "原始任务描述 (可选,用于注入检测)",
  "action_history": [{"action_type": "...", "action_detail": "..."}],
  "a_next": {
    "action_type": "bash",
    "action_detail": "cat /etc/passwd"
  },
  "reason": "执行理由 (可选)",
  "os_type": "",
  "cwd": "/home/user/project",
  "metadata": {"agent_id": "...", "sandbox_id": "..."}
}
字段 类型 必填 说明
session_id string 会话唯一标识
prompt_session string 原始任务描述(层1 注入检测会扫描此字段)
action_history array 历史动作序列
a_next.action_type string 动作类型 (bash/file_read/file_write 等)
a_next.action_detail string 命令/动作详情
reason string 执行理由
os_type string "linux" / "windows",留空自动检测
cwd string 当前工作目录
agent_id string 调用方 agent 标识(如 xiaoo / opendesk)。留空走通用模式。详见 SECURITY_RULES.md「三方 agent 定制规则」
metadata object 扩展元数据(llm_config/llm_log_path per-request LLM 配置)

响应字段

字段 类型 说明
decision string Allow / Deny
reason string 决策原因
risk_level string low / medium / high / critical
risk_type string 风险类别 (file_access, script_execution, data_exfiltration, prompt_injection, privilege_escalation, lateral_movement, ...)
violated_layers array 触发的检测层,如 ["1", "2"]
violated_policy string 违反的具体条款 (Deny 时)
policy string Cerberus TOML 策略 (Allow 时)
confidence int 置信度 0-100
analysis_duration_ms float 分析耗时(毫秒)

配置

优先级:环境变量 > YAML 配置文件 > 内置默认值

环境变量

完整清单(含 audit_agent 迁移对照、bridge.py 端口变量、配置优先级)见 docs/ENV_VARS.md

变量 说明 默认值
AGENT_MOSS_LLM_API_KEY LLM API Key(兼容 fallback OPENROUTER_API_KEY / OPENAI_API_KEY 未设置
AGENT_MOSS_LLM_MODEL LLM 模型名称 gpt-4o (TS) / anthropic/claude-3.5-sonnet (Python)
AGENT_MOSS_LLM_BASE_URL LLM API 端点 https://api.openai.com/v1 (TS) / https://openrouter.ai/api/v1 (Python)
AGENT_MOSS_LLM_PROVIDER Provider 标识(决定注入 HTTP headers) 从 base_url 推断
AGENT_MOSS_LLM_TEMPERATURE LLM 采样温度 0.1
AGENT_MOSS_LLM_MAX_TOKENS LLM 最大输出 token 数 4096
AGENT_MOSS_LLM_TIMEOUT LLM 单次调用超时(秒) 300
AGENT_MOSS_LLM_RETRIES LLM 调用重试次数 2(共 3 次尝试)
AGENT_MOSS_LLM_FAIL_MODE LLM 失败策略:fail_open(默认 Allow+warn)/ fail_closed(Deny) fail_open
AGENT_MOSS_DISABLE_LLM 设为 1 禁用层3 LLM 未设置
AGENT_MOSS_DISABLE_HEURISTIC 设为 1 禁用层1 特征匹配 未设置
AGENT_MOSS_DISABLE_LOGIC_RULES 设为 1 禁用层2 逻辑规则 未设置
AGENT_MOSS_LOG_PATH 全量 hook 日志 + LLM prompt 日志(bridge 记 HOOK_INPUT/OUTPUT,L3 记 prompt,写同文件;对应 audit_agent AUDIT_LOG_PATH 未设置(不记录)
AGENT_MOSS_CUSTOM_RULES 自定义规则 JSON 数组 []
AGENT_MOSS_ENABLE_POLICY_GEN 设为 1 启用 Policy 生成 未设置
AGENT_MOSS_CONFIG_PATH 主配置 YAML 路径 ~/.config/agentmoss/agent_moss.yaml
AGENT_MOSS_DATA_DIR 数据根目录(所有 ~/.config/agentmoss 文件落盘位置)。systemd 下即使 root 启动也按安装用户落盘 ~/.config/agentmoss
AGENT_MOSS_RUNTIME_CONFIG_PATH runtime JSON(层级开关+规则启停持久化) ~/.config/agentmoss/agent_moss_runtime.json
AGENT_MOSS_TOKEN_STATS_PATH token 用量统计 JSON(显式优先于 instance 派生路径) 见「token 消耗按实例隔离」
AGENT_MOSS_SETTINGS_PATH agent_moss_settings.json 路径 包内默认
AGENT_MOSS_CONSOLE_TOKEN Console Bearer 鉴权 token 未设(本机免鉴权)
AGENT_MOSS_URL / HOST / PORT bridge.py 连服务用(端口被占自动 findFreePort) 127.0.0.1:9090
ACTRAIL_ENABLED 设为 1 启用 AcTrail 事件上报 未设置(禁用)
ACTRAIL_STORAGE_PATH AcTrail SQLite 数据库路径 /tmp/actrail.sqlite
ACTRAIL_TIMEOUT_MS AcTrail 写入超时(毫秒) 100

配置文件

参考 config/agent_moss.yaml

自定义规则

通过 AGENT_MOSS_CUSTOM_RULES 环境变量注入自定义正则规则:

export AGENT_MOSS_CUSTOM_RULES='[
  {"pattern": "kubectl delete namespace", "action": "Deny", "severity": "critical"},
  {"pattern": "docker rm -f", "action": "Deny", "severity": "high"}
]'

配置模板

# OS Profile 自动选择
os_profile:
  type: ""         # 留空自动检测,可手动指定 linux / windows

# 服务调用模式
server:
  mode: "http"     # "http" (TCP) 或 "socket" (Unix Domain Socket)
  socket_path: "/var/run/agent_moss/agent_moss.sock"

项目结构

AgentMoss/
├── agent_moss/               # Python 实现 (PyPI: agent-moss)
│   ├── __init__.py
│   ├── cli.py                # 命令行工具 (init/analyze/server)
│   ├── __version__.py
│   ├── profiles/             # OS Profile 系统
│   │   ├── base.py           # OSProfile 抽象基类
│   │   ├── linux.py          # LinuxProfile
│   │   └── windows.py        # WindowsProfile
│   ├── engine/               # 安全分析引擎
│   │   ├── analyzer.py       # 分析入口
│   │   ├── coordinator.py    # 三层协调器 + L1.5/L2.5 递归脚本链 + fail-open
│   │   ├── heuristic.py      # 层1: 特征匹配检测 (危险命令 + 注入关键词,热重载 runtime_config)
│   │   ├── logic_rules.py    # 层2: 逻辑规则 (敏感路径/意图/密码/用户删除,credential 区分)
│   │   ├── llm_analyzer.py   # 层3: LLM + Skill 深度分析 (skip_l3_hints + token 记录)
│   │   ├── script_analyzer.py        # 脚本预扫描
│   │   ├── script_content_analyzer.py # L1.5/L2.5 递归脚本链内容分析 (移植自 audit_agent)
│   │   ├── inline_analyzer.py        # 内联脚本/文本区分
│   │   ├── skill_engine.py   # Skill 匹配引擎 (热重载 runtime_config 禁用 skill)
│   │   └── types.py
│   ├── infra/                # 基础设施
│   │   ├── config.py         # 配置管理 (YAML + 环境变量 + 继承 xiaoo config.toml)
│   │   ├── runtime_config.py # runtime JSON:seed/merge/CRUD/层级开关持久化 (51 函数)
│   │   ├── token_stats.py   # token 用量统计 (JSON 持久化)
│   │   ├── llm_client.py     # LLM 客户端 (流式回退 + Provider header 适配)
│   │   ├── actrail.py        # AcTrail 事件上报
│   │   ├── logging.py / parsers.py / policy_cache.py / prompt_templates.py
│   ├── server/               # HTTP API 服务层 (FastAPI)
│   │   ├── app.py            # 应用 + run_server + _find_free_port (端口动态分配)
│   │   ├── routes.py         # /api/v1/* 路由 (health/analyze/brain)
│   │   ├── models.py / middleware.py / socket_server.py
│   ├── console/              # Policy Console (FastAPI sub-router, 23 路由)
│   │   ├── router.py         # /console/api/* (layers/rules/skills/config/env/reset/token-stats)
│   │   └── static/index.html # 自包含 SPA (--ag- 风格 + 暗色模式)
│   ├── adapters/  # 适配器层 (observable)
│   ├── skills/    # 安全 Skill 规则 (Markdown)
│   ├── templates/ # Prompt 模板 + policy_mapping
│   ├── agents/    # 三方 agent 定制化扩展 (xiaoO / opendesk) — rules.json 单一事实源,py+ts 共享
│   └── brain/     # 规则自学习/存储
│
├── ts/                       # TypeScript 实现 (npm: @kenhkl/agent-moss) — 功能与 Python 对等
│   ├── src/
│   │   ├── cli.ts            # CLI 入口 (init/analyze/server)
│   │   ├── config.ts         # 配置 (环境变量 + fail-open)
│   │   ├── models.ts         # Zod 数据模型
│   │   ├── routes.ts         # Hono API 路由 (health/analyze)
│   │   ├── server.ts         # Hono HTTP + findFreePort + 挂载 Console
│   │   ├── actrail.ts / package-json.ts
│   │   ├── engine/           # 三层防御引擎 (与 py 对等)
│   │   │   ├── coordinator.ts / heuristic.ts / logic-rules.ts
│   │   │   ├── llm-analyzer.ts / script-analyzer.ts / script-content-analyzer.ts
│   │   │   ├── inline-analyzer.ts / skill-loader.ts / template-loader.ts
│   │   │   ├── token-stats.ts / types.ts
│   │   ├── infra/runtime-config.ts  # runtime JSON 全功能 (seed/merge/CRUD/query,对齐 py)
│   │   └── console/          # Policy Console (Hono sub-app, 23 路由 1:1 对齐 py)
│   │       ├── router.ts / index.ts
│   │       └── static/index.html  # 复用 py 的同一份 SPA
│   └── package.json
│
├── hooks/xiaoO/             # xiaoO hook 桥接 (bridge.py + plugin.json)
│   └── bridge.py             # stdin JSON → POST /api/v1/analyze → stdout {result,reason};探测兜底
├── config/agent_moss.yaml   # YAML 配置模板
├── docs/
│   ├── design.md             # 架构需求设计
│   ├── ENV_VARS.md           # 环境变量参考 + audit_agent 迁移对照
│   └── ...
└── tests/
    ├── conftest.py / test_all_cases.py / test_agents_xiaoo.py / test_brain.py
    ├── test_find_free_port.py  # 端口动态分配单测
    └── cases/                  # 测试用例 JSON

测试

用例归一:单一事实源

所有安全分析测试用例集中在 tests/cases/{l1,l2,l3}/*.json226 个,按 L1/L2/L3 分子目录),Python 与 TypeScript 双端共用同一批 case(双端各自另有语言特有的手写单测,故 pytest/vitest 报告 passed 总数 > JSON 数且两数不同,详见 tests/cases/README.md)。每个 JSON 含:

字段 说明
expected_decision 期望决策(Deny/Allow),双端都断言
expected_risk_level 期望风险等级(critical/high/medium/low),双端都断言
expected_risk_type 期望风险类型(文档用,不断言)
expected_layers 期望命中层(文档用,不断言)
llm_required L3 case 标 true:禁 LLM 时 skip,需有效 LLM key 真跑
input {session_id, action_history, a_next, reason, os_type, cwd}

按子目录分层:l1/ 164 个(特征匹配命中+放行)、l2/ 25 个(逻辑规则命中+放行)、l3/ 28 个(13 个 security skill 命中+放行,llm_required:true)。

新增 case 只改一个 JSON,双端自动跑:

# 新增 case:复制一个现有 JSON 改内容即可(按层放对应子目录)
cp tests/cases/l1/deny-01-chmod-777.json tests/cases/l1/deny-99-mine.json
# 编辑 deny-99-mine.json 的 desc / expected_* / input

Python 端

# 前两层静态规则(禁用 LLM,CI 默认跑法,189 个 L1+L2 case 全绿)
python3 -m pytest tests/test_all_cases.py::TestLayer1And2 -v

# 仅跑 JSON case 加载器(L1+L2,禁 LLM)
AGENT_MOSS_DISABLE_LLM=1 python3 -m pytest tests/test_all_cases.py::TestLayer1And2 -v

# 包含 L3 LLM 层(需有效 LLM key,28 个 L3 case 真调 LLM,串行跑约 2~4 分钟)
# key/地址/model 从 env 或 ~/.config/agentmoss/config.json 统一判定 + 连通性探测,
# 判定通过才真跑;缺 key 或 key 不通则 skip(见下「L3 判定策略」)
python3 -m pytest tests/test_all_cases.py::TestLayer3 -v
# 若需显式覆盖 config.json,仍可传环境变量:
#   AGENT_MOSS_LLM_API_KEY="sk-xxx" AGENT_MOSS_LLM_BASE_URL="https://api.deepseek.com/v1" AGENT_MOSS_LLM_MODEL="deepseek-v4-flash"

入口:tests/test_all_cases.py

  • TestLayer1And2 参数化读 tests/cases/{l1,l2}/*.json,断言 expected_decision / expected_risk_level
  • TestLayer3 参数化读 tests/cases/l3/*.json,跑不跑由 llm_probe_available fixture 决定(判定源 env+config.json 有 key 且连通性探测通过才真调 LLM,否则 pytest.skip
  • TestHeuristicDetector / TestLogicRules / TestOSProfile / TestCoordinator 跑各子模块单测

L3 判定策略(双端统一)

L3 是否真跑由统一判定源 + 连通性探测决定,Python 与 TS 对称(避免两端判定不一致 + 坏 key fail-open 假通过):

  1. 判定源AGENT_MOSS_LLM_API_KEY env → 否则 ~/.config/agentmoss/config.jsonllm.api_key(Python 走 get_default_config().llm.api_key,TS 走 isLLMAvailable())。
  2. 连通性探测:有 key 再发一次 max_tokens=1 ping(Python _probe_llm / TS probeLLMConnection)。连通才真跑;key 无效/网络不通 → 明确提示 + skip,不假通过。
  3. 同源:probe 的 base_url/model/api_key 与 L3 实际调用一致,probe 通过即真跑可信。

TypeScript 端

cd ts

# JSON case 加载器(L1+L2,禁用 LLM,189 个 L1+L2 case 全绿)
npx vitest run src/__tests__/json-cases.test.ts

# 全量(含 heuristic / logic-rules / coordinator / agents 等)
npx vitest run

# 类型检查
npx tsc --noEmit

# 包含 L3 LLM 层(需有效 LLM key,28 个 L3 case 真调 LLM)
# 注意 TS 端与 Python 端有两个差异:
#   1) vitest 默认每 test 5s 超时,L3 跑 LLM 慢需加 --test-timeout=120000
#   2) 加载器并行跑 28 个 L3 case 会撞 LLM rate limit 走 fallback 假命中,
#      已加串行 gate + --no-file-parallelism 避免
# key/地址/model 从 env 或 config.json 统一判定 + 连通性探测,判定通过才真跑
npx vitest run src/__tests__/json-cases.test.ts --no-file-parallelism --test-timeout=120000
# 若需显式覆盖:
#   AGENT_MOSS_LLM_API_KEY="sk-xxx" AGENT_MOSS_LLM_BASE_URL="https://api.deepseek.com/v1" AGENT_MOSS_LLM_MODEL="deepseek-v4-flash"

入口:ts/src/__tests__/json-cases.test.ts

  • beforeAll:判定源(isLLMAvailable,env + config.json)无 key → 设 AGENT_MOSS_DISABLE_LLM=1(仅跑 L1+L2,对齐 Python);有 key → probeLLMConnection() 发一次 ping,连通才保留 LLM;key 无效/网络不通 → 禁 LLM + 明确提示,避免坏 key fail-open 假通过
  • tests/cases/{l1,l2,l3}/*.json,转 snake_case → camelCase,调 runAnalysis,断言 expected_decision / expected_risk_level
  • L1/L2 用例(非 llm_required)强制禁 LLM(对齐 Python default_config):只测 L1+L2 静态结果,避免 LLM 二次判定翻盘(Allow 变 Deny)导致波动。仅 llm_required 的 L3 case 在 LLM 可用时真跑
  • risk_level 断言:仅对 L1/L2 case 断言;L3 case 只断言 expected_decision(LLM 层 risk_level 有非确定性波动,对齐 Python TestLayer3
  • llm_required:true 的 L3 case:禁 LLM 时 it.skip;有 key + 探测通过时串行 gate(promise 链)一次只跑一个,避免并行撞 LLM rate limit 走 fail-open fallback 假命中
  • 与 Python TestLayer1And2 / TestLayer3 共用同一批 case,双端行为不一致会立刻暴露

双端跑 L3 差异说明

差异点 Python TypeScript
L3 跑法 TestLayer3 参数化串行跑,pytest 自带 test 超时足够 加载器需 --test-timeout=120000(vitest 默认 5s 不够)+ --no-file-parallelism(串行 gate 避免撞 rate limit)
LLM 字段名 Python 解析兼容 risk_level/riskLevel 两种 TS 已修 runLLMAnalysis 兼容两种(之前只取 riskLevel 拿不到走兜底 'low'
禁 LLM 跑 L3 TestLayer3 全 skip 加载器 llm_required:true case 单个 skip
L3 判定源 get_default_config().llm.api_key(env + config.json) isLLMAvailable()(env + config.json)
连通性探测 conftest.py _probe_llm(session 缓存,只 ping 一次) config.ts probeLLMConnection()(beforeAll 探测一次)

LLM 测试与 API Key

  • L3 是否真跑由统一判定源 + 连通性探测决定,Python 与 TS 对称(见上文「L3 判定策略」):
    • 判定源:AGENT_MOSS_LLM_API_KEY env → 否则 ~/.config/agentmoss/config.jsonllm.api_key
    • 连通性探测:有 key 再发 max_tokens=1 ping,连通才真跑;key 无效/网络不通 → 明确提示 + skip(不假通过
  • 无 Key 时:Python TestLayer3 skip;TS 加载器设 AGENT_MOSS_DISABLE_LLM=1,L3 case it.skip
  • 禁用 LLM 跑纯静态测试:TS 加载器内部已设 AGENT_MOSS_DISABLE_LLM=1;Python 默认就是不调 LLM

双端一致性核对

除 JSON case 加载器外,还有专项一致性测试:

测试 核对内容
ts/src/__tests__/dual-parity.test.ts isWriteOperation 双端对同一批 case 返回一致
ts/src/__tests__/json-cases.test.ts 226 个 JSON case 双端 decision + risk_level 一致

归一前:Python 跑 Python 的 test_all_cases.py,TS 跑 TS 的 *.test.ts,期望值各写各的,双端不一致发现不了。归一后:期望值写在 JSON 里,双端共用,改一处 JSON 双端同步——ts/src/__tests__/json-cases.test.ts 加载器一上线就暴露了 2 处真实代码差异 + 3 处 JSON 期望值错误。

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_moss-0.12.9.tar.gz (369.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_moss-0.12.9-py3-none-any.whl (344.1 kB view details)

Uploaded Python 3

File details

Details for the file agent_moss-0.12.9.tar.gz.

File metadata

  • Download URL: agent_moss-0.12.9.tar.gz
  • Upload date:
  • Size: 369.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agent_moss-0.12.9.tar.gz
Algorithm Hash digest
SHA256 abaa4be89310e61bd5c0f121381fff0d6ff61b36be51aa1c3d153fbef424f4a1
MD5 b9d562146ab8bd9c866ec4c28f66f371
BLAKE2b-256 8ef88f32093bae6db604e97f51cbac51e331bce5f99643d1d83440cd87d14a3f

See more details on using hashes here.

File details

Details for the file agent_moss-0.12.9-py3-none-any.whl.

File metadata

  • Download URL: agent_moss-0.12.9-py3-none-any.whl
  • Upload date:
  • Size: 344.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for agent_moss-0.12.9-py3-none-any.whl
Algorithm Hash digest
SHA256 e3d1b19b9b0f16fc0f77eefd15305a8cdff9c0fb0caa0f2709c2ac97f5d6adf7
MD5 cb95367d6edbe7c2167d52a7becde1e3
BLAKE2b-256 d3e62fe0d2bcae619002d678522dc8541bc91cac34db178a5f39645b1130c2e6

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.12.9 This release

2 files

0.12.8

2 files

0.12.7

2 files

0.12.6

2 files

0.12.5

2 files

0.12.4

2 files

0.12.3

2 files

0.12.2

2 files

0.12.1

2 files

0.12.0

2 files

0.11.5

2 files

0.11.4

2 files

0.11.3

2 files

0.11.2

2 files

0.11.1

2 files

0.11.0

2 files

0.10.5

2 files

0.10.4

2 files

0.10.3

2 files

0.10.2

2 files

0.10.1

2 files

0.10.0

2 files

0.9.1

2 files

0.9.0

2 files

0.8.5

2 files

0.8.4

2 files

0.8.3

2 files

0.8.2

2 files

0.8.1

2 files

0.8.0

2 files

0.7.13

2 files

0.7.12

2 files

0.7.11

2 files

0.7.10

2 files

0.7.9

2 files

0.7.8

2 files

0.7.6

2 files

0.7.5

2 files

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page