TrenzaCR

trenza-security

0
0
# Install this skill:
npx skills add TrenzaCR/trenzaos-config --skill "trenza-security"

Install specific skill from multi-skill repository

# Description

>

# SKILL.md


name: trenza-security
description: >
Estándares de seguridad y políticas RLS para TrenzaOS.
Trigger: Al escribir código que accede a la base de datos, autenticación, o políticas de seguridad.
license: MIT
metadata:
author: trenza
version: "1.0"


TrenzaOS Security Skills

Purpose

Este skill enforce las reglas de seguridad obligatorias de TrenzaOS para todo desarrollo.

Core Rules

1. PROHIBICIÓN DE service_role

  • NUNCA uses service_role_key en Server Components, Server Actions, API Routes, o cualquier código expuesto al cliente
  • ✅ Solo usa el JWT del usuario autenticado
  • ✅ Si necesitas acceso privilegiado, crea una Edge Function con validación explícita

2. AISLAMIENTOS OBLIGATORIOS

Todo acceso a datos DEBE incluir:

// SIEMPRE: Filtrar por tenant_id
const products = await db.query.products.findMany({
  where: eq(products.tenantId, currentTenantId)  // ✅ Obligatorio
})

// NUNCA: Confiar en tenant_id del cliente
const products = await db.query.products.findMany({
  where: eq(products.tenantId, formData.get('tenantId'))  // ❌ PROHIBIDO
})

3. Row Level Security (RLS)

Toda tabla de negocio DEBE tener:

-- Política de aislamiento obligatoria
CREATE POLICY "table_tenant_isolation" ON table_name
  FOR ALL
  USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid)
  WITH CHECK (tenant_id = current_setting('app.current_tenant_id', true)::uuid);

Checklist para nuevas tablas:
- [ ] tenant_id como columna obligatoria
- [ ] Columnas auditoras: created_by, created_at, updated_at
- [ ] RLS habilitado: ALTER TABLE enable ROW LEVEL SECURITY
- [ ] Política de aislamiento creada
- [ ] Índice en tenant_id

4. Protección Contra IDOR

  • ✅ Usa UUIDs, NUNCA IDs secuenciales
  • ✅ Valida ownership server-side antes de mutaciones
  • ✅ Usa Signed URLs para recursos compartidos
// Validar ownership
async function validateOwnership(resourceId: string, userId: string) {
  const resource = await db.query.resources.findFirst({
    where: and(
      eq(resources.id, resourceId),
      eq(resources.ownerId, userId)
    )
  })

  if (!resource) throw new ForbiddenError('RESOURCE_NOT_OWNED')
}

5. Error Handling

  • ❌ NUNCA expongas errores crudos al cliente
  • ✅ Mapea a error_code y mensaje genérico
catch (error) {
  console.error('Operation failed:', error)
  return {
    status: 'error',
    error_code: 'INTERNAL_ERROR',
    message: 'Ha ocurrido un error interno'
  }
}

Security Checklist

Antes de escribir código, verifica:

  • [ ] ¿Estoy usando service_role? → ELIMINAR
  • [ ] ¿Tengo tenant_id en el WHERE? → AGREGAR
  • [ ] ¿La tabla tiene RLS? → CREAR política
  • [ ] ¿Estoy exponiendo errores crudos? → MAPEAR a error_code
  • [ ] ¿Uso UUIDs? → SÍ, nunca IDs secuenciales

References

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.