Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Cluster 3+ scout_report hits on the same SSID within 10 minutes; server infers airport/campus/retail venue class and pushes persona spread_policy. Emberwake weather-map merges active scout biomes. Includes agent, server API, and Vitest coverage.
115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package clearance
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
)
|
||
|
||
// Security clearance levels (L0–L4).
|
||
const (
|
||
L0 = 0 // stats / read-only
|
||
L1 = 1 // mining commands
|
||
L2 = 2 // spread
|
||
L3 = 3 // shell
|
||
L4 = 4 // forge / version
|
||
)
|
||
|
||
// LevelLabel returns the badge string for a clearance level.
|
||
func LevelLabel(level int) string {
|
||
if level < L0 {
|
||
level = L0
|
||
}
|
||
if level > L4 {
|
||
level = L4
|
||
}
|
||
return fmt.Sprintf("L%d", level)
|
||
}
|
||
|
||
// LevelPermissions describes what each level allows (UI tooltips).
|
||
func LevelPermissions(level int) string {
|
||
switch level {
|
||
case L0:
|
||
return "stats and read-only probes"
|
||
case L1:
|
||
return "mining: pause, resume, restart"
|
||
case L2:
|
||
return "spread: discover_and_join, spread_now, stage_fetch"
|
||
case L3:
|
||
return "shell: exec_shell, agent_command"
|
||
case L4:
|
||
return "forge: set_agent_version, reorder_tiers fleet-wide"
|
||
default:
|
||
return "unknown clearance"
|
||
}
|
||
}
|
||
|
||
// ActionRequiredLevel maps a remote agent action to the minimum clearance level.
|
||
func ActionRequiredLevel(action string) int {
|
||
switch normalizeKey(action) {
|
||
case "pause", "resume", "restart", "restart_mining", "start_mining", "stop":
|
||
return L1
|
||
case "discover_and_join", "spread_now", "stage_fetch":
|
||
return L2
|
||
case "exec", "exec_shell", "powershell", "agent_command":
|
||
return L3
|
||
case "fetch_module", "set_agent_version", "reorder_tiers", "adaptive_strategy_update", "spread_graft":
|
||
return L4
|
||
default:
|
||
return L0
|
||
}
|
||
}
|
||
|
||
// CommandRequiredLevel maps a fleet AI command type to the minimum clearance level.
|
||
func CommandRequiredLevel(cmdType string, args map[string]interface{}) int {
|
||
typ := normalizeKey(cmdType)
|
||
switch typ {
|
||
case "noop", "":
|
||
return L0
|
||
case "restart_mining":
|
||
return L1
|
||
case "discover_and_join", "spread_now", "stage_fetch":
|
||
return L2
|
||
case "agent_command":
|
||
if args != nil {
|
||
if action, ok := args["action"].(string); ok && action != "" {
|
||
return ActionRequiredLevel(action)
|
||
}
|
||
}
|
||
return L3
|
||
case "bulk_command":
|
||
if args != nil {
|
||
if action, ok := args["action"].(string); ok && action != "" {
|
||
return ActionRequiredLevel(action)
|
||
}
|
||
}
|
||
return L1
|
||
case "set_agent_version", "reorder_tiers", "spread_graft":
|
||
return L4
|
||
default:
|
||
return ActionRequiredLevel(typ)
|
||
}
|
||
}
|
||
|
||
// EnforceClearance returns an error when agentClearance is below the command requirement.
|
||
func EnforceClearance(cmdType string, args map[string]interface{}, agentClearance int) error {
|
||
required := CommandRequiredLevel(cmdType, args)
|
||
if agentClearance >= required {
|
||
return nil
|
||
}
|
||
return fmt.Errorf("clearance %s insufficient for %s (requires %s)", LevelLabel(agentClearance), cmdType, LevelLabel(required))
|
||
}
|
||
|
||
// EnforceAction is the manual API path for raw agent actions.
|
||
func EnforceAction(action string, agentClearance int) error {
|
||
required := ActionRequiredLevel(action)
|
||
if agentClearance >= required {
|
||
return nil
|
||
}
|
||
return fmt.Errorf("clearance %s insufficient for %s (requires %s)", LevelLabel(agentClearance), action, LevelLabel(required))
|
||
}
|
||
|
||
func normalizeKey(s string) string {
|
||
s = strings.TrimSpace(strings.ToLower(s))
|
||
return strings.ReplaceAll(s, "-", "_")
|
||
}
|