auth

Require work emails in Firebase Authentication

Use a Firebase Auth blocking function (beforeUserCreated) to reject personal and disposable emails with isBusinessEmail and set custom claims.

isBusinessEmail for Firebase Auth

Firebase Authentication supports blocking functions: Cloud Functions that run before a user is created and can reject the sign-up. That’s the right place for a work-email check, because it covers email/password, email link and federated sign-ins alike.

Blocking functions require Firebase Authentication with Identity Platform. Check the Firebase docs for current requirements.

1. Store the key

firebase functions:secrets:set IBE_API_KEY

2. The blocking function

// functions/index.js
import { beforeUserCreated, HttpsError } from 'firebase-functions/v2/identity';
import { defineSecret } from 'firebase-functions/params';

const IBE_API_KEY = defineSecret('IBE_API_KEY');

export const requireWorkEmail = beforeUserCreated({ secrets: [IBE_API_KEY] }, async (event) => {
  const email = event.data?.email;
  if (!email) return;

  let verdict;
  try {
    const res = await fetch('https://api.isbusinessemail.com/v1/check', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${IBE_API_KEY.value()}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ email }),
      signal: AbortSignal.timeout(2500),
    });
    if (!res.ok) return;            // fail open
    verdict = await res.json();
  } catch {
    return;                         // fail open
  }

  if (verdict.recommendation === 'block') {
    throw new HttpsError('permission-denied', 'Please sign up with your work email.');
  }

  return {
    customClaims: {
      email_category: verdict.category,
      ms365: verdict.workspace?.microsoft_365?.detected === true,
    },
  };
});

Deploy with firebase deploy --only functions, then register the function as a blocking function for “before account creation” in the Authentication settings if your setup requires it.

How it behaves

  • block: the sign-up fails with your message; the client SDK receives an error you can show next to the email field.
  • allow / review: the user is created with custom claims your app and security rules can read.
  • Our API slow or down: the function returns without changes and the sign-up proceeds.

Tips

  • Blocking functions have a short time budget, so keep the timeout at 2–3 s.
  • Keep custom claims small; store detailed verdicts (reasons, tenant ID) in Firestore if you need them.
  • “Sign in with Google” can be a personal Gmail account. The function sees that address and classifies it like any other.

Official docs: Firebase Authentication (see “blocking functions”). See also: Response fields.