chore: cerrar issue 0024a-security-types
Mueve el issue a completed/ y actualiza el README de issues.
This commit is contained in:
@@ -32,7 +32,7 @@ afectados y notas de implementacion.
|
||||
| 22c | E2E: Tests de agentes + docs | [0022c-e2e-agent-tests.md](completed/0022c-e2e-agent-tests.md) | completado |
|
||||
| 23 | Seccion de tests en dashboard | [0023-dashboard-tests.md](completed/0023-dashboard-tests.md) | completado |
|
||||
| 24 | Grupos y permisos centralizados | [0024-centralized-security-groups.md](0024-centralized-security-groups.md) | pendiente |
|
||||
| 24a | Security types: pkg/security/ | [0024a-security-types.md](0024a-security-types.md) | pendiente |
|
||||
| 24a | Security types: pkg/security/ | [0024a-security-types.md](completed/0024a-security-types.md) | completado |
|
||||
| 24b | Security loader: shell/security/ | [0024b-security-loader.md](0024b-security-loader.md) | pendiente |
|
||||
| 24c | Security integration + cleanup | [0024c-security-integration.md](0024c-security-integration.md) | pendiente |
|
||||
| 25 | Catálogo cron + scaffolder | [0025-cron-scaffolder.md](completed/0025-cron-scaffolder.md) | completado |
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# 0024a — Security types: pkg/security/ — tipos puros y resolución ACL
|
||||
|
||||
> Parte a del issue [0024-centralized-security-groups.md](0024-centralized-security-groups.md).
|
||||
|
||||
## Objetivo
|
||||
|
||||
Crear el paquete puro `pkg/security/` con los tipos `UserGroup`, `AgentGroup`, `SecurityPolicy` y la función `ResolveACL(agentID, policy) → acl.ACL`. Este paquete es el núcleo de resolución del sistema centralizado de permisos.
|
||||
|
||||
## Contexto
|
||||
|
||||
- `pkg/acl/` ya existe con `ACL`, `Role`, `CanDo()`, `RoleFor()`. Lo reutilizamos como motor de evaluación.
|
||||
- Este sub-issue no toca ningún otro archivo. Es pure core sin dependencias nuevas.
|
||||
- El código se mergea con `centralized-security-groups` feature flag = false (no wired todavía).
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
pkg/security/ NEW
|
||||
groups.go NEW — UserGroup, AgentGroup
|
||||
policy.go NEW — Permission, AgentPolicy, SecurityPolicy
|
||||
resolver.go NEW — ResolveACL()
|
||||
security_test.go NEW
|
||||
```
|
||||
|
||||
### Patron pure core / impure shell
|
||||
|
||||
- `pkg/security/` — **puro**: solo tipos y funciones de transformación. Cero I/O, cero side effects.
|
||||
|
||||
## Tareas
|
||||
|
||||
### Fase 1: Tipos y resolver
|
||||
|
||||
- [ ] **1.1** Crear `pkg/security/groups.go`:
|
||||
```go
|
||||
type UserGroup struct { Name string; Members []string }
|
||||
type AgentGroup struct { Name string; Agents []string }
|
||||
```
|
||||
- [ ] **1.2** Crear `pkg/security/policy.go`:
|
||||
```go
|
||||
type Permission struct { UserGroup string; Actions []string }
|
||||
type AgentPolicy struct { AgentGroup string; Permissions []Permission }
|
||||
type SecurityPolicy struct { UserGroups []UserGroup; AgentGroups []AgentGroup; Policies []AgentPolicy }
|
||||
```
|
||||
- [ ] **1.3** Crear `pkg/security/resolver.go` con `ResolveACL(agentID string, p SecurityPolicy) acl.ACL`:
|
||||
- Iterar `p.Policies` para encontrar `AgentPolicy` cuyo `AgentGroup` sea un grupo que contenga `agentID` o `"*"`, o sea directamente el `agentID`
|
||||
- Para cada `AgentPolicy` que aplique, iterar sus `Permissions`
|
||||
- Resolver `Permission.UserGroup` a los `Members` del grupo correspondiente
|
||||
- Construir `[]acl.Role` y devolver `acl.ACL` via `acl.FromRoles()` (verificar que esta función existe; si no, añadirla a `pkg/acl/`)
|
||||
- [ ] **1.4** Soporte wildcard: `AgentGroup.Agents = ["*"]` → aplica la policy a cualquier agentID; `UserGroup.Members = ["*"]` → rol sin restricción de usuario
|
||||
- [ ] **1.5** Políticas acumulativas: si un agente aparece en múltiples grupos, sus permisos se acumulan (unión de roles)
|
||||
|
||||
### Fase 2: Tests
|
||||
|
||||
- [ ] **2.1** Test: sin política → ACL vacía (todo permitido, comportamiento actual de acl.Empty())
|
||||
- [ ] **2.2** Test: agente en grupo → recibe los permisos del grupo
|
||||
- [ ] **2.3** Test: agente NO en ningún grupo → ACL vacía
|
||||
- [ ] **2.4** Test: wildcard de agente `"*"` → todos los agentes reciben los permisos
|
||||
- [ ] **2.5** Test: wildcard de usuario `"*"` → todos los usuarios reciben la acción
|
||||
- [ ] **2.6** Test: múltiples grupos que incluyen al agente → permisos acumulados (unión)
|
||||
- [ ] **2.7** Test: agente referenciado directamente por ID en `AgentPolicy.AgentGroup` (sin definir grupo) → recibe permisos
|
||||
|
||||
### Fase 3: Cleanup
|
||||
|
||||
- [ ] **3.1** `go build -tags goolm ./...` compila sin errores
|
||||
- [ ] **3.2** `go test -tags goolm ./pkg/security/...` pasa
|
||||
|
||||
## Ejemplo de uso
|
||||
|
||||
```go
|
||||
policy := security.SecurityPolicy{
|
||||
UserGroups: []security.UserGroup{
|
||||
{Name: "admins", Members: []string{"@alice:matrix.org"}},
|
||||
{Name: "everyone", Members: []string{"*"}},
|
||||
},
|
||||
AgentGroups: []security.AgentGroup{
|
||||
{Name: "all", Agents: []string{"*"}},
|
||||
},
|
||||
Policies: []security.AgentPolicy{
|
||||
{
|
||||
AgentGroup: "all",
|
||||
Permissions: []security.Permission{
|
||||
{UserGroup: "admins", Actions: []string{"*"}},
|
||||
{UserGroup: "everyone", Actions: []string{"ask"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
acl := security.ResolveACL("assistant-bot", policy)
|
||||
acl.CanDo("@alice:matrix.org", "tool:ssh_command") // true (admin → "*")
|
||||
acl.CanDo("@unknown:matrix.org", "ask") // true (everyone → "ask")
|
||||
acl.CanDo("@unknown:matrix.org", "command:deploy") // false
|
||||
```
|
||||
|
||||
## Decisiones de diseño
|
||||
|
||||
- **No reemplazar pkg/acl/**: este paquete produce `acl.ACL`, no lo sustituye. Máxima reutilización.
|
||||
- **AgentPolicy.AgentGroup acepta nombre de grupo O ID directo de agente**: permite asignar permisos a un agente individual sin crear un grupo de un solo elemento.
|
||||
- **Unión de permisos entre grupos**: si un agente está en `assistants` y en `all`, recibe la unión de sus permisos. Seguro: siempre da más acceso, nunca menos de lo esperado.
|
||||
|
||||
## Prerequisitos
|
||||
|
||||
- `pkg/acl/` compilando (completado en issue 0010)
|
||||
|
||||
## Riesgos
|
||||
|
||||
- **acl.FromRoles() puede no existir**: si `pkg/acl/` solo expone `FromMap(map[string]RoleDef)`, añadir `FromRoles([]Role) ACL` en ese paquete como parte de esta tarea. Es una adición mínima.
|
||||
Reference in New Issue
Block a user