package shellstream import ( "encoding/json" "fmt" "os" ) // AccordPolicy defines the local node's policy for granting capabilities // to incoming Shellstream sessions, derived from Guildhouse accords. type AccordPolicy struct { TrustTiers map[string]TierPolicy `json:"trust_tiers"` } // TierPolicy maps a Guildhouse trust tier to allowed Kedge modes and operations. type TierPolicy struct { Mode []string `json:"mode"` // ["overlay"], ["overlay", "underlay"] Operations []string `json:"operations"` // ["read"], ["read", "mutate", "admin"] Subnets []string `json:"subnets"` // ["172.16.0.0/24", "10.0.1.0/24"] } // EvaluateCapability evaluates a capability request against the local accord policy. // Returns the attenuated grant (requested capabilities intersected with policy). func EvaluateCapability(req CapabilityRequest, policyPath string) (*CapabilityGrant, error) { policy, err := loadAccordPolicy(policyPath) if err != nil { return nil, fmt.Errorf("failed to load accord policy: %w", err) } // TODO: Determine the remote peer's trust tier from its SAT token. // For Phase 1, assume "journeyman" tier. tier := "journeyman" tierPolicy, ok := policy.TrustTiers[tier] if !ok { return nil, fmt.Errorf("unknown trust tier: %s", tier) } // Attenuate: grant the intersection of requested and allowed. grantedMode := attenuateMode(req.Mode, tierPolicy.Mode) if grantedMode == "" { return nil, fmt.Errorf("requested mode %s not allowed for tier %s", req.Mode, tier) } grantedOps := attenuateOperations(req.Operations, tierPolicy.Operations) if len(grantedOps) == 0 { return nil, fmt.Errorf("no operations allowed for tier %s", tier) } return &CapabilityGrant{ Mode: grantedMode, Operations: grantedOps, }, nil } func loadAccordPolicy(path string) (*AccordPolicy, error) { data, err := os.ReadFile(path) if err != nil { return nil, err } var policy AccordPolicy if err := json.Unmarshal(data, &policy); err != nil { return nil, err } return &policy, nil } func attenuateMode(requested string, allowed []string) string { for _, m := range allowed { if m == requested || m == "both" { return requested } } // If "both" was requested but only one mode allowed, grant the allowed one. if requested == "both" && len(allowed) > 0 { return allowed[0] } return "" } func attenuateOperations(requested, allowed []string) []string { allowedSet := make(map[string]bool) for _, op := range allowed { allowedSet[op] = true } var granted []string for _, op := range requested { if allowedSet[op] { granted = append(granted, op) } } return granted }