Set global access policies for your business
Build on Kinde
Kinde can block known disposable email providers out of the box on the Plus plan and above. See how to enable this setting from the Kinde dashboard. Use the policy if you want a list that Kinde maintains with no code. Use this workflow if you need your own list of domains or custom logic, or if you are on the Free or Pro plan.
The workflow runs on the user:pre_registration trigger and checks the sign-up email against your own list.
DISPOSABLE_EMAIL_DOMAINS.yopmail.com,guerrillamail.com,mailinator.com.Read the email from the pre-registration event:
event.context.user.emailRead your domain list from your environment variable (e.g., DISPOSABLE_EMAIL_DOMAINS):
const disposableEmailDomains = getEnvironmentVariable( "DISPOSABLE_EMAIL_DOMAINS")?.valueDisplay a message on the Kinde form when registration is blocked using the denyAccess built-in function:
denyAccess("Disposable email domain detected")Workflow.ts file exampleEach trigger can have only one workflow. If you already have a user:pre_registration workflow, add the disposable-domain check and the kinde.env and kinde.auth bindings to that workflow so its other registration rules stay in place.
import { onUserPreRegistrationEvent, WorkflowSettings, WorkflowTrigger, denyAccess, getEnvironmentVariable,} from "@kinde/infrastructure";
// The settings for this workflowexport const workflowSettings: WorkflowSettings = { id: "preRegistration", name: "Block disposable emails", failurePolicy: { action: "stop", }, trigger: "user:pre_registration", bindings: { "kinde.env": {}, "kinde.auth": {}, },};
// The workflow code to be executed when the event is triggeredexport default async function Workflow( event: onUserPreRegistrationEvent) { console.log("handlePreRegistration");
// Check if user email exists in the event if (!event.context.user?.email) { console.log( "No user email found in pre-registration event, allowing registration" ); return; }
const disposableEmailDomains = getEnvironmentVariable( "DISPOSABLE_EMAIL_DOMAINS" )?.value;
// If no disposable email domains are configured, allow registration if (!disposableEmailDomains) { console.log( "No disposable email domains configured, allowing registration" ); return; }
const disposableEmailDomainsArray = disposableEmailDomains .split(",") .map((domain) => domain.trim().toLowerCase());
const userEmailDomain = event.context.user.email.split("@")[1]?.toLowerCase();
if (userEmailDomain && disposableEmailDomainsArray.includes(userEmailDomain)) { console.log( `Blocking registration for disposable email domain: ${userEmailDomain}` ); denyAccess("Disposable email domain detected"); } else { console.log(`Allowing registration for email domain: ${userEmailDomain}`); }}The workflow checks the sign-up email against the domains in DISPOSABLE_EMAIL_DOMAINS:
denyAccess stops registration and the user sees Disposable email domain detected.kinde.env: required to read the environment variablekinde.auth: required for denyAccess on the pre-registration triggerDISPOSABLE_EMAIL_DOMAINS. Registration will be blocked and the user sees Disposable email domain detected.