---
title: 'Supabase Auth: Identity Linking, Hooks, and HaveIBeenPwned integration'
description: >-
  Four major Auth features: Identity Linking, Session Control, Leaked Password
  Protection, and Hooks
author: 'stojan,joel,kangmingtay'
date: '2023-12-14'
tags:
  - launch-week
  - auth
categories:
  - product
---
We're excited to announce four new features for Supabase Auth:1) Identity Linking
1) Session Control
1) Leaked Password Protection
1) Auth Hooks with Postgres functions## Identity LinkingWhen a user signs in, an identity is created with the authentication method and sign-in provider. Historically, [Supabase Auth](/docs/guides/auth) has been automatically linking identities to a user if the identity shares the same verified email as the user. This is convenient to de-duplicate user accounts. However, some developers also need the flexibility to link accounts that don’t share the same email.Today we are launching Identity Linking, which developers can use to manually link two separate identities. We’ve added two new endpoints for developers to manage the identity linking process:Once a user is signed in, use `linkIdentity()` to [link an OAuth identity](/docs/reference/javascript/auth-linkidentity):```jsx
const { data, error } = await supabase.auth.linkIdentity({
  provider: 'google',
})
```Use `unlinkIdentity()` to [unlink an identity](/docs/reference/javascript/auth-unlinkidentity):```jsx
// retrieve all identities linked to a user
const {
  data: { identities },
} = await supabase.auth.getUserIdentities()

// find the google identity linked to the user
const googleIdentity = identities.find(({ provider }) => provider === 'google')

// unlink the google identity from the user
const { data, error } = await supabase.auth.unlinkIdentity(googleIdentity)
```Currently, these methods support linking an OAuth identity. To link an email or phone identity to the user, you can use the [`updateUser()`](/docs/reference/javascript/auth-updateuser)method.Manual linking is disabled by default. You can enable it for your project in [the dashboard Auth settings](/dashboard/project/_/auth/providers).> **NOTE**
>
> See the [Identity Linking docs](/docs/guides/auth/auth-identity-linking) for more information.## Session ControlSupabase Auth manages the full session lifecycle from the moment your user signs into your application. This involves the following steps:1) Creating the session for the user.
1) Refreshing the session to keep it active.
1) Revoking the session upon expiry or logout.For developers who want finer control over their users’ sessions, we have exposed 3 new settings:* **Time-box user sessions**: Force users to sign in again after a time interval.
* **Inactivity Timeout**: Force users to sign in again if they’re inactive for a time interval.
* **Single session per user**: Restrict users to a single session. The most recently active session is kept, and all others are terminated.These session control settings are available on the Pro Plan and above.> **NOTE**
>
> See the [Session Management docs](/docs/guides/auth/sessions) for more information.## Leaked Password ProtectionPasswords can be inherently insecure due to common user behaviors like choosing guessable passwords or reusing them across different platforms.Even though OAuth and magiclinks are more secure, we recognize passwords are here to stay. We want to make the potential pitfalls less user-prone. To accomplish that, we have integrated the [HaveIBeenPwned.org](https://haveibeenpwned.com/) *Pwned Passwords API* in Supabase Auth to prevent users from using leaked passwords.> **NOTE**
>
> ℹ️ We have open-sourced a Go library for interacting with the [HaveIBeenPwned.org](http://HaveIBeenPwned.org) Pwned Passwords API that we use in our Auth server. Check out the [repository](https://github.com/supabase/hibp) and feel free to contribute!As an additional step, we have added the ability to specify password requirements for your users. This can be configured from your project’s Auth settings in [the dashboard](/dashboard/project/_/auth/providers):> **NOTE**
>
> See the [password docs](/docs/guides/auth/passwords) for more information.## Auth HooksWe’ve received a ton of feedback asking for ways to customize Auth, like:* Add custom claims to the access token JWT
* Log the user out after multiple failed MFA verification attempts
* Apply custom rules for password validation attemptsWe aim to maintain a straightforward and seamless Supabase Auth experience. It should work effortlessly for most developers, requiring no customization. However, recognizing the diversity of apps, you can now extend standard Auth features through Auth Hooks.Auth Hooks are simply Postgres functions that run synchronously at key points in the Auth lifecycle, to change the outcome of the action.For example, to customize the JWT claims with Auth Hooks, you can create a Postgres function that accepts the JWT claims in the first argument and returns the JWT you wish to be used by Supabase Auth.Suppose you’re creating a gamified application and you wish to attach the user’s level to the JWT as a custom claim:```sql
create function custom_access_token_hook(event jsonb)
returns jsonb
language plpgsql
as $$
declare
  user_level jsonb;
begin
  -- fetch the current user's level
  select
    to_jsonb(level) into user_level
  from profiles
  where
    user_id = event->>'user_id'::uuid;

  -- change the event.claims.level
  return jsonb_set(
		event,
		'{claims,level}',
		user_level);

end;
$$
```Once you’ve created the function in the database, you only need to register it with Supabase Auth:Currently, you can register an Auth Hook for the following points in the flow:* **Custom access token:** called each time a new JWT is generated.
* **MFA verification attempt**: called each time an MFA factor is verified, allowing finer control over detecting and blocking attempts.
* **Password verification attempt**: called each time a password is used to sign-in a user, allowing finer control over the security of the user’s accounts.And if writing PL/pgSQL functions is not your forte, you can always use [pg\_net](https://supabase.com/docs/guides/database/extensions/pg_net) to send out requests to your backend APIs instead, or use [plv8](https://supabase.com/docs/guides/database/extensions/plv8) to manipulate JSON more easily by writing your function in JavaScript.Auth Hooks is available today for self-hosting and will be rolled out to the platform next month. Reach out to us via [support](https://supabase.help) if you need access sooner!That’s not all! Postgres functions aren’t the only way to write hooks.Supabase is a founding contributor of [Standard Webhooks](https://www.standardwebhooks.com/), a set of open source tools and guidelines about sending and receiving webhooks easily, securely, and reliably. Naturally, Auth Hooks will be supporting webhooks in Q1 of 2024.## One more thing…If you’ve been following us from [the start](https://supabase.com/blog/supabase-auth), you will know that Supabase Auth started by forking [Netlify’s GoTrue server](https://github.com/netlify/gotrue). A lot has changed since then and we’ve diverged from the upstream repository. At this stage it makes sense to rename the project to something else (*cues drumroll*) — Auth.This simply means that the repositories will be renamed from using `gotrue` to `auth`. But don’t worry! Docker images and libraries like `@supabase/gotrue-js` will continue to be published and you can use `@supabase/auth-js` interchangeably for the current v2 version for as long as it is supported. All of the classes and methods remain in place. No breaking changes here!## ConclusionThanks for reading till the end! We hope you enjoyed the Supabase Auth updates for Launch Week X: Identity Linking, Session Control, Leaked Password Protection, and Auth Hooks with Postgres functions.We are looking forward to seeing what you build with these new features, and, of course, your feedback to make them even better.
