Safeguard
Security Guides•

Next.js data access layer and DTOs, explained

A data access layer is a server-only module that checks authorization and returns minimal objects. Why Next.js recommends it for new projects.

Safeguard Security Team
3 min read

A data access layer, or DAL, is an internal server-only library that decides how data is fetched, checks who is asking, and returns small safe objects called data transfer objects. The Next.js data security guide recommends it for new projects because it puts authorization in one place.

The three approaches in the docs

The guide describes three ways to fetch data:

  • HTTP APIs for large existing applications, using a zero trust model and calling existing REST or GraphQL endpoints.
  • A data access layer for new projects.
  • Component level data access for prototypes and learning.

It recommends picking one and not mixing them. That makes the code predictable for developers and for security auditors.

What a DAL does

Per the guide, a DAL should only run on the server, perform authorization checks, and return safe, minimal DTOs. In the guide's example, a function looks up a profile and then decides field by field what the current viewer may see, returning a phone number only if the viewer is an admin or on the same team.

import 'server-only'

export async function getProfileDTO(slug: string) {
  const [rows] = await sql`SELECT * FROM user WHERE slug = ${slug}`
  const viewer = await getCurrentUser()
  return {
    username: rows[0].username,
    phonenumber: canSeePhone(viewer, rows[0].team) ? rows[0].phonenumber : null,
  }
}

Two details in that pattern are worth copying. The query uses a database API with safe templating, so values are parameters. And the function returns only what this caller needs, not the whole row.

Why prototypes leak

With component level access, a Server Component fetches a full row and passes it to a Client Component as props. Every field then goes to the browser. The guide gives exactly this as an example of exposure: the client component accepts far more data than it needs, which encourages the server component to pass it all down.

Environment variables belong in the DAL

The guide notes that secrets should live in environment variables, and that only the DAL should read process.env, so secrets are not exposed to the rest of the app.

What to check in a review

  1. Are database packages and environment variables imported outside the DAL?
  2. Do client components take narrow props rather than whole records?
  3. Does every function that returns data check the viewer?
  4. Do mutations go through the same layer?

Quick check

Is a DAL needed for a small app?

The docs suggest it for new projects and call component level access suitable for prototypes. If the app will hold user data, start with the DAL.

What is a DTO?

A data transfer object is a small object holding only the fields a caller is allowed to see.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.