Documentation
supastarter for Nuxtsupastarter for NuxtAuthentication

Permissions and access control

Basic access control

Of course you want to protect certain API endpoints to be only accessible by authenticated users, specific roles or even specific criteria of each user.

With supastarter you can control the access of each endpoint individually using oRPC procedures. From the context of the handler you have access to the following data:

  • user: The information of the authenticated user (always defined if you use a protected procedure)
  • session: The session of the user (always defined if you use a protected procedure)

There are three kinds of procedures you can use:

  • publicProcedure: This procedure is accessible by everyone
  • protectedProcedure: This procedure is only accessible by authenticated users
  • adminProcedure: This procedure is only accessible by authenticated users with the role admin

To protect a procedure so that only authenticated users can request it you can use the protectedProcedure like so:

import { protectedProcedure } from "../../../orpc/procedures";

export const myProtectedEndpoint = protectedProcedure
  .route({
    method: "GET",
    path: "/my-endpoint",
  })
  .handler(async ({ context: { user } }) => {
    return `Hello ${user.name}`;
  });

If someone tries to call this endpoint without being authenticated, they will receive a 401 Unauthorized error.

In case you want to have an endpoint that is available for everyone but only returns certain data for authenticated users, use the publicProcedure and check the session manually:

import { publicProcedure } from "../../../orpc/procedures";
import { auth } from "@repo/auth";

export const myPublicEndpoint = publicProcedure
  .route({
    method: "GET",
    path: "/my-public-endpoint",
  })
  .handler(async ({ context }) => {
    const session = await auth.api.getSession({
      headers: context.headers,
    });

    if (session?.user) {
      return `Hello ${session.user.name}`;
    }

    return `Hello anonymous`;
  });

Organization-level access control

To check if a user is an admin of an organization, you can use the isOrganizationAdmin helper from packages/auth/lib/helper.ts:

Check if user is organization admin
import { isOrganizationAdmin } from "@repo/auth/lib/helper";

// In your procedure handler:
if (!isOrganizationAdmin(organization, user)) {
  throw new ORPCError("FORBIDDEN");
}

To verify organization membership, use the verifyOrganizationMembership function from packages/api/modules/organizations/lib/membership.ts:

Check if user is organization member
import { verifyOrganizationMembership } from "../lib/membership";

const membership = await verifyOrganizationMembership(organizationId, user.id);

if (!membership) {
  throw new ORPCError("FORBIDDEN");
}