Files
zclaw_openfang/crates/zclaw-kernel/src/capabilities.rs
iven eed347e1a6
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
feat: 实现循环防护和安全验证功能
refactor(loop_guard): 为LoopGuard添加Clone派生
feat(capabilities): 实现CapabilityManager.validate()安全验证
fix(agentStore): 添加token用量追踪
chore: 删除未实现的Predictor/Lead HAND.toml文件
style(Credits): 移除假数据并标注开发中状态
refactor(Skills): 动态加载技能卡片
perf(configStore): 为定时任务添加localStorage降级
docs: 更新功能文档和版本变更记录
2026-03-27 07:56:53 +08:00

94 lines
2.9 KiB
Rust

//! Capability manager
use dashmap::DashMap;
use zclaw_types::{AgentId, Capability, CapabilitySet, Result, ZclawError};
/// Manages capabilities for all agents
pub struct CapabilityManager {
capabilities: DashMap<AgentId, CapabilitySet>,
}
impl CapabilityManager {
pub fn new() -> Self {
Self {
capabilities: DashMap::new(),
}
}
/// Grant capabilities to an agent
pub fn grant(&self, agent_id: AgentId, capabilities: Vec<Capability>) {
let set = CapabilitySet {
capabilities,
};
self.capabilities.insert(agent_id, set);
}
/// Revoke all capabilities from an agent
pub fn revoke(&self, agent_id: &AgentId) {
self.capabilities.remove(agent_id);
}
/// Check if an agent can invoke a tool
pub fn can_invoke_tool(&self, agent_id: &AgentId, tool_name: &str) -> bool {
self.capabilities
.get(agent_id)
.map(|set| set.can_invoke_tool(tool_name))
.unwrap_or(false)
}
/// Check if an agent can read memory
pub fn can_read_memory(&self, agent_id: &AgentId, scope: &str) -> bool {
self.capabilities
.get(agent_id)
.map(|set| set.can_read_memory(scope))
.unwrap_or(false)
}
/// Check if an agent can write memory
pub fn can_write_memory(&self, agent_id: &AgentId, scope: &str) -> bool {
self.capabilities
.get(agent_id)
.map(|set| set.can_write_memory(scope))
.unwrap_or(false)
}
/// Validate capabilities for dangerous combinations
///
/// Checks that overly broad capabilities are not combined with
/// dangerous operations. Returns an error if an unsafe combination
/// is detected.
pub fn validate(&self, capabilities: &[Capability]) -> Result<()> {
let has_tool_all = capabilities.iter().any(|c| matches!(c, Capability::ToolAll));
let has_agent_kill = capabilities.iter().any(|c| matches!(c, Capability::AgentKill { .. }));
let has_shell_wildcard = capabilities.iter().any(|c| {
matches!(c, Capability::ShellExec { pattern } if pattern == "*")
});
// ToolAll + destructive operations is dangerous
if has_tool_all && has_agent_kill {
return Err(ZclawError::SecurityError(
"ToolAll 与 AgentKill 不能同时授予".to_string(),
));
}
if has_tool_all && has_shell_wildcard {
return Err(ZclawError::SecurityError(
"ToolAll 与 ShellExec(\"*\") 不能同时授予".to_string(),
));
}
Ok(())
}
/// Get capabilities for an agent
pub fn get(&self, agent_id: &AgentId) -> Option<CapabilitySet> {
self.capabilities.get(agent_id).map(|c| c.clone())
}
}
impl Default for CapabilityManager {
fn default() -> Self {
Self::new()
}
}