Tutorial - Customize tokens using workflows
Workflows
Kinde enforces essential password safety rules out of the box, such as a minimum length and checks against the most common passwords. But what if your application requires more specific password policies, like enforcing uppercase letters, numbers, or special characters?
In this guide, you’ll implement a custom password validation workflow in Kinde using its flexible workflow engine. This feature lets you define exactly how strict (or lenient) your password rules should be, and display custom error messages right on the Kinde sign-up or login widget.
Fork the workflow base template repo into your GitHub account by selecting Use this template > Create a new repository
Clone the repo into your computer with the following Git command:
git clone https://github.com/your_github_username/workflow-base-template.gitChange into the directory:
cd workflow-base-templateCreate a new workflow directory with the following command.
You can name it anything that resonates with your project structure; we are calling it newPasswordValidation
mkdir kindeSrc/environment/workflows/newPasswordValidationCreate a new Workflow.ts file:
touch kindeSrc/environment/workflows/newPasswordValidation/Workflow.tsOpen the new file with your favorite code editor (e.g., VS Code) and add the following workflow code into the file and save changes:
import { onNewPasswordProvidedEvent, WorkflowSettings, WorkflowTrigger, invalidateFormField,} from "@kinde/infrastructure"
// The setting for this workflowexport const workflowSettings: WorkflowSettings = { id: "onNewPasswordProvided", name: "New Password Entered", trigger: WorkflowTrigger.NewPasswordProvided, failurePolicy: { action: "stop", }, bindings: { "kinde.widget": {}, // Required for accessing the UI },}
function customPasswordValidator(password: string) { const hasUppercase = /[A-Z]/.test(password) const hasLowercase = /[a-z]/.test(password) const hasNumber = /[0-9]/.test(password) const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password)
if (!hasUppercase) { return "Password must include at least one uppercase letter." } if (!hasLowercase) { return "Password must include at least one lowercase letter." } if (!hasNumber) { return "Password must include at least one number." } if (!hasSpecialChar) { return "Password must include at least one special character." } return null // valid password}
// The workflow code to be executed when the event is triggeredexport default async function Workflow(event: onNewPasswordProvidedEvent) { const { firstPassword } = event.context.auth const invalidMessage = customPasswordValidator(firstPassword)
if (invalidMessage) { // Custom form validation invalidateFormField("p_first_password", invalidMessage) }}Optional: Install the Kinde infrastructure dependency with the following bash command for TypeScript intellisense.
npm installRun the following git commands in your terminal to push the changes to your GitHub repo:
git add .git commit -m "add new password validation workflow"git pushHere’s a quick breakdown of what the code does.
Imports
The top of the file brings in useful methods and types from the @kinde/infrastructure package, including onNewPasswordProvidedEvent, WorkflowSettings, and invalidateFormField.
Workflow settings
The workflowSettings object defines when and how the workflow runs.
NewPasswordProvided event, meaning it runs whenever a user enters a new password.name field (“New Password Entered”) helps you easily identify this workflow in the Kinde dashboard.bindings section ("kinde.widget") gives the workflow access to the Kinde sign-in form UI.Password validation logic
The customPasswordValidator function checks that the password meets all of your custom rules:
You can easily update this logic to match your app’s specific requirements.
Main workflow function
The default Workflow function runs each time the NewPasswordProvided event is triggered.
It grabs the user’s input, validates the password using your custom logic, and if it fails, calls invalidateFormField() to show an error message right in the Kinde UI.
Sign in to your Kinde dashboard and select Workflows from the sidebar.
If you already have your workflow repo connected, go straight to step 4.
Select Connect repo > Connect GitHub and follow the onboarding flow to authorize Kinde to access your GitHub account.
From the dropdown, select your GitHub repository that contains the Kinde workflow code, choose the main branch, and click Next.
If you already have a repo connected and want to change it, go to Kinde > Settings > Git repo > Change repo.
Select Sync code to pull your latest workflow code from GitHub into your Kinde project. You’ll now see your workflow listed inside the dashboard.
Sign in to your Kinde dashboard and select View details for the one you are testing.
Go to Authentication and uncheck Email + code and check Email + password auth method, and select Save.
By default, Kinde uses passwordless connection, so to test this workflow, we are enabling it.
Start your project and go through the sign-up flow. When you enter a weak or invalid password, your custom error messages will appear directly in the Kinde sign-up widget, giving users instant feedback based on your validation rules.
You’ve just built and deployed a custom password validation workflow in Kinde!
With this setup, you now have full control over the strength and structure of user passwords in your application. Whether you’re enforcing security best practices or meeting specific compliance needs, Kinde workflows make it easy to extend the platform with custom logic, without compromising on developer experience.
Check out additional workflow examples in the official Kinde workflow base template repository.