P PasteCode
Rule

AI Coding Rules for Auth and Security

AGENTS.md rules for authentication and security that prevent agents from rolling custom crypto, leaking secrets, or bypassing authorization checks.

CursorClaude CodeCodexWindsurf Next.jsTypeScriptPostgreSQL
.md .json Updated Jun 8, 2026

Drop this in your repo root as AGENTS.md. Security rules must be strict — agents are highly capable of writing code that is functionally correct but introduces critical authentication or authorization vulnerabilities.

AGENTS.md

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.

Why these rules

  • No localStorage for tokens eliminates the most widespread security mistake in React/Next.js applications. Agents that copy authentication patterns from older tutorials (pre-2020) frequently store JWTs in localStorage, which is trivially readable by any third-party script on the page. HttpOnly cookies are not accessible from JavaScript at all — they are the correct storage mechanism.
  • Authorization checks verify ownership, not just authentication closes the IDOR vulnerability that agents most commonly miss. An agent asked to “add an endpoint to fetch a user’s order” will typically check if (!session) but not if (order.userId !== session.user.id) — because the second check requires understanding the data model’s ownership semantics, which are project-specific and not implied by the task description.

Good fit

  • Any application with user accounts, protected resources, or payment data — essentially any production web application.

Not a fit

  • Internal tools behind a corporate VPN or network-level access control, where the threat model is different and some of these controls may be handled by the infrastructure layer.