kerne.auth.signup() succeeds depends on two settings, read from GET /v1/auth/config (kerne.auth.config()) and checked in this order:
- User limit. If
user_registration_limitis set and the tenant already has that many active users, every signup is rejected - regardless ofregistration_mode. registration_mode. One tenant-wide setting, one of three values:OPEN- any signup succeeds.INVITE_ONLY- the signup must include a validinvitationTokenorinvitationCode(see Invitations) - anything else is rejected.CLOSED- no self-service signup at all; every user comes from your own backend instead.
Waitlist vs. invitations
These are two separate mechanisms - joining a waitlist does not grant registration access by itself, and doesn’t put a user into any kind of pending account state:- Waitlist (
kerne.waitlist.join()) just collects interest before you’re ready to onboard everyone - an email and optional metadata, nothing more. An admin later invites specific entries, at which point they go through the same invitation flow as anyone else. - Invitations (tokens or reusable codes,
kerne.invitations.*) are what actually unlock a signup whenregistration_modeisINVITE_ONLY.
Checking the current config
enable_credentials is false) instead of hardcoding assumptions about how your tenant is configured.
For a walkthrough of building an invite-only product end to end, see Implement invite-only SaaS.
Which one to pick
Consumer / self-serve
OPEN. Friction is the enemy — every extra step loses signups.Early access / high-touch
INVITE_ONLY, or a waitlist first. Fewer, better-qualified signups, and room to onboard people by
hand while you’re still learning what they need.Next
Implement invite-only SaaS
Codes, tokens, and the signup flow end to end.
Set up authentication
Login, registration and route protection.

