Align SLURP access control with config authority levels

This commit is contained in:
anthonyrawlins
2025-09-27 15:33:23 +10:00
parent 0b670a535d
commit a99469f346
3 changed files with 157 additions and 148 deletions

View File

@@ -274,14 +274,13 @@ func (c *Config) ApplyRoleDefinition(role string) error {
} }
// GetRoleAuthority returns the authority level for a role (from CHORUS) // GetRoleAuthority returns the authority level for a role (from CHORUS)
func (c *Config) GetRoleAuthority(role string) (string, error) { func (c *Config) GetRoleAuthority(role string) (AuthorityLevel, error) {
// This would contain the authority mapping from CHORUS roles := GetPredefinedRoles()
switch role { if def, ok := roles[role]; ok {
case "admin": return def.AuthorityLevel, nil
return "master", nil
default:
return "member", nil
} }
return AuthorityReadOnly, fmt.Errorf("unknown role: %s", role)
} }
// Helper functions for environment variable parsing // Helper functions for environment variable parsing

View File

@@ -2,12 +2,18 @@ package config
import "time" import "time"
// Authority levels for roles // AuthorityLevel represents the privilege tier associated with a role.
type AuthorityLevel string
// Authority levels for roles (aligned with CHORUS hierarchy).
const ( const (
AuthorityReadOnly = "readonly" AuthorityMaster AuthorityLevel = "master"
AuthoritySuggestion = "suggestion" AuthorityAdmin AuthorityLevel = "admin"
AuthorityFull = "full" AuthorityDecision AuthorityLevel = "decision"
AuthorityAdmin = "admin" AuthorityCoordination AuthorityLevel = "coordination"
AuthorityFull AuthorityLevel = "full"
AuthoritySuggestion AuthorityLevel = "suggestion"
AuthorityReadOnly AuthorityLevel = "readonly"
) )
// SecurityConfig defines security-related configuration // SecurityConfig defines security-related configuration
@@ -47,7 +53,7 @@ type RoleDefinition struct {
Description string `yaml:"description"` Description string `yaml:"description"`
Capabilities []string `yaml:"capabilities"` Capabilities []string `yaml:"capabilities"`
AccessLevel string `yaml:"access_level"` AccessLevel string `yaml:"access_level"`
AuthorityLevel string `yaml:"authority_level"` AuthorityLevel AuthorityLevel `yaml:"authority_level"`
Keys *AgeKeyPair `yaml:"keys,omitempty"` Keys *AgeKeyPair `yaml:"keys,omitempty"`
AgeKeys *AgeKeyPair `yaml:"age_keys,omitempty"` // Legacy field name AgeKeys *AgeKeyPair `yaml:"age_keys,omitempty"` // Legacy field name
CanDecrypt []string `yaml:"can_decrypt,omitempty"` // Roles this role can decrypt CanDecrypt []string `yaml:"can_decrypt,omitempty"` // Roles this role can decrypt
@@ -61,7 +67,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Project coordination and management", Description: "Project coordination and management",
Capabilities: []string{"coordination", "planning", "oversight"}, Capabilities: []string{"coordination", "planning", "oversight"},
AccessLevel: "high", AccessLevel: "high",
AuthorityLevel: AuthorityAdmin, AuthorityLevel: AuthorityMaster,
CanDecrypt: []string{"project_manager", "backend_developer", "frontend_developer", "devops_engineer", "security_engineer"}, CanDecrypt: []string{"project_manager", "backend_developer", "frontend_developer", "devops_engineer", "security_engineer"},
}, },
"backend_developer": { "backend_developer": {
@@ -69,7 +75,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Backend development and API work", Description: "Backend development and API work",
Capabilities: []string{"backend", "api", "database"}, Capabilities: []string{"backend", "api", "database"},
AccessLevel: "medium", AccessLevel: "medium",
AuthorityLevel: AuthorityFull, AuthorityLevel: AuthorityDecision,
CanDecrypt: []string{"backend_developer"}, CanDecrypt: []string{"backend_developer"},
}, },
"frontend_developer": { "frontend_developer": {
@@ -77,7 +83,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Frontend UI development", Description: "Frontend UI development",
Capabilities: []string{"frontend", "ui", "components"}, Capabilities: []string{"frontend", "ui", "components"},
AccessLevel: "medium", AccessLevel: "medium",
AuthorityLevel: AuthorityFull, AuthorityLevel: AuthorityCoordination,
CanDecrypt: []string{"frontend_developer"}, CanDecrypt: []string{"frontend_developer"},
}, },
"devops_engineer": { "devops_engineer": {
@@ -85,7 +91,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Infrastructure and deployment", Description: "Infrastructure and deployment",
Capabilities: []string{"infrastructure", "deployment", "monitoring"}, Capabilities: []string{"infrastructure", "deployment", "monitoring"},
AccessLevel: "high", AccessLevel: "high",
AuthorityLevel: AuthorityFull, AuthorityLevel: AuthorityDecision,
CanDecrypt: []string{"devops_engineer", "backend_developer"}, CanDecrypt: []string{"devops_engineer", "backend_developer"},
}, },
"security_engineer": { "security_engineer": {
@@ -93,7 +99,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Security oversight and hardening", Description: "Security oversight and hardening",
Capabilities: []string{"security", "audit", "compliance"}, Capabilities: []string{"security", "audit", "compliance"},
AccessLevel: "high", AccessLevel: "high",
AuthorityLevel: AuthorityAdmin, AuthorityLevel: AuthorityMaster,
CanDecrypt: []string{"security_engineer", "project_manager", "backend_developer", "frontend_developer", "devops_engineer"}, CanDecrypt: []string{"security_engineer", "project_manager", "backend_developer", "frontend_developer", "devops_engineer"},
}, },
"security_expert": { "security_expert": {
@@ -101,7 +107,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Advanced security analysis and policy work", Description: "Advanced security analysis and policy work",
Capabilities: []string{"security", "policy", "response"}, Capabilities: []string{"security", "policy", "response"},
AccessLevel: "high", AccessLevel: "high",
AuthorityLevel: AuthorityAdmin, AuthorityLevel: AuthorityMaster,
CanDecrypt: []string{"security_expert", "security_engineer", "project_manager"}, CanDecrypt: []string{"security_expert", "security_engineer", "project_manager"},
}, },
"senior_software_architect": { "senior_software_architect": {
@@ -109,7 +115,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Architecture governance and system design", Description: "Architecture governance and system design",
Capabilities: []string{"architecture", "design", "coordination"}, Capabilities: []string{"architecture", "design", "coordination"},
AccessLevel: "high", AccessLevel: "high",
AuthorityLevel: AuthorityAdmin, AuthorityLevel: AuthorityDecision,
CanDecrypt: []string{"senior_software_architect", "project_manager", "backend_developer", "frontend_developer"}, CanDecrypt: []string{"senior_software_architect", "project_manager", "backend_developer", "frontend_developer"},
}, },
"qa_engineer": { "qa_engineer": {
@@ -117,7 +123,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
Description: "Quality assurance and testing", Description: "Quality assurance and testing",
Capabilities: []string{"testing", "validation"}, Capabilities: []string{"testing", "validation"},
AccessLevel: "medium", AccessLevel: "medium",
AuthorityLevel: AuthorityFull, AuthorityLevel: AuthorityCoordination,
CanDecrypt: []string{"qa_engineer", "backend_developer", "frontend_developer"}, CanDecrypt: []string{"qa_engineer", "backend_developer", "frontend_developer"},
}, },
"readonly_user": { "readonly_user": {

View File

@@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"time" "time"
"chorus/pkg/ucxl"
"chorus/pkg/config" "chorus/pkg/config"
"chorus/pkg/ucxl"
) )
// ContextNode represents a hierarchical context node in the SLURP system. // ContextNode represents a hierarchical context node in the SLURP system.
@@ -302,8 +302,12 @@ func AuthorityToAccessLevel(authority config.AuthorityLevel) RoleAccessLevel {
switch authority { switch authority {
case config.AuthorityMaster: case config.AuthorityMaster:
return AccessCritical return AccessCritical
case config.AuthorityAdmin:
return AccessCritical
case config.AuthorityDecision: case config.AuthorityDecision:
return AccessHigh return AccessHigh
case config.AuthorityFull:
return AccessHigh
case config.AuthorityCoordination: case config.AuthorityCoordination:
return AccessMedium return AccessMedium
case config.AuthoritySuggestion: case config.AuthoritySuggestion:
@@ -398,8 +402,8 @@ func (cn *ContextNode) HasRole(role string) bool {
// CanAccess checks if a role can access this context based on authority level // CanAccess checks if a role can access this context based on authority level
func (cn *ContextNode) CanAccess(role string, authority config.AuthorityLevel) bool { func (cn *ContextNode) CanAccess(role string, authority config.AuthorityLevel) bool {
// Master authority can access everything // Master/Admin authority can access everything
if authority == config.AuthorityMaster { if authority == config.AuthorityMaster || authority == config.AuthorityAdmin {
return true return true
} }