#SMS One-Time Code (SMS OTP)
SMS one-time code is an optional second factor for portal sign-in. The role policy permits it for client_admin and partner_admin accounts only, and it is only available when your organisation has been opted in by an AiDial operator. The feature is deny-by-default unless the current tenant's SMS OTP override is enabled. That override is the mfa.sms_otp.enabled flag, read from the mfa_features.sms_otp.enabled field on the session-context response and propagated through the portal session; it defaults to OFF. The operator opt-in list on the aidial_api side ships empty, so no tenant has SMS one-time code enabled until an operator adds one.
In the current portal UI, the self-service SMS enrolment card is rendered only on the Settings → Profile & Security panel (/settings?section=profile), and no role reaches it through supported navigation. client_admin requests to /settings?section=profile are redirected to the Account shell, which has no SMS card, and the customer Settings navigation lists business sections only (Opening hours, Notifications, Reports). partner_admin accounts are policy-allowed at the enrolment route but see a read-only, provider-managed security block on that panel instead of the SMS card (see Who can use it). The POST /api/auth/mfa-sms-enrol route below is live and enforces its own gates, so treat the role/tenant policy as the boundary, not the missing card.
#What it is
When SMS OTP is enrolled, the identity provider sends a one-time code by text message during sign-in. You enter the code on the identity provider's sign-in screen to complete the second factor. AiDial Portal does not collect or validate SMS code values itself.
#How enrolment works
When the portal renders the SMS factor card on the Settings → Profile & Security panel, it appears only if SMS one-time code is available for your role and organisation (the card is hidden entirely unless your resolved allowed_factors includes sms_otp, which folds the role and tenant-override checks together). Before enrolment the card shows the privacy notice and a number field that expects an Australian +61 mobile number.
The browser submits the phone number to the portal BFF route POST /api/auth/mfa-sms-enrol. The route enforces CSRF and session authentication, checks the role policy (client_admin / partner_admin only) and the tenant override, validates the number, applies rate limits, and then calls the identity provider's SMS factor endpoint server-side. The browser does not send an X-API-Key.
On success, the response contains only a masked phone_tail such as +61 ... 678.
#Who can use it
| Role | Eligibility |
|---|---|
client_admin | Policy-allowed at the enrolment route (when the organisation override is enabled); the self-service card lives on Settings → Profile & Security, which client_admin is currently redirected away from, so there is no self-service enrolment path in the UI today |
partner_admin | Policy-allowed at the enrolment route (when the organisation override is enabled), but the current portal shows a read-only, provider-managed security block instead of the SMS enrolment card |
client_manager, client_staff, partner_user | Not available — use authenticator app (TOTP) |
aidial_admin, aidial_operator | Not available (hard-denied) — use authenticator app (TOTP) |
#Privacy Notice (APP-5)
By enrolling SMS one-time code, you consent to AiDial Pty Ltd disclosing your mobile number to Twilio Inc. (United States) — our authentication SMS sub-processor — for the sole purpose of delivering security codes. Twilio handles this data outside Australia. You may withdraw consent by removing SMS one-time code from your account in Settings (the portal launches the identity-provider management flow to complete removal when available).
This mirrors the in-app privacy notice shown above the number field on the enrolment card, which the portal displays before it collects a phone number.
#What we store
| Surface | What we hold |
|---|---|
| Portal session/JWT | MFA factor identifiers and state only; no full phone number and no persisted phone tail |
| SMS enrolment response | Masked phone tail (+## ... 999) only |
| Portal database | No SMS OTP phone-number table or SMS factor copy; audit events only |
| Portal audit log | Factor, outcome, request metadata, and masked phone tail when available |
| Browser local storage | Nothing; the masked tail is held only in the current page state after enrolment |
| Identity provider store | Full phone number as the SMS authentication factor |
| Twilio | Phone number + delivery status only |
The portal briefly receives the phone number once at enrolment time so it can validate the country prefix, derive SHA-256 hashes for rate-limit buckets, and forward the number to the identity provider. The plaintext is discarded after that call. The identity provider holds the canonical SMS factor record; the portal's later enrolled-factor lookup reads only factor presence, not the full phone number or phone tail.
SMS enrolment audit metadata is passed through the MFA audit redactor. Full phone-number keys, raw OTP values, recovery codes, session tokens, cookies, and bearer headers are stripped before audit emission.
#Supported phone numbers
- Australia (
+61) only. - Non-Australian E.164 numbers are rejected before the portal calls the identity provider.
- Input that is not well-formed E.164 (missing
+, non-digits, or too few digits) is also rejected before the identity-provider call.
#Delivery failures and carrier opt-out
If SMS delivery is blocked, the enrolment flow can surface a delivery/provider warning. If you previously replied STOP, the carrier may block future SMS delivery. Use a different second factor, such as an authenticator app or recovery code, or update/remove the SMS factor through the provider management flow when available.
#What we do not do
- We do NOT send marketing or promotional SMS.
- We do NOT send appointment reminders, booking confirmations, or other business-flow SMS through this surface. Those use a separate Twilio configuration in the AiDial voice runtime.
- We do NOT use SMS OTP for any AiDial voice or chat runtime.
- We do NOT share your phone number with any third party other than the identity-provider/SMS delivery path described above.
#Removing SMS OTP
Use the trusted provider link on Account → Security (the two-factor row), which is the reachable removal path today. The separate disable-launch action lives only on the Settings → Profile & Security panel, which customer roles are currently redirected away from. Either way the portal opens the identity provider's page in a new tab. The portal does not directly delete the SMS factor; complete removal with the identity provider, then return to the portal and refresh your security status.
#Troubleshooting
- "SMS one-time code is not available for this organisation": your organisation has not opted in. Contact your administrator.
- "SMS one-time code is not available for this account type": your role does not allow SMS OTP. Use authenticator app (TOTP) or recovery code.
- "Only Australian phone numbers (+61) are supported for SMS one-time code at this time": AiDial supports
+61numbers only at launch. - "Enter a valid mobile number including the +61 country code": the number was not accepted as well-formed E.164, or the identity provider rejected it.
- "Too many SMS one-time code requests. Try again in a minute.": the rate limit has been reached. The portal enforces per-phone and per-user buckets (3 per minute and 10 per day), a trusted source-IP bucket when proxy headers are verified (30 per hour), and a global bucket (100 per minute). Wait one minute and try again.
- "We could not deliver the SMS to this number": the identity-provider SMS integration is unavailable, the provider call failed, or the carrier may have blocked delivery. The portal returns the same
mfa_sms_provider_unavailablecode for all of those cases, so the card cannot distinguish them. Use a different second factor, and contact support if it keeps failing.
#Sub-processor disclosure
| Sub-processor | Country | Purpose | Data shared |
|---|---|---|---|
| Twilio Inc. | United States | Deliver authentication SMS | Mobile number + delivery status |
| (See multi-factor-auth.md for the email OTP sub-processor disclosure) |