Verify the active user's permissions in an organization
In general, you should always verify whether or not a user is authorized to access sensitive information, important content, or exclusive features. The most secure way to implement authorization is by checking the active user's role or permissions.
Clerk enables two broad approaches to role and permissions-based authorization:
- If you would like to immediately prevent unauthorized users from accessing content, you can:
- Use the
<Protect>
component to prevent content from rendering if the active user is unauthorized. - Call
auth.protect()
to throw a404
error if the active user is unauthorized.
- Use the
- If you would like more control over the response when a user is unauthorized, you can:
- Call the
has()
helper, which returnsfalse
if the active user lacks the role or permissions you're checking for. You can choose how your app responds instead of immediately preventing content from rendering or throwing an error.
- Call the
Authorization in Client Components
The following examples work for both SSR and CSR.
The following example uses the <Protect>
component to only render the form for users with the correct permission. The example uses the fallback
prop to render a different UI if the user is not authorized.
The following example uses has()
to inspect a user's permissions granularly. If the user doesn't have the permission, has()
returns false
, causing the component to return null
instead of rendering its children.
The following example uses the <Protect>
component to only render the layout for users with the correct permission. If the user is not authorized, the component will not render its children.
The following example uses has()
to inspect a user's permissions granularly. If the user doesn't have the correct permission, has()
returns false
, causing the component to return null
instead of rendering its children.
The following example uses auth.protect()
to protect a RSC from unauthenticated and unauthorized access.
- If the user is not authenticated,
auth.protect()
will redirect the user to the sign-in route. - If the user is authenticated but is not authorized (as in, does not have the
org:team_settings:read
permission),auth.protect()
will throw a404
error. - If the user is both authenticated and authorized,
auth.protect()
will return the user'suserId
.
The following example uses has()
to inspect a user's permissions granularly in a Next.js Server Action. If the user doesn't have the correct permission, has()
returns false
, causing the Server Action to return a 403
error.
The following example demonstrates how to use has()
in a Next.js Route Handler.
The example:
- uses the
userId
returned fromauth()
to check if the user is signed in. If the user is not authenticated, the Route Handler will return a401
error. - uses
has()
to check if the user has the correct permission. If the user is not authorized,has()
will return false, causing the Route Handler to return a403
error.
The following example uses auth.protect()
to protect a Next.js Route Handler from unauthenticated and unauthorized access.
- If the user is not authenticated nor authorized (as in, does not have the
org:team_settings:manage
permission),auth.protect()
will throw a404
error. - If the user is both authenticated and authorized,
auth.protect()
will return the user'suserId
.
Use the getAuth()
helper to access the has()
helper in a Next.js Pages Router application.
The following example:
- uses the
userId
returned fromgetAuth()
to check if the user is signed in. If the user is not authenticated, the route will return a401
error. - uses
has()
to check if the user has the correct permission. If the user is not authorized,has()
will return false, causing the route to return a403
error.
Authorization in Remix Loaders
The following example uses the has()
helper to check if the user has the correct permission. If the user is not authorized, has()
will return false, causing the loader to redirect the user to the /request-access
route.
Authorization in JavaScript
If you are not using React or any of the meta-frameworks we support, you can use the Clerk JavaScript SDK. The following example demonstrates how to use the checkAuthorization()
method to check if a user is authorized.
You can pass a role
the same way you can pass a permission
in all the examples above.
The following example uses <Protect>
's condition
prop to conditionally render its children if the user has the correct role.
The following example uses auth.protect()
to protect a RSC from unauthenticated and unauthorized access.
- If the user is not authenticated,
auth.protect()
will redirect the user to the sign-in route. - If the user is authenticated but is not authorized (as in, does not have the
org:admin
ororg:billing_manager
role),auth.protect()
will throw a404
error. - If the user is both authenticated and authorized,
auth.protect()
will return the user'suserId
.
The following example uses has()
to inspect a user's roles granularly. If the user doesn't have the correct role, has()
returns false
, causing the component to return null
instead of rendering its children.
How to add types for roles and permissions
In order to enhance typesafety in your project, you can define a global ClerkAuthorization
interface, which defines the acceptable values for roles and permissions.
In the example below, ClerkAuthorization
is defined with the default roles that Clerk provides.
Because Clerk supports custom roles and permissions, you can modify ClerkAuthorization
to align with the roles and permissions configured in your Clerk application. See how in the example below, the default Clerk roles org:admin
and org:member
are replaced with custom roles org:super_admin
, org:teacher
, and org:student
.
Feedback
Last updated on