Stack · Vercel
Release testing for Next.js apps
Server actions are endpoints, page checks do not protect them, and NEXT_PUBLIC_ variables reach the browser. The checklist tests the app the way a request does, not the way the UI does.
TermsAPI (the interface other software calls; tested directly, without the UI in between) · row-level security (database rules that decide which rows each signed-in user may read or write) · two-user test (sign in as one user, create a row, then try to read or change it as another user; pass is nothing comes back) · critical flow (a path a user takes that costs money or trust if it breaks: sign-up, checkout, invite, export) · verdict (a one-word release result (pass, pass with findings, fail) with the findings and the checklist version behind it) · CI (the pipeline that builds and tests every change before it can be merged or deployed) · client bundle (the JavaScript your app sends to the browser or ships inside the mobile app; anyone can read it)
What Next.js changes in a codebase
Server components, server actions and route handlers put data access and mutations in the same codebase as the UI. The security assumptions differ from a client-only app.
Most AI-assisted web apps we see are Next.js apps. The framework's own data security guide reads like a test plan: call actions directly, re-check authorization inside them, validate client input, return minimal objects. The checklist runs that plan on every release.
Defaults, from the docs verified 2026-09-21
| Default, from the docs | Why it matters for release testing | Source |
|---|---|---|
| "By default, when a Server Action is created and exported, it is reachable via a direct POST request, not just through your application's UI." | Every exported action is an endpoint; AU-02 calls each one directly without a session. | docs verified 2026-09-21 |
| "A page-level authentication check does not extend to the Server Actions defined within it. Always re-verify inside the action." | The gated-page, open-action pattern; AC-04 and AU-02 test the action, not the page. | docs verified 2026-09-21 |
| "By default, environment variables are only available on the Server. Next.js exposes any environment variable prefixed with NEXT_PUBLIC_ to the client." | SC-03 lists every NEXT_PUBLIC_ variable and confirms each value is meant to be public. | docs verified 2026-09-21 |
| Passing a whole database row from a Server Component to a Client Component "exposes all the fields in userData to the client"; the docs recommend a Data Access Layer returning minimal DTOs. | AC-05 reads the server-component payload for the most sensitive screens. | docs verified 2026-09-21 |
| "You should always validate input from client, as they can be easily modified. For example, form data, URL parameters, headers, and searchParams." | Role flags and amounts in the request are the test inputs for AC-04 and PY-04. | docs verified 2026-09-21 |
| Server Actions compare the Origin header to the Host header and only accept POST, which "prevents most CSRF vulnerabilities"; custom route handlers do not inherit this. | AU-05 tests route handlers and any endpoint outside the action mechanism. | docs verified 2026-09-21 |
Each row was read on the linked page on the date shown. Docs change; the date tells you how current the row is. Next.js documentation.
Failure patterns most associated
- criticalAPI key shipped in the client bundle
A key meant for the server ends up in JavaScript the browser downloads, so anyone can read it and call the service as the app.
- criticalList endpoint returns other tenants' rows
A list or search endpoint filters by the wrong column or none, so a user sees records belonging to other accounts.
- criticalObject fetched by id without an ownership check
An endpoint checks that the caller is logged in, then returns whatever id was requested.
- criticalAdmin gate enforced only in the UI
The admin page hides its buttons from ordinary users, but the underlying route or action accepts calls from anyone logged in.
- criticalRole or flag read from the request
The server decides what a user may do from a role, plan or isAdmin value that arrived in the request body, query string or client state.
- criticalProtected route checked only in the browser
A redirect in client code hides the page from signed-out users while the data endpoint behind it answers anyone.
- criticalServer action without its own auth check
The page checks the session, but the exported action it calls does not, and actions can be invoked by direct POST.
- criticalRegistration or verification endpoint usable without prerequisites
An endpoint in the sign-up or verification flow accepts calls out of order, so an account can be created or verified without the intended step.
How the checklist adapts
- AU-02 POSTs to every exported server action without a session and with a foreign session.
- AC-04 and AC-05 read the server-component payload for private fields and test admin actions as a regular user.
- SC-03 lists every NEXT_PUBLIC_ variable and confirms each is meant to be public.
- AU-05 tests route handlers, which do not inherit the Origin check server actions have.
Release checklist, five of the published items
v1.0 · verified on 2026-09-21Server actions and API mutations re-check authentication and authorization
automated Invoke each server action or mutation endpoint directly by POST, without a session and with another user's session.
Every mutation rejects the unauthenticated call and the foreign-user call.
Admin functions are verified on the server
automated Call every admin route and admin server action as a regular user, with and without an admin flag set in the client state or query string.
Every admin route and action rejects the regular user regardless of client-side flags.
Public environment prefix carries only public values
manual List every variable with a client-exposed prefix (NEXT_PUBLIC_, EXPO_PUBLIC_, VITE_, REACT_APP_) and confirm each one is meant to be public.
Every client-prefixed variable is documented as public; no variable holds a key that can write or read beyond the anonymous role.
No secret keys in client bundles
automated Scan the built client assets (JS, source maps, HTML) for known key prefixes and for every value present in the server environment file.
Zero matches for key prefixes (sk_, service_role, AKIA, whsec_, private keys) and zero server-only env values found in client assets.
The client receives only the fields it renders
manual Inspect API responses and the server-component payload for the five most sensitive screens and list every field returned.
No password hash, token, internal note, other user's email or billing detail appears in any inspected payload.
Which plan fits
Growth $5,900/mo
Growth when there is an API or daily releases; Starter for a small web-only app releasing weekly.
For 8-15 engineers, daily releases, web plus API or one mobile platform. Limits, cadence and what is not included.
Questions
Next.js release testing checklist
Next.js server actions security testing
Next.js production checklist
Get a risk list for your codebase
5 business days, $1,200, credited to the first month.