Files
viettranx 7aa47d1baf refactor(security): remove cross-tenant bypass, enforce strict tenant isolation
- Add RoleOwner ("owner") to permissions hierarchy (above admin)
- Replace all IsCrossTenant/client.IsCrossTenant() permission guards with
  IsOwnerRole/client.IsOwner() role-based checks (20+ locations)
- Remove cross-tenant bypass from tenantClauseN SQL helper — always adds
  AND tenant_id = $N (fail-closed)
- Add explicit unscoped store methods for startup: ListAllProviders,
  ListAllInstances, ListAllEnabled, GetByIDUnscoped, GetTeamUnscoped
- Remove CrossTenant from auth layer: owner users get role "owner" with
  concrete tenant ID (MasterTenantID fallback), no bypass flag
- Remove crossTenant field from WS Client; connect response sends
  is_owner instead of cross_tenant
- Simplify event filter from 3-mode to 2-mode (tenant-scoped + owner sees system events)
- Fix channel instance loader to use inst.TenantID for agent lookup
- Fix agent embedding goroutine to capture tenant from caller context
- Fix provider cache invalidation to use event.TenantID
- Separate skills store: ListAllSystemSkills (system only) vs
  ListAllSkills (system + tenant-scoped), StoreMissingDeps restricted
  to system skills only
- Frontend: isCrossTenant → isOwner, add "owner" to UserRole type,
  RequireAdmin uses hasMinRole for owner > admin hierarchy
2026-03-24 20:40:59 +07:00

23 lines
555 B
Go

package pg
import (
"context"
"fmt"
"github.com/google/uuid"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
// GetByIDUnscoped returns an agent by ID without tenant filtering. Server-internal only.
func (s *PGAgentStore) GetByIDUnscoped(ctx context.Context, id uuid.UUID) (*store.AgentData, error) {
row := s.db.QueryRowContext(ctx,
`SELECT `+agentSelectCols+`
FROM agents WHERE id = $1 AND deleted_at IS NULL`, id)
d, err := scanAgentRow(row)
if err != nil {
return nil, fmt.Errorf("agent not found: %s", id)
}
return d, nil
}