feat: integrar RBAC y allowlist de usuarios en runtime y listener

Cambios en 3 archivos:
- agents/runtime.go: construye ACL desde config de roles, verifica permisos
  antes de ejecutar comandos (command:<name>), interacción LLM (ask) y
  ejecución de tools (tool:<name>). Mensajes denegados se loguean y
  responden al usuario.
- shell/matrix/listener.go: filtra invites y mensajes de usuarios no
  autorizados cuando se configura allowed_users (allowlist vacía = todos).
- internal/config/schema.go: añade campos AllowedUsers y
  UnauthorizedResponse a FiltersCfg para soportar la allowlist en config.

Esto conecta el paquete pkg/acl con el runtime para dar soporte completo
a control de acceso por rol, sin romper la compatibilidad (ACL vacío
permite todo como antes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 17:59:09 +00:00
parent 386e4d3dcb
commit b60782959d
3 changed files with 81 additions and 6 deletions
+32
View File
@@ -84,6 +84,23 @@ func (l *Listener) Run(ctx context.Context) error {
if membership != event.MembershipInvite {
return
}
// Invite gating: if allowlist is configured, reject invites from unauthorized users
if len(l.cfg.Filters.AllowedUsers) > 0 {
allowed := false
for _, u := range l.cfg.Filters.AllowedUsers {
if evt.Sender.String() == u {
allowed = true
break
}
}
if !allowed {
l.logger.Info("rejecting invite from unauthorized user",
"room", evt.RoomID, "inviter", evt.Sender)
return
}
}
l.logger.Info("received room invite, joining", "room", evt.RoomID, "inviter", evt.Sender)
if _, err := l.client.raw.JoinRoom(ctx, evt.RoomID.String(), "", nil); err != nil {
l.logger.Error("failed to auto-join room", "room", evt.RoomID, "err", err)
@@ -208,6 +225,21 @@ func (l *Listener) shouldHandle(evt *event.Event) bool {
}
}
// Check allowlist — if configured, only allowed users can talk to the bot
if len(f.AllowedUsers) > 0 {
allowed := false
for _, u := range f.AllowedUsers {
if evt.Sender.String() == u {
allowed = true
break
}
}
if !allowed {
l.logger.Debug("ignoring unauthorized user", "sender", evt.Sender)
return false
}
}
// Check if room is in the listen list
if len(l.cfg.Rooms.Listen) > 0 {
allowed := false