Skip to content

Start your next project with a prompt. → netlify.new 🚀

Use Identity in functions

You can use @netlify/identity in Netlify Functions and Edge Functions to verify users, check roles, and manage users programmatically.

Use getUser() to check whether the request comes from an authenticated user. It returns the User object, or null if the user is not logged in.

import { getUser } from '@netlify/identity'
import type { Context } from '@netlify/functions'
export default async (req: Request, context: Context) => {
const user = await getUser()
if (!user) return new Response('Unauthorized', { status: 401 })
return Response.json({ id: user.id, email: user.email })
}

The User object includes a roles array from the user’s app_metadata. You can use this to restrict access to specific functions based on a user’s role.

netlify/functions/admin-users.ts
import { getUser, admin } from '@netlify/identity'
import type { Context } from '@netlify/functions'
export default async (req: Request, context: Context) => {
const user = await getUser()
if (!user) return new Response('Unauthorized', { status: 401 })
if (!user.roles.includes('admin')) {
return new Response('Forbidden', { status: 403 })
}
// Only admins reach this point
const users = await admin.listUsers()
return Response.json({ users })
}

Roles are set on the user’s app_metadata.roles field and included in the JWT. Changes to a user’s roles take effect on their next login or token refresh, not immediately.

The admin export from @netlify/identity provides server-side user management: list, create, update, and delete users. These operations use a short-lived admin token and can only run in Netlify Functions (not in the browser or Edge Functions).

import { admin } from '@netlify/identity'
import type { Context } from '@netlify/functions'
export default async (req: Request, context: Context) => {
const users = await admin.listUsers()
return Response.json({ total: users.length })
}

For the full admin API, refer to the @netlify/identity admin operations documentation.

Identity event functions are different from the patterns above. Instead of calling @netlify/identity from your function, the Netlify platform calls your function automatically when an Identity event occurs. The function receives a JSON payload with the event type and user object.

To set this up, create a function file whose name matches the event name.

Five events are available:

  • identity-validate — Triggers when a user attempts to sign up, before the account is created. Use this to block signups based on email domain, rate limiting, or custom validation.
  • identity-signup — Triggers when a user completes signup (email or external providers). Triggers after email confirmation, if confirmation is enabled. Use this to assign roles, sync to external systems, or send welcome notifications.
  • identity-login — Triggers when a user logs in. Use this to track logins, update last-seen timestamps, or sync profile data.

Each event function receives a request with a JSON body containing the event type and user object:

{
"event": "signup",
"user": {
"id": "abc-123",
"email": "jane@example.com",
"app_metadata": {
"provider": "email",
"roles": []
},
"user_metadata": {
"full_name": "Jane Doe"
}
}
}

The event field will be one of: validate, signup, login, userdeleted, or usermodified.

If your function returns a status other than 200, 202, or 204, the signup or login is blocked. Use identity-validate to reject signups before the account is created.

netlify/functions/identity-validate.ts
import type { Context } from '@netlify/functions'
export default async (req: Request, context: Context) => {
const { user } = await req.json()
const domain = user.email.split('@')[1]
if (domain !== 'example.com') {
return new Response('Only example.com emails allowed', { status: 403 })
}
return new Response('OK', { status: 200 })
}

Return a 200 response with a JSON body to modify the user’s metadata. This is the most common way to assign roles programmatically.

netlify/functions/identity-signup.ts
import type { Context } from '@netlify/functions'
export default async (req: Request, context: Context) => {
const { user } = await req.json()
return Response.json({
app_metadata: {
...user.app_metadata,
roles: ['member'],
},
})
}

This sets the member role on every new user. The roles are included in the user’s JWT and can be used for role-based access control with redirect rules.

To trigger a background function on an Identity event, include the event name in the function file name with a -background suffix. For example, identity-login-background.ts runs asynchronously after each login without blocking the login response.