Check roles and permissions with authorization checks
Authorization checks verify that users can only access resources and perform actions they have permission for within an organization. These checks are essential for protecting sensitive data, gating premium features, and ensuring users stay within their allowed scope of access.
Clerk provides two primary ways to perform these checks: the has() method for server-side logic and the <Protect> component for conditional rendering in React. Both methods let you check against roles, permissions, features, and plans.
What you can check
Authorization checks can verify roles and custom permissions. Roles like org:admin determine a user's level of access within an organization, while custom permissions like org:invoices:create provide fine-grained control over specific features and actions.
Frontend checks with <Protect>
The <Protect> component is the easiest way to conditionally show or hide content in React applications based on what a user can access. This works well for UI elements like buttons, sections, or entire page layouts that should only appear to users with specific access. You can show or hide content based on roles and permissions, render different layouts for different access levels, or display fallback messages when access is denied.
Use the <Protect> component to conditionally render content based on role or permission:
import { Protect } from '@clerk/nextjs'
export default function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
{/* Only show to org admins */}
<Protect role="org:admin">
<AdminSettings />
</Protect>
{/* Only show to users with specific permission */}
<Protect permission="org:invoices:create">
<CreateInvoiceButton />
</Protect>
{/* Display fallback when access is denied */}
<Protect permission="org:reports:read" fallback={<p>You don't have access to reports.</p>}>
<ReportsSection />
</Protect>
</div>
)
}Server-side checks with has()
While <Protect> works well for the frontend, server-side checks are essential for securing API routes, backend logic, and data access. The has() method provides a way to verify access before performing sensitive operations or returning protected data. You'll use this when protecting API endpoints, controlling database operations, validating permissions before executing business logic, or returning different data based on user access.
Use the has() method from the auth() object to check permissions on the server:
import { auth } from '@clerk/nextjs/server'
export default async function handler(req, res) {
const { has, userId } = await auth()
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' })
}
// Check if user has admin role
if (!has({ role: 'org:admin' })) {
return res.status(403).json({ error: 'Forbidden' })
}
// Check if user has specific permission
if (!has({ permission: 'org:invoices:create' })) {
return res.status(403).json({ error: 'Forbidden' })
}
// Proceed with authorized action
// ...
}Next steps
Now that you know how to check roles and permissions, you can:
- Read the complete authorization checks guide for advanced patterns including middleware protection and custom authorization logic
- Learn how to check features and plans for subscription-based applications
- Set up custom roles and permissions to define your access control model
- Configure default roles for new organization members
Feedback
Last updated on