Login & identity Available
Sms-gateway
The second step needs no vendor. If you also want to send codes by SMS, you point the API at a gateway that accepts a simple JSON message.
What you need
- Access to the API container's environment variables: this is installation configuration, not a per-organisation setting.
- A gateway that accepts a JSON POST, such as Twilio, MessageBird, Spryng or something you built yourself.
- A confirmed authenticator app per person; SMS sits on top of that.
- Phone numbers in international format, for example +31612345678.
How to connect it
- 1 Set
SCHAKL_SMS_GATEWAY_URLto your gateway's send address, for examplehttps://your-gateway.example/send, and restart the API container. - 2 If your gateway needs a token, set
SCHAKL_SMS_GATEWAY_TOKEN; the API sends it asAuthorization: Bearer.SCHAKL_SMS_GATEWAY_SENDERpicks a sender id; leave it empty and the gateway applies its own default. - 3 Check that your gateway takes the shape the API sends: a POST with
{"to": "+31612345678", "message": "...", "sender": "..."}. If it does not, put a small relay in front of it. - 4 Each team member sets up the authenticator themselves first: Instellingen → Mijn account (Settings → My account), the Tweestapsverificatie block, button Tweestapsverificatie instellen, then the code and Verifiëren en inschakelen. Keep the ten backup codes; they are shown once.
- 5 The Sms-codes block now appears on that same screen. Enter a number under Telefoonnummer, press Verificatiecode versturen, type the code you receive and press Nummer verifiëren.
- 6 From then on the login flow offers an extra button: Sms een code naar mijn telefoon. You can drop the number later with Nummer verwijderen; the authenticator stays.
What already works with no gateway
The basics are there the moment you run the app: an authenticator app as the standing factor, with ten single-use backup codes beside it. No permission is involved, because it is your own account. The issuer your colleague sees in their app is your agency's own brand name, taken from Instellingen → Huisstijl (Settings → Branding), so a white-label install never shows a product name the client has never heard of. Regenerating backup codes costs a current code from the app, so a stolen session on its own cannot mint recovery codes.
- After eight failed attempts the factor locks for fifteen minutes.
- A sign-in left waiting on the code step expires after five minutes and returns you to the password step.
- An already-accepted code never works a second time, not even inside the same 30-second window.
- Turning it off takes your account password; abandoning a half-finished setup costs nothing.
The SMS leg belongs to the installation, not the organisation
SCHAKL_SMS_GATEWAY_URL is instance configuration, so an agency running on somebody else's server cannot switch SMS on for itself. With the variable unset there is no Sms-codes block, no extra button on the login page, and the API answers 'Sms-codes zijn niet beschikbaar op deze installatie' (SMS codes are not available on this installation). The message text comes from the translation catalogue, in the recipient's own language.
- An SMS code is six digits, valid for ten minutes, five attempts, single use.
- A resend is refused for the first thirty seconds.
- SMS is never a standalone factor: removing the number never leaves an account without a second step.
- With no sender id the API leaves the field empty so the gateway applies its own default; a fixed product name there would cut across your client's branding.
Lost phone
An admin handles that from the team roster: Instellingen → Team & gebruikers (Settings → Team & users), the ⋯ menu on that colleague's row, 'Tweestapsverificatie resetten' (reset two-factor). The account goes back to signing in with a password alone until it is set up again. The menu item only appears for people who actually have two-factor on, and never on your own row.
- The reset clears the enrolment outright: secret, backup codes and phone number. No secret is ever read out.
- Every reset is written to the organisation's audit log.
- The second factor belongs to the person, not the organisation, so a reset applies everywhere that account is a member. On an ordinary single-organisation install those are the same thing.
With SSO enforced, your provider owns the MFA
If your organisation enforces single sign-on, that switches off the whole two-factor surface here, enrolment included. That is deliberate: on a federated session the second step belongs to your identity provider, and two places both asking for a code only creates confusion. So this screen is for agencies that sign in with a password.
Permissions
Grant these to the role that manages this integration (Settings → Roles). Admin-only by default, and never to the client role.
-
members.member.writeInvite, change and remove users, and use 'Tweestapsverificatie resetten' in Instellingen → Team & gebruikers. Admin only by default. Setting up your own two-factor, regenerating backup codes, adding a number or switching it all off needs no permission at all.
What it deliberately does not do
- There is no organisation-wide requirement: every team member enables two-factor themselves, and nobody can mandate it.
- No 'trust this device': every password login asks for a code again.
- No two-factor on top of SSO; enforce single sign-on and the whole surface disappears for that organisation.
- SMS never stands alone: with no confirmed authenticator app, no SMS option appears.
- The gateway is installation configuration, not something an organisation can switch on in the app.
- API keys and MCP bypass two-factor entirely; they authenticate with their own key and scopes.
Where to find it Instellingen → Mijn account (Settings → My account), the Tweestapsverificatie block; the gateway itself lives in the API container's environment.
Read the guide