gomcp/internal/domain/identity/capability.go

72 lines
2 KiB
Go

package identity
// CapabilityDecision represents the result of a capability check.
type CapabilityDecision struct {
Allowed bool `json:"allowed"`
AgentID string `json:"agent_id"`
ToolName string `json:"tool_name"`
Reason string `json:"reason"`
}
// CapabilityChecker verifies agent permissions against the identity store.
// Integrates with DIP Oracle — called before tool execution.
type CapabilityChecker struct {
store *Store
}
// NewCapabilityChecker creates a capability checker backed by the identity store.
func NewCapabilityChecker(store *Store) *CapabilityChecker {
return &CapabilityChecker{store: store}
}
// Check verifies that the agent has the required permission for the tool.
// Returns DENY for: unknown agent, unknown tool, missing permission (fail-safe closed).
func (c *CapabilityChecker) Check(agentID, toolName string, perm Permission) CapabilityDecision {
agent, err := c.store.Get(agentID)
if err != nil {
return CapabilityDecision{
Allowed: false,
AgentID: agentID,
ToolName: toolName,
Reason: "agent_not_found",
}
}
if !agent.HasPermission(toolName, perm) {
// Determine specific denial reason
reason := "unknown_tool_for_agent"
if agent.HasTool(toolName) {
reason = "insufficient_permissions"
}
return CapabilityDecision{
Allowed: false,
AgentID: agentID,
ToolName: toolName,
Reason: reason,
}
}
// Update last seen timestamp
_ = c.store.UpdateLastSeen(agentID)
return CapabilityDecision{
Allowed: true,
AgentID: agentID,
ToolName: toolName,
Reason: "allowed",
}
}
// CheckExternal verifies capability for an EXTERNAL agent type.
// External agents have additional restrictions: no EXECUTE permission ever.
func (c *CapabilityChecker) CheckExternal(agentID, toolName string, perm Permission) CapabilityDecision {
if perm == PermExecute {
return CapabilityDecision{
Allowed: false,
AgentID: agentID,
ToolName: toolName,
Reason: "external_agents_cannot_execute",
}
}
return c.Check(agentID, toolName, perm)
}