0102afa06e
Mueve el issue a completed/ y actualiza el índice. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
0024b — Security loader: security/ YAML files + shell/security/ loader
Parte b del issue 0024-centralized-security-groups.md. Requiere 0024a (pkg/security/ tipos).
Objetivo
Crear la carpeta security/ en la raíz del proyecto con los YAML de grupos de usuarios, grupos de agentes y permisos. Crear el loader impuro shell/security/loader.go que los lee y devuelve un security.SecurityPolicy.
Contexto
pkg/security/ya existe (0024a). Este sub-issue añade la capa de persistencia (YAML) y el loader.- Los YAML de
security/se commitean al repositorio — son configuración de acceso, no secrets. - El código se mergea con feature flag = false (loader creado pero no usado todavía).
Arquitectura
security/ NEW — en raíz del proyecto
user-groups.yaml NEW
agent-groups.yaml NEW
permissions.yaml NEW
shell/security/ NEW
loader.go NEW
loader_test.go NEW
Patron pure core / impure shell
security/*.yaml— datos de configuración (no código)shell/security/loader.go— impuro: lee filesystem, parsea YAML, construyesecurity.SecurityPolicy
Tareas
Fase 1: YAML files
- 1.1 Crear
security/user-groups.yaml:# Grupos de usuarios del sistema # Members: lista de Matrix user IDs, o "*" para todos los usuarios groups: admins: members: [] # rellenar con los administradores reales everyone: members: ["*"] - 1.2 Crear
security/agent-groups.yaml:# Grupos de agentes del sistema # Agents: lista de agent IDs (del campo agent.id en config.yaml), o "*" para todos groups: assistants: agents: - assistant-bot - asistente-2 all: agents: ["*"] - 1.3 Crear
security/permissions.yaml:# Políticas de permisos: para cada grupo de agentes, qué acciones tiene cada grupo de usuarios # Actions: "*" = todo, "ask" = chat libre, "command:<name>" = comandos, "tool:<name>" = tools policies: - agent_group: all permissions: - user_group: admins actions: ["*"] - user_group: everyone actions: ["ask"]
Fase 2: Shell loader
- 2.1 Crear
shell/security/loader.gocon funciónLoad(dir string) (security.SecurityPolicy, error):- Lee
<dir>/user-groups.yaml→[]security.UserGroup - Lee
<dir>/agent-groups.yaml→[]security.AgentGroup - Lee
<dir>/permissions.yaml→[]security.AgentPolicy - Si el directorio no existe o está vacío: devuelve
security.SecurityPolicy{}sin error (backward compat) - Si un archivo no existe individualmente: ese campo queda vacío (no es error)
- Si el YAML es inválido: devuelve error con mensaje claro indicando qué archivo falló
- Lee
- 2.2 Definir structs YAML intermedios (solo para parseo) distintos de los tipos puros de
pkg/security/. Convertir tras parsear. Esto mantienepkg/security/independiente degopkg.in/yaml.v3.
Fase 3: Tests del loader
- 3.1 Test: directorio inexistente → policy vacía, sin error
- 3.2 Test: directorio vacío (sin YAML) → policy vacía, sin error
- 3.3 Test: los 3 YAML válidos → policy con todos los campos
- 3.4 Test: solo
user-groups.yamlpresente → user groups poblados, resto vacío - 3.5 Test: YAML malformado → error con nombre de archivo en el mensaje
- 3.6 Test:
user_group: "*"yagent: ["*"]parseados correctamente como strings literales
Fase 4: Cleanup
- 4.1
go build -tags goolm ./...compila - 4.2
go test -tags goolm ./shell/security/...pasa - 4.3
go test -tags goolm ./...pasa completo
Ejemplo de uso
// En el launcher (todavía no wired — eso es 0024c)
policy, err := shellsecurity.Load("security/")
if err != nil {
log.Fatal("error loading security policy", err)
}
// policy.UserGroups, policy.AgentGroups, policy.Policies disponibles
acl := security.ResolveACL("assistant-bot", policy)
Decisiones de diseño
- Structs YAML separados de los tipos puros:
pkg/security/no importagopkg.in/yaml.v3. El loader usa tipos intermedios locales y convierte. Mantiene el core verdaderamente puro. - Directorio no existente = policy vacía: no fuerza a crear los YAML si no se necesitan (ej: agentes puramente públicos). Backward compat con configuraciones existentes.
- 3 archivos separados: cada uno puede editarse independientemente. Los grupos son más estables que los permisos.
Prerequisitos
- 0024a completado (
pkg/security/con tipos yResolveACL)
Riesgos
- Typos en user IDs de YAML: si un Matrix ID tiene un typo, el usuario no tendrá acceso. No hay validación de formato de ID en este issue — es aceptable para MVP.