# Reglas de Codificación de IA para Autenticación y Seguridad

> Reglas de AGENTS.md para autenticación y seguridad que evitan que los agentes implementen criptografía personalizada, filtren secretos o omitan verificaciones de autorización.

**Type:** Rule  
**Tools:** Cursor, Claude Code, Codex, Windsurf  
**Stack:** Next.js, TypeScript, PostgreSQL  
**Updated:** 2026-06-08

---

Coloca esto en la raíz de tu repositorio como `AGENTS.md`. Las reglas de seguridad deben ser `strict` — los agentes son altamente capaces de escribir código que es funcionalmente correcto pero introduce vulnerabilidades críticas de autenticación o autorización.

## AGENTS.md

```md title="AGENTS.md"
# Project Rules — Auth and Security

## Authentication — hard rules
- NEVER implement custom password hashing. Use `bcrypt`, `argon2`, or the auth
  library's built-in hashing (Better Auth, Auth.js, Clerk, Supabase Auth). Custom
  hashing is almost always wrong and may be cryptographically broken.
- NEVER store plaintext passwords, plaintext tokens, or plaintext secrets in the
  database. Hash passwords; hash or encrypt tokens before persistence.
- NEVER roll custom JWT signing or verification. Use a well-audited library
  (`jose`, `jsonwebtoken`). Never use `alg: "none"` — reject tokens with no algorithm.
- Session tokens must be at least 128 bits of cryptographic randomness. Use
  `crypto.getRandomValues()` (Web) or `crypto.randomBytes(32)` (Node.js).
  Do NOT use `Math.random()` for any security-relevant value.
- NEVER store session tokens or JWTs in `localStorage`. Use `HttpOnly`, `Secure`,
  `SameSite=Lax` cookies. `localStorage` is readable by any XSS payload on the page.

## Authorization — hard rules
- Every API route and server action MUST check the current user's session before
  accessing data. Do not assume that reaching a route implies authorization.
- Authorization checks must verify ownership or role, not just authentication.
  "Is logged in" is authentication. "Is allowed to read this resource" is authorization.
  Both are required.
- Never pass a user-controlled ID directly into a database query without first
  verifying that the authenticated user has permission to access that record.
  This is an IDOR (Insecure Direct Object Reference) vulnerability.
- In Next.js App Router: run auth checks in middleware OR at the top of every
  Server Component and Server Action that touches user data. Do not rely on
  client-side redirects for access control.

## Secrets management
- All secrets (API keys, database URLs, OAuth client secrets) live in environment
  variables. Validate them with Zod at startup via `src/lib/env.ts`.
- NEVER commit secrets to the repository. If a secret is accidentally committed,
  treat it as compromised immediately — rotate it before doing anything else.
- NEVER log secrets, tokens, or full request bodies that may contain credentials.
  Scrub sensitive fields before logging.
- Client-side code must never contain secrets. In Next.js, only variables prefixed
  with `NEXT_PUBLIC_` are exposed to the client — and only non-sensitive values
  should use that prefix.

## Input validation and output encoding
- Validate all user input at the server boundary with Zod before use. Never trust
  client-provided data, including data in headers, cookies, or URL parameters.
- Sanitize any HTML rendered from user input. Use a library (`DOMPurify`, `sanitize-html`)
  — do NOT write a custom HTML sanitizer.
- When constructing URLs from user input, use the `URL` constructor to parse and
  validate. Never concatenate user input into a URL string that will be fetched
  server-side — this is an SSRF vector.

## CSRF and clickjacking
- All state-mutating endpoints (POST, PUT, PATCH, DELETE) must be protected against
  CSRF. In Next.js App Router, Server Actions are CSRF-protected by default; do not
  disable this. For custom API routes, verify the `Origin` header or use a CSRF token.
- Add `X-Frame-Options: DENY` or `Content-Security-Policy: frame-ancestors 'none'`
  to pages that should not be embedded in iframes.

## Definition of done
- No `Math.random()` calls in authentication or token generation paths.
- No `localStorage` for session/token storage (grep the codebase).
- Every API route handler has an auth check at the top.
- `NEXT_PUBLIC_` env vars contain no secrets (audit the list before shipping).
- Zod validation runs on all form inputs before they touch the database.
```

## Por qué estas reglas

- **No usar `localStorage` para tokens** elimina el error de seguridad más extendido en aplicaciones React/Next.js. Los agentes que copian patrones de autenticación de tutoriales antiguos (anteriores a 2020) frecuentemente almacenan JWTs en `localStorage`, que es trivialmente legible por cualquier script de terceros en la página. Las cookies `HttpOnly` no son accesibles desde JavaScript en absoluto — son el mecanismo de almacenamiento correcto.
- **Las verificaciones de autorización confirman propiedad, no solo autenticación** cierra la vulnerabilidad IDOR que los agentes omiten con mayor frecuencia. Un agente al que se le pide "agregar un endpoint para obtener el pedido de un usuario" típicamente verifica `if (!session)` pero no `if (order.userId !== session.user.id)` — porque la segunda verificación requiere entender la semántica de propiedad del modelo de datos, que es específica del proyecto y no está implícita en la descripción de la tarea.

## Buen ajuste

- Cualquier aplicación con cuentas de usuario, recursos protegidos o datos de pago — esencialmente cualquier aplicación web de producción.

## No es adecuado

- Herramientas internas detrás de una VPN corporativa o control de acceso a nivel de red, donde el modelo de amenazas es diferente y algunos de estos controles pueden ser manejados por la capa de infraestructura.