@kenhkl/agent-moss 0.7.13 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/__init__.py +92 -0
- package/dist/agents/__pycache__/__init__.cpython-312.pyc +0 -0
- package/dist/agents/__pycache__/base.cpython-312.pyc +0 -0
- package/dist/agents/base.py +116 -0
- package/dist/agents/xiaoo/README.md +41 -0
- package/dist/agents/xiaoo/rules.json +47 -0
- package/dist/cli.js +2131 -251
- package/dist/cli.js.map +1 -1
- package/dist/data/agent_moss.service +16 -0
- package/dist/templates/security_judge_template.txt +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""三方 agent 定制化注册中心
|
|
2
|
+
|
|
3
|
+
按 `agent_id` 加载该 agent 的专属规则集(JSON 单一事实源)。
|
|
4
|
+
规则文件位置:`agent_moss/agents/<agent_id>/rules.json`
|
|
5
|
+
|
|
6
|
+
Python 与 TypeScript 两端共享同一份 rules.json:
|
|
7
|
+
- py: agent_moss/agents/__init__.py:get_agent_extensions
|
|
8
|
+
- ts: ts/src/agents/index.ts:getAgentExtensions
|
|
9
|
+
|
|
10
|
+
使用:
|
|
11
|
+
from agent_moss.agents import get_agent_extensions
|
|
12
|
+
ext = get_agent_extensions("xiaoo")
|
|
13
|
+
if ext:
|
|
14
|
+
# 把 ext.extra_command_patterns 追加到通用规则之后
|
|
15
|
+
...
|
|
16
|
+
|
|
17
|
+
无 agent_id 或 rules.json 不存在时返回 None(通用模式)。
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
import threading
|
|
22
|
+
import logging
|
|
23
|
+
|
|
24
|
+
from .base import AgentExtensions, InjectionKeyword, CommandPattern, SensitivePath
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
_AGENTS_DIR = Path(__file__).parent
|
|
29
|
+
_cache: dict[str, AgentExtensions | None] = {}
|
|
30
|
+
_lock = threading.Lock()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_agent_extensions(agent_id: str) -> AgentExtensions | None:
|
|
34
|
+
"""按 agent_id 加载该 agent 的专属规则集。
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
agent_id: 调用方 agent 标识,如 "xiaoo" / "opencode" / "opendesk"。
|
|
38
|
+
空字符串返回 None(通用模式)。
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
AgentExtensions 实例,或 None(无 agent 专属规则)。
|
|
42
|
+
"""
|
|
43
|
+
if not agent_id:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
# 双重检查锁定,避免并发重复 IO
|
|
47
|
+
if agent_id in _cache:
|
|
48
|
+
return _cache[agent_id]
|
|
49
|
+
|
|
50
|
+
with _lock:
|
|
51
|
+
if agent_id in _cache:
|
|
52
|
+
return _cache[agent_id]
|
|
53
|
+
|
|
54
|
+
rules_file = _AGENTS_DIR / agent_id / "rules.json"
|
|
55
|
+
if not rules_file.exists():
|
|
56
|
+
logger.debug("agent %s 无 rules.json,走通用模式", agent_id)
|
|
57
|
+
_cache[agent_id] = None
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
ext = AgentExtensions.from_json(rules_file)
|
|
62
|
+
_cache[agent_id] = ext
|
|
63
|
+
logger.info(
|
|
64
|
+
"加载 agent %s 定制规则: %d cmd patterns, %d injection keywords, "
|
|
65
|
+
"%d sensitive paths, %d builtin safe skills",
|
|
66
|
+
agent_id,
|
|
67
|
+
len(ext.extra_command_patterns),
|
|
68
|
+
len(ext.extra_injection_keywords),
|
|
69
|
+
len(ext.extra_sensitive_paths),
|
|
70
|
+
len(ext.builtin_safe_skills),
|
|
71
|
+
)
|
|
72
|
+
return ext
|
|
73
|
+
except Exception as e:
|
|
74
|
+
logger.error("加载 agent %s rules.json 失败: %s", agent_id, e)
|
|
75
|
+
_cache[agent_id] = None
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def clear_agent_extensions_cache() -> None:
|
|
80
|
+
"""清空 agent 扩展缓存(用于测试或 rules.json 热加载)"""
|
|
81
|
+
with _lock:
|
|
82
|
+
_cache.clear()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
__all__ = [
|
|
86
|
+
"AgentExtensions",
|
|
87
|
+
"InjectionKeyword",
|
|
88
|
+
"CommandPattern",
|
|
89
|
+
"SensitivePath",
|
|
90
|
+
"get_agent_extensions",
|
|
91
|
+
"clear_agent_extensions_cache",
|
|
92
|
+
]
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""三方 agent 定制化扩展 — 数据载体
|
|
2
|
+
|
|
3
|
+
`AgentExtensions` 描述某个宿主 agent(xiaoO / opencode / opendesk)在通用安全规则
|
|
4
|
+
之上需要追加的专属规则。规则以 JSON 单一事实源存储(agent_moss/agents/<id>/rules.json),
|
|
5
|
+
Python 与 TypeScript 两端共享同一份文件。
|
|
6
|
+
|
|
7
|
+
设计原则:
|
|
8
|
+
- 所有字段以 `extra_` 为前缀,表示"追加到通用规则之后",不覆盖通用规则。
|
|
9
|
+
- 通用规则先匹配;命中即短路,避免重复检测。
|
|
10
|
+
- agent 专属规则只做"通用规则没覆盖的宿主 agent 特有风险"。
|
|
11
|
+
|
|
12
|
+
JSON schema(agent_moss/agents/<id>/rules.json):
|
|
13
|
+
{
|
|
14
|
+
"agent_id": "xiaoo",
|
|
15
|
+
"description": "xiaoO 宿主 agent 专属安全规则",
|
|
16
|
+
"extra_command_patterns": [CommandPattern...],
|
|
17
|
+
"extra_injection_keywords": [InjectionKeyword...],
|
|
18
|
+
"extra_sensitive_paths": [SensitivePath...],
|
|
19
|
+
"builtin_safe_skills": ["xiaoo-guardian"],
|
|
20
|
+
"extra_skills": []
|
|
21
|
+
}
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from dataclasses import dataclass, field
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
import json
|
|
27
|
+
import logging
|
|
28
|
+
|
|
29
|
+
from agent_moss.profiles.base import CommandPattern, SensitivePath
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class InjectionKeyword:
|
|
36
|
+
"""Prompt 注入关键词条目"""
|
|
37
|
+
keyword: str
|
|
38
|
+
risk_level: str # low / medium / high / critical
|
|
39
|
+
lang: str # en / zh
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class AgentExtensions:
|
|
44
|
+
"""三方 agent 定制化扩展
|
|
45
|
+
|
|
46
|
+
由 `agent_moss.agents.get_agent_extensions(agent_id)` 按需加载。
|
|
47
|
+
缺失 rules.json 时返回 None(通用模式)。
|
|
48
|
+
"""
|
|
49
|
+
agent_id: str
|
|
50
|
+
description: str = ""
|
|
51
|
+
extra_command_patterns: list[CommandPattern] = field(default_factory=list)
|
|
52
|
+
extra_injection_keywords: list[InjectionKeyword] = field(default_factory=list)
|
|
53
|
+
extra_sensitive_paths: list[SensitivePath] = field(default_factory=list)
|
|
54
|
+
builtin_safe_skills: list[str] = field(default_factory=list)
|
|
55
|
+
extra_skills: list[dict] = field(default_factory=list)
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def from_json(cls, rules_file: Path) -> "AgentExtensions":
|
|
59
|
+
"""从 rules.json 加载 AgentExtensions。
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
rules_file: agent_moss/agents/<id>/rules.json 的绝对路径
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
AgentExtensions 实例
|
|
66
|
+
|
|
67
|
+
Raises:
|
|
68
|
+
ValueError: JSON 结构不合法
|
|
69
|
+
"""
|
|
70
|
+
with open(rules_file, "r", encoding="utf-8") as f:
|
|
71
|
+
data = json.load(f)
|
|
72
|
+
|
|
73
|
+
agent_id = data.get("agent_id", "")
|
|
74
|
+
if not agent_id:
|
|
75
|
+
raise ValueError(f"rules.json 缺少 agent_id 字段: {rules_file}")
|
|
76
|
+
|
|
77
|
+
# extra_command_patterns: dict → CommandPattern
|
|
78
|
+
extra_cmd_patterns: list[CommandPattern] = []
|
|
79
|
+
for p in data.get("extra_command_patterns", []):
|
|
80
|
+
extra_cmd_patterns.append(CommandPattern(
|
|
81
|
+
pattern=p["pattern"],
|
|
82
|
+
risk_level=p["risk_level"],
|
|
83
|
+
risk_type=p["risk_type"],
|
|
84
|
+
reason=p["reason"],
|
|
85
|
+
))
|
|
86
|
+
|
|
87
|
+
# extra_injection_keywords: dict → InjectionKeyword
|
|
88
|
+
extra_inj_keywords: list[InjectionKeyword] = []
|
|
89
|
+
for k in data.get("extra_injection_keywords", []):
|
|
90
|
+
extra_inj_keywords.append(InjectionKeyword(
|
|
91
|
+
keyword=k["keyword"],
|
|
92
|
+
risk_level=k["risk_level"],
|
|
93
|
+
lang=k.get("lang", "en"),
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
# extra_sensitive_paths: dict → SensitivePath
|
|
97
|
+
extra_sensitive_paths: list[SensitivePath] = []
|
|
98
|
+
for sp in data.get("extra_sensitive_paths", []):
|
|
99
|
+
extra_sensitive_paths.append(SensitivePath(
|
|
100
|
+
path=sp["path"],
|
|
101
|
+
risk_level=sp["risk_level"],
|
|
102
|
+
desc=sp["desc"],
|
|
103
|
+
credential=sp.get("credential", False),
|
|
104
|
+
read_only=sp.get("read_only", False),
|
|
105
|
+
deny_mode=sp.get("deny_mode", ""),
|
|
106
|
+
))
|
|
107
|
+
|
|
108
|
+
return cls(
|
|
109
|
+
agent_id=agent_id,
|
|
110
|
+
description=data.get("description", ""),
|
|
111
|
+
extra_command_patterns=extra_cmd_patterns,
|
|
112
|
+
extra_injection_keywords=extra_inj_keywords,
|
|
113
|
+
extra_sensitive_paths=extra_sensitive_paths,
|
|
114
|
+
builtin_safe_skills=data.get("builtin_safe_skills", []),
|
|
115
|
+
extra_skills=data.get("extra_skills", []),
|
|
116
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# xiaoO 宿主 agent 定制化规则
|
|
2
|
+
|
|
3
|
+
## 文件
|
|
4
|
+
|
|
5
|
+
- `rules.json` — xiaoO 专属规则的单一事实源,Python 与 TypeScript 两端共享
|
|
6
|
+
|
|
7
|
+
## 规则内容
|
|
8
|
+
|
|
9
|
+
### extra_command_patterns(5 条)
|
|
10
|
+
|
|
11
|
+
同步自 `xiaoO/plugins/hookers/audit_agent/audit_policy_checker/audit_policy_checker/security/heuristic_detector.py` 行 98–132:
|
|
12
|
+
|
|
13
|
+
1. `xiaoo\.env|xiaoo\.toml|llm_secrets\.json` — 访问 xiaoO 配置/密钥文件(high)
|
|
14
|
+
2. `/usr/lib/\.xiaoo/skills/xiaoo-guardian/.*<写命令>` — 系统级 xiaoO-guardian 目录写保护(critical)
|
|
15
|
+
3. `<写命令>.* /usr/lib/\.xiaoo/skills/xiaoo-guardian/` — 反序匹配(critical)
|
|
16
|
+
4. `\.xiaoo/skills/xiaoo-guardian/.*<写命令>` — 用户级 xiaoO-guardian 目录写保护(critical)
|
|
17
|
+
5. `<写命令>.*\.xiaoo/skills/xiaoo-guardian/` — 反序匹配(critical)
|
|
18
|
+
|
|
19
|
+
写命令集合:`rm|del|delete|remove|修改|删除|chmod|chown|write|save|保存|modify|更新|覆盖|replace|truncate|追加|append`
|
|
20
|
+
|
|
21
|
+
### extra_injection_keywords(6 条)
|
|
22
|
+
|
|
23
|
+
xiaoO 专属绕过词(同步自 audit_agent heuristic_detector.py 行 361–367):
|
|
24
|
+
|
|
25
|
+
- EN: `bypass audit` / `skip security check` / `disable guard`(全 critical)
|
|
26
|
+
- ZH: `绕过审计` / `禁用安全检查` / `关闭防护`(全 critical)
|
|
27
|
+
|
|
28
|
+
### builtin_safe_skills
|
|
29
|
+
|
|
30
|
+
`["xiaoo-guardian"]` — xiaoO 内置安全 Skill,coordinator 直接放行(不递归分析其内容)。
|
|
31
|
+
|
|
32
|
+
## 加载机制
|
|
33
|
+
|
|
34
|
+
- py: `agent_moss.agents.get_agent_extensions("xiaoo")` → `AgentExtensions`
|
|
35
|
+
- ts: `ts/src/agents/index.ts:getAgentExtensions("xiaoo")` → `AgentExtensions`
|
|
36
|
+
|
|
37
|
+
detection pipeline 把 `extra_*` 追加到通用规则之后;通用规则先匹配命中即短路。
|
|
38
|
+
|
|
39
|
+
## 调用方
|
|
40
|
+
|
|
41
|
+
`hooks/xiaoO/bridge.py` 在 POST `/api/v1/analyze` 时带 `agent_id: "xiaoo"`,AgentMoss 服务端据此加载本规则集。
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"agent_id": "xiaoo",
|
|
3
|
+
"description": "xiaoO 宿主 agent 专属安全规则。在通用 Linux profile 之上追加 xiaoO 配置/密钥/安全 Skill 目录的写保护,以及 xiaoO 专属绕过词。同步自 audit_agent heuristic_detector.py 行 98-132 + 行 361-367。",
|
|
4
|
+
"extra_command_patterns": [
|
|
5
|
+
{
|
|
6
|
+
"pattern": "xiaoo\\.env|xiaoo\\.toml|llm_secrets\\.json",
|
|
7
|
+
"risk_level": "high",
|
|
8
|
+
"risk_type": "config_tampering",
|
|
9
|
+
"reason": "检测到尝试访问或修改 xiaoO 配置文件"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"pattern": "/usr/lib/\\.xiaoo/skills/xiaoo-guardian/.*\\b(rm|del|delete|remove|修改|删除|chmod|chown|write|save|保存|modify|更新|覆盖|replace|truncate|追加|append)\\b",
|
|
13
|
+
"risk_level": "critical",
|
|
14
|
+
"risk_type": "config_tampering",
|
|
15
|
+
"reason": "检测到尝试修改或删除 xiaoO 系统级安全防护 Skill 目录"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pattern": "\\b(rm|del|delete|remove|修改|删除|chmod|chown|write|save|保存|modify|更新|覆盖|replace|truncate|追加|append)\\b.* /usr/lib/\\.xiaoo/skills/xiaoo-guardian/",
|
|
19
|
+
"risk_level": "critical",
|
|
20
|
+
"risk_type": "config_tampering",
|
|
21
|
+
"reason": "检测到尝试修改或删除 xiaoO 系统级安全防护 Skill 目录"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"pattern": "\\.xiaoo/skills/xiaoo-guardian/.*\\b(rm|del|delete|remove|修改|删除|chmod|chown|write|save|保存|modify|更新|覆盖|replace|truncate|追加|append)\\b",
|
|
25
|
+
"risk_level": "critical",
|
|
26
|
+
"risk_type": "config_tampering",
|
|
27
|
+
"reason": "检测到尝试修改或删除 xiaoO 用户级安全防护 Skill 目录"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"pattern": "\\b(rm|del|delete|remove|修改|删除|chmod|chown|write|save|保存|modify|更新|覆盖|replace|truncate|追加|append)\\b.*\\.xiaoo/skills/xiaoo-guardian/",
|
|
31
|
+
"risk_level": "critical",
|
|
32
|
+
"risk_type": "config_tampering",
|
|
33
|
+
"reason": "检测到尝试修改或删除 xiaoO 用户级安全防护 Skill 目录"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"extra_injection_keywords": [
|
|
37
|
+
{ "keyword": "bypass audit", "risk_level": "critical", "lang": "en" },
|
|
38
|
+
{ "keyword": "skip security check", "risk_level": "critical", "lang": "en" },
|
|
39
|
+
{ "keyword": "disable guard", "risk_level": "critical", "lang": "en" },
|
|
40
|
+
{ "keyword": "绕过审计", "risk_level": "critical", "lang": "zh" },
|
|
41
|
+
{ "keyword": "禁用安全检查", "risk_level": "critical", "lang": "zh" },
|
|
42
|
+
{ "keyword": "关闭防护", "risk_level": "critical", "lang": "zh" }
|
|
43
|
+
],
|
|
44
|
+
"extra_sensitive_paths": [],
|
|
45
|
+
"builtin_safe_skills": ["xiaoo-guardian"],
|
|
46
|
+
"extra_skills": []
|
|
47
|
+
}
|