Strapi
Strapi Permissions & Public APIs: Avoiding Common Security Mistakes
How to set Strapi permissions and expose public APIs without leaking drafts or private data.
Strapi’s role-based permissions control who can hit which endpoints and which fields are returned. Misconfiguration often leads to published content that shouldn’t be public or draft content leaking. Here’s how to avoid that.
Public vs authenticated roles
The Public role is used for unauthenticated requests (e.g. your Next.js app fetching content). Give Public only the permissions it needs: typically “find” and “findOne” on collection types that are meant to be public (e.g. Post, Page). Do not grant “create,” “update,” or “delete” to Public. For single types (e.g. Homepage), grant “find” only. Use a separate role (e.g. Authenticated or a custom “Frontend draft” role) with a token for draft or restricted content, and don’t expose that token to the browser.
Draft and publish
If you use Strapi’s draft & publish, the default “find” and “findOne” only return published entries for Public. So with Public permissions set correctly, unpublished content is not returned. When you need to show drafts (e.g. Next.js preview), use a dedicated token and a role that can access draft content; pass the token from your backend or a secure preview route, not from the client. Never grant Public permission to see drafts.
Field-level and relation exposure
Review which fields each content type exposes. Sensitive fields (e.g. internal notes, author email) should not be in the response for Public. Use Strapi’s field-level permissions if your version supports them, or create a separate “public” API or controller that returns only safe fields. For relations, only populate what the front end needs; avoid exposing full user or admin data through relations.
Rate limiting and CORS
In production, put Strapi behind a reverse proxy or use a plugin for rate limiting so the API isn’t abused. Configure CORS so only your front-end origin (and preview URLs if needed) can call the API. Restrict admin panel access by IP or VPN if possible. Keep Strapi and its dependencies updated so you get security fixes.
Summary
Give Public only find/findOne on content that’s meant to be public; never give Public create/update/delete or draft access. Use a token and a separate role for draft content. Limit exposed fields and relations, and add rate limiting and CORS. That keeps Strapi permissions and public APIs secure.