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 everyoneprotectedProcedure: This procedure is only accessible by authenticated usersadminProcedure: This procedure is only accessible by authenticated users with the roleadmin
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:
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:
import { verifyOrganizationMembership } from "../lib/membership";
const membership = await verifyOrganizationMembership(organizationId, user.id);
if (!membership) {
throw new ORPCError("FORBIDDEN");
}