payload-cms-securitylisted
Install: claude install-skill GoldenWing-360/claude-security-skills
# Payload CMS Security
Payload (v2 / v3) gives you a powerful headless CMS in a Node app, but its security depends almost entirely on the **access functions you write per collection and per field**. Defaults are reasonable but not strict — production-readiness requires intentional config.
## When to invoke
- Shipping a Payload app to production
- Opening the admin UI to non-developer team members or clients
- After a Payload major version upgrade (v2 → v3)
- Adding a new collection, especially user-generated or multi-tenant data
- Investigating a "user X saw user Y's data" incident
## Step 1 — Lock the admin UI
By default the admin is at `/admin` on the same origin as the app. That is a permanent target.
Three layers of defense, use at least two:
1. **Zero Trust / IP allowlist in front** — put `/admin` behind SSO with Cloudflare Access, Tailscale, or a VPN. The admin should not be reachable from the open internet for most projects. See [`cloudflare-hardening`](../cloudflare-hardening/SKILL.md).
2. **Rate limit auth endpoints** — `/api/users/login` and friends. Cloudflare Rate Limit or `express-rate-limit` on the Express app.
3. **Strong auth for admin users** — long passphrases, MFA where supported (Payload v3 has plugins for this), no shared accounts.
Optional but worth it: move `/admin` to an unguessable path via `routes.admin`. Not strong security, but cuts noise:
```ts
// payload.config.ts
export default buildConfig({
routes: { admin: '/cms-' + process.env.ADMI