Skip to content
Deployment
Skill

/netlify-identity

Add authentication and user management to a Netlify site with @netlify/identity — signup/login/logout, OAuth social login (Google/GitHub/GitLab/Bitbucket), server-side user verification in Functions, role-based access control (RBAC), admin user management, and Identity event

From plugin
netlify-skills
3715 skills1 MCP
Install
$ npx -y skills add netlify/context-and-tools --skill netlify-identity --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/netlify-identity

Context preview

The summary Claude sees to decide when to auto-load this skill.

Add authentication and user management to a Netlify site with @netlify/identity — signup/login/logout, OAuth social login (Google/GitHub/GitLab/Bitbucket), server-side user verification in Functions, role-based access control (RBAC), admin user management, and Identity event

SKILL.md

netlify-identity.SKILL.md
name: netlify-identity
description: Add authentication and user management to a Netlify site with @netlify/identity — signup/login/logout, OAuth social login (Google/GitHub/GitLab/Bitbucket), server-side user verification in Functions, role-based access control (RBAC), admin user management, and Identity event hooks. Use when adding a login/signup flow, "add social login", gating content by user role, protecting a function or page behind auth, assigning roles at signup, customizing auth emails, or handling OAuth/confirmation/recovery callbacks. Not for locking an entire site to a company/team — that is netlify-access-control.

Netlify Identity

Auth and user management for a Netlify site without requiring visitors to be Netlify users. Package: `@netlify/identity`.

**Reach for `@netlify/identity`.** Do NOT use the legacy `netlify-identity-widget` or `gotrue-js` for new work — same capabilities, simpler API, built-in server-side support.

Footguns — read first

  • **Identity does not work under `netlify dev`.** Test auth flows on a deploy — Deploy Previews work. Local `netlify dev` cannot exercise `/.netlify/identity/*`.
  • **Never build a from-scratch third-party OAuth flow beside Identity** — no provider app registration in code, no `client_id`/`secret` in code, no custom callback token exchange. Use `oauthLogin()` + `handleAuthCallback()`. Raw OAuth beside Identity is the single most common source of rework.
  • **Identity config has no public API — dashboard only.** Never curl `api.netlify.com` to flip/inspect Identity settings, never read tokens from `~/Library/Preferences/netlify/config.json`, never probe undocumented endpoints.
  • **RBAC redirects without a fallback = raw 404.** A visitor lacking the role gets a bare 404 with no way to log in. Always add a fallback rule.
  • **Server-side `login()`/`signup()`/`logout()` need CSRF protection.** Call `verifyRequestOrigin(req)` first, or an attacker can log a victim into the attacker's account.
  • **Site-gating** ("lock this site to my company", employees-only) → route to **netlify-access-control** first. Identity is the app-level user layer only.
  • **On failure** (callback 404s, `/.netlify/identity/*` unreachable, OAuth doesn't return): surface the error, the dashboard URL, and the setting to check — then stop. Do not invent recovery commands.

Setup

Identity must be enabled in the dashboard first (no API): **Project configuration > Identity** (`https://app.netlify.com/projects/{site_name}/configuration/identity`) → **Enable Identity**.

npm install @netlify/identity

HTTPS is required. On a custom domain, get HTTPS/SSL working before integrating Identity.

Client / universal auth

import { signup, login, logout, getUser, oauthLogin, handleAuthCallback } from '@netlify/identity'

// Sign up — sends a confirmation email by default (skippable via autoconfirm setting)
const user = await signup('jane@example.com', 'securepassword', { full_name: 'Jane Doe' })

// Log in / log out
await login('jane@example.com', 'securepassword')
await logout()

// Current user — null if not logged in (works in browser + server)
const u = await getUser()
if (u) console.log(u.email)

// OAuth — redirects browser to provider login
oauthLogin('github') // 'google' | 'github' | 'gitlab' | 'bitbucket'

**Callback handling is mandatory.** Call `handleAuthCallback()` on your landing page. It processes ALL token types in the URL hash — OAuth redirect, email confirmation, password recovery, invite. Without it, confirmation links and OAuth redirects never complete.

import { handleAuthCallback } from '@netlify/identity'

const result = await handleAuthCallback()
if (result) console.log(result.type, result.user.email) // may be falsy if nothing to process

Other client functions:

  • `recoverPassword()` — complete a password reset (alternative to letting `handleAuthCallback()` handle the `recovery_token`).
  • `acceptInvite()` — complete invite acceptance (alternative to `handleAuthCallback()` handling `invite_token`).
  • `refreshSession()` — refresh token/session so newly-assigned roles take effect.

**Don't hard-code which providers exist.** Call `getSettings()` at startup and render the signup form and OAuth buttons from what it returns.

Server-side (Functions / Edge Functions)

Handlers are modern v2 functions: `export default async (req, context) => {}`. **v1 `export { handler }` is not supported** for `getUser()`/`login()`/`admin.*`.

import { getUser } from '@netlify/identity'
import type { Context } from '@netlify/functions'      // or '@netlify/edge-functions' for Edge

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 })
  return Response.json({ id: user.id, email: user.email })
}

`getUser()` works in browser, Netlify Functions, and Edge Functions.

**CSRF — always guard exposed `login`/`signup`/`logout` endpoints:**

import { login, verifyRequestOrigin } from '@netlify/identity'
import type { Context } from '@netlify/functions'

export default async (req: Request, context: Context) => {
  verifyRequestOrigin(req)   // throws 403 on Origin mismatch; supports { allowedOrigins }
  const { email, password } = await req.json()
  await login(email, password)
  return new Response(null, { status: 302, headers: { Location: '/dashboard' } })
}

admin — Netlify Functions ONLY

`admin.*` uses a short-lived admin token and runs **only in Netlify Functions** — NOT browser, NOT 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()   // array of users
  return Response.json({ total: users.length })
}
  • `admin.listUsers()
Read more
Ships withnetlify-skills

Public Netlify skills for AI coding agents. Each skill is a focused, factual reference for a Netlify platform primitive — designed to help agents build correctly on Netlify without needing to search docs.

Get the whole plugin

Other skills on netlify-skills.