When SMS one-time codes with authentik make sense as a second factor
Choose SMS one-time codes only when your users already carry a phone that can receive texts, you have no practical way to hand them a stronger factor on the same timeline, and you accept that SMS is the lowest-assurance second factor in your set. The authentik SMS stage sends a code to a phone number during a flow and validates the code the user types back. It supports two provider types: Twilio, which needs an account SID, an auth token and a sender number, and a generic provider that POSTs the message to an API URL you configure, authenticated with Basic or Bearer credentials. With the generic provider, a response with status 400 or higher blocks the user, so the gateway's failure behavior becomes part of your login availability.
Weigh SMS against the other methods authentik offers before you commit. TOTP apps run on the user's device without a carrier in the path, WebAuthn and passkeys resist phishing in ways a typed code does not, and Duo gives you push approval and a managed enrollment path if you already license it. SMS depends on the carrier, the phone number and the messaging gateway, and a number can be reassigned or ported. Ask your security team whether your risk assessment and any control you must map to accept SMS as a factor for each population, and confirm that answer in writing before you build the flow. Some organizations keep SMS only as a fallback for users who cannot use an app or key.
If you proceed, decide early whether the phone number is for ongoing MFA or only for proving ownership. Verify-only mode confirms the user controls the number at enrollment and stores a hash instead of the number, so that number cannot later be used as a factor. That fits a recovery or identity-proofing use case better than daily login. Limiting which numbers users may register needs a prompt stage and an expression policy, which you should plan for alongside the provider choice. Confirm with your gateway vendor the per-message costs, country coverage and sender registration rules that apply to your user base, because those drive operating cost and are not set by authentik.
Twilio or generic gateway: which provider fits
This table compares the Twilio provider with the generic HTTP provider in authentik's SMS stage across credentials, setup, and failure behavior. Read it against your SMS contract and your gateway's operating model to decide which provider your team can run and audit.
| Consideration | Twilio provider | Generic HTTP provider |
|---|---|---|
| Typical fit | Organization with a contracted Twilio account and sender number | In-house, regional or carrier gateway that accepts an HTTP request |
| Settings to enter | Account SID, auth token and sender number | Configured API URL plus Basic or Bearer authentication |
| Credential handling | Auth token is stored in authentik, so restrict admin access to the stage and rotate the token on your schedule | Credentials depend on the gateway's auth scheme, so confirm whether a Bearer token or Basic password is needed and who can read it |
| Request format | Built for Twilio's messaging interface, with no custom request body to maintain | authentik sends a request to your URL, so the gateway must accept the payload authentik produces |
| Failure behavior | Confirm with your Twilio account how send errors surface before relying on the stage | Responses with status 400 or higher block the user, so a gateway outage can lock out MFA logins |
| Operations owner | Your Twilio account administrator and your sender registration | Your team or the gateway vendor, including uptime, rate limits and logs |
| Recovery planning | Keep a second MFA method available for users whose SMS fails | Keep a second MFA method available and test gateway changes in staging first |
Verify-only mode: confirming a number without storing it
Verify-only mode lets authentik confirm that a user controls a phone number at enrollment, then keeps only a hash of that number instead of the number itself. Because the stored value is a hash, the number cannot later be used as a second factor for login. The practical effect is that verify-only is a one-way check, not a login method. Before you enable it, confirm in the SMS stage settings in your own authentik version how the hash is generated and whether any administrator view still exposes the plain number, since the answer determines what your privacy notice and data inventory must say.
The trade-off appears when users expect to sign in with SMS later. A user who enrolls under verify-only will find no SMS option afterward, and the same number cannot be re-added as an authenticator without a separate enrollment path. Decide before rollout whether SMS login is a supported method at all. If it is, use a standard SMS authenticator stage with an explicit enrollment flow, and communicate clearly which users were enrolled in which mode so help desk staff do not treat a missing SMS option as a fault.
A verify-only stage fits recovery and identity proofing better than ongoing MFA. Examples include confirming that a number supplied during account recovery belongs to the person before a password reset, or checking a phone number during onboarding where you need evidence of possession without retaining the identifier. Illustrative case: a workforce tenant that wants to confirm a contractor's mobile during provisioning but does not want the number stored in the directory. Pair the stage with the throttling and failed-send behavior described elsewhere on this page, and ask your compliance lead whether a hashed identifier satisfies the retention and minimization rules that apply to your users.
How to configure the SMS stage and wire it into a flow
This sequence creates an SMS authenticator setup stage, points it at Twilio or a generic gateway, binds it to a flow, and proves with controlled test numbers that codes are sent, failures are handled and verify-only mode stores no usable phone number.
Confirm the gateway account and test numbers
Before touching authentik, the team confirms which SMS path applies: a Twilio account with an account SID, auth token and sender number, or a generic HTTP SMS gateway with an API URL and either Basic or Bearer credentials. Ask the gateway provider or your messaging team which sender identity and country routes are approved, and reserve a small set of company-controlled phone numbers for testing. Done when the team holds working credentials in a secrets store and a written list of test numbers that the project owner can receive messages on.
Create the SMS authenticator setup stage
An administrator opens the authentik admin interface, creates a new SMS authenticator setup stage, and chooses the provider type. For Twilio, enter the account SID, auth token and sender number. For a generic provider, enter the API URL and select Basic or Bearer authentication with its credential. Save the stage and keep the Twilio token or gateway credential out of change tickets and shared documents. Done when the stage appears in the stage list with the chosen provider type and no validation error on save.
Enable verify-only mode for enrollment
For enrollment, the administrator turns on verify-only mode in the SMS stage. With this setting, authentik confirms that the user controls the phone number at enrollment and stores a hash of the number instead of the number itself, so that the number cannot later be used as an MFA factor. Decide before go-live whether verify-only is the right fit, because users who need SMS as a live second factor will need a non-verify-only configuration with its own data handling review. Done when the stage shows verify-only as enabled and the team has recorded which mode each flow uses.
Bind the stage to an enrollment or validation flow
The administrator adds the SMS stage to a test enrollment or authenticator validation flow, placing it after identification and before the flow completes. For limiting accepted numbers, add a prompt stage for the phone number and an expression policy that checks the entered number against an allowed pattern or list before the SMS stage runs. Bind the flow to a test application or a test brand so that only the test group reaches it. Done when the flow diagram shows the stages in the intended order and the test user can reach the SMS step.
Run a successful test send
A tester on a controlled number starts the test flow, enters the phone number, and waits for the code. Confirm that the message arrives on the handset, that the sender identity looks as expected, and that the code is accepted at the prompt. Check the authentik event log and the gateway's delivery log to match the request to the delivered message. Done when the test user completes the stage and both logs show a successful send for the same attempt.
Run a failed-send test
Force a failure by entering a number the gateway will reject, or by temporarily pointing the generic provider at a wrong API URL in a non-production environment. Confirm the behavior the team expects: for the generic provider, a response with status 400 or higher blocks the user, so the flow should stop with a clear error and not let the user proceed without a code. Check the event log for the failure and confirm that no partial enrollment was saved. Restore the correct settings and rerun a successful test before moving on. Done when the failure produces a blocked flow and an event record, and the working configuration is restored.
Confirm the stored value in verify-only mode
After a successful verify-only enrollment, the administrator opens the user record and the authenticator device entry for the test user. Confirm that the stored value is a hash and that the plain phone number does not appear in the user attributes, device list or exported data. Then attempt to use that number in a later validation flow and confirm it is not offered as an SMS factor. Record the results with the test date and the stage version in the change record. Done when the stored value is confirmed as non-readable and the test user cannot use the number for later MFA.
What happens when the SMS provider fails
An SMS code depends on several systems outside authentik's control, so a failed send can look like a login problem to the user. The cards below cover what authentik does when the gateway rejects a request, what Twilio errors and carrier delays look like from the user's side, and how to decide between blocking the sign-in, retrying and offering another factor.
Generic gateway errors block the user
When the generic provider receives a response with status 400 or higher, authentik treats the send as failed and blocks the user at the SMS stage. The user gets no code and cannot proceed through that stage. Before go-live, call your gateway's error paths in a test tenant and confirm which status codes it returns for invalid numbers, quota limits and expired credentials, since each one lands on the same block.
Twilio rejections need a runbook
Twilio failures usually come from the account rather than the code: a wrong account SID or auth token, an unverified sender number, a suspended account or a destination country the account has not enabled. Check the Twilio console message logs first, then confirm that the sender number in authentik matches the one Twilio sends from. Keep a named owner for the Twilio account so a credential rotation does not silently break sign-in for every user.
Timeouts and carrier delays
A request that hangs is harder to handle than one that fails fast. Carrier delivery is also outside both authentik and the gateway, so a code can arrive late even when the API call succeeded. Ask the gateway about its timeout behavior, then decide how long a user should wait before the stage offers another option. Test the delay with a real handset on each carrier your users depend on.
Choose block, retry or fallback
Blocking is the strictest choice because it never sends a code through a path you did not verify, but it can lock out a user for reasons they cannot fix. Retrying helps with transient errors yet can multiply messages during an outage. Offering an alternative factor, such as TOTP or a passkey, keeps the user moving when the phone path is down. Write the policy down per error class before you enable SMS for anyone.
What users see and how to message it
A blocked stage gives the user a generic error, which often leads to a help desk ticket that looks like a password problem. Decide what the message says about the cause, whether it suggests waiting, and which alternative factor is available. Test the wording with a user account that has no other enrolled factor, because that is the case where a failed SMS send leaves the user with no path forward.
Restricting which phone numbers are accepted
Limiting which phone numbers a user can enroll takes more than the SMS stage itself. The topic facts state that restricting accepted numbers needs a prompt stage that collects the number, combined with an expression policy that decides whether the entry is allowed to continue. The policy runs on the submitted value, so the rule you write there is the only gate between a user's typed number and the SMS provider. Plan the flow so the policy is evaluated before the number is sent to Twilio or your generic gateway, because a send that already happened cannot be recalled and still costs money.
Typical rules work at the conceptual level. One group checks format and origin, such as requiring a country prefix from an approved list or rejecting entries that do not match the expected length. A second group checks reuse, such as blocking a number that another account already holds in the directory, which stops one person from registering several accounts on the same handset. Whatever rules you choose, write down the exact outcome for each case, including what the user sees when a number is refused and whether an administrator can override it. Confirm in your own environment which attributes the policy can read at that point in the flow, because reuse checks depend on the data available to the policy engine.
Test the rules against real enrollment cases before you rely on them. Build a list that includes numbers from every country you serve, mobile and landline formats, numbers with and without a leading zero, and numbers already in use by other accounts. Run each through the complete flow in a staging instance, and confirm that refused numbers never reach the send step in your gateway logs. Repeat the test after any change to the prompt or policy, and after upgrades, since flow and policy behavior can change between authentik releases. Treat this test list as a maintained artifact owned by the identity team, not a one-time check.
Security risks of SMS codes and how to reduce them
SMS codes are easy to deploy and reach most users, but the phone network carries risks that authentik cannot fix on its own. The cards below cover the threats that matter most for this setup, the settings that limit them, and the checks to run before you rely on SMS as a second factor.
SIM swap and interception
An attacker who convinces a carrier to move your user's number to a new SIM receives every code sent to that number. Because authentik cannot see the carrier's account controls, treat SMS as a weaker factor than an app or hardware key for privileged accounts. Ask your carrier and your security team which port-out and SIM change protections apply to the numbers you enroll.
Toll fraud and pumping costs
Attackers who can trigger code requests for many numbers can run up messaging charges, a pattern often called SMS pumping. Each send is billed by your provider account, so an unthrottled login form can turn into a cost problem. Confirm what your provider charges per message and set spending alerts on the account that holds the Twilio credentials or gateway key.
Phone number reuse
Carriers recycle numbers that a user has given up, so a new owner may receive codes meant for the old one. If a number stays linked to an account after the phone is replaced, the wrong person may sign in with it. Pair SMS with a periodic review of enrolled numbers and a clear process to remove a number when a user leaves or changes phones.
Provider credentials in authentik
Twilio requires an account SID and auth token, and the generic provider stores Basic or Bearer credentials for your gateway. Anyone who can read the SMS stage configuration or the database can use those secrets to send messages from your account. Restrict which administrators can edit flow stages, rotate the token on a schedule, and check where the PostgreSQL backups that hold configuration are stored.
Failed-send behavior and alerting
A generic gateway that returns a status of 400 or higher blocks the user, so a gateway outage becomes a login outage. Decide in advance whether users fall back to another factor or wait, and test that path. Log failed sends and failed logins, forward them to your monitoring system, and alert on sudden spikes, which can signal an attack or a broken integration.
Limiting accepted numbers
Verify-only mode confirms phone ownership at enrollment and stores a hash instead of the number, which stops a number from being reused for later MFA. Restricting which country codes or number ranges users may enroll needs a prompt stage with an expression policy. Confirm the exact policy logic against the authentik documentation for your version before you rely on it for country restrictions.
Questions teams ask before configuring SMS codes in authentik
How much effort does configuring SMS codes in authentik take?
The effort depends on how many flows and stages need SMS, how many provider accounts and sender numbers are involved, and how many countries your users sit in. A single enrollment flow with one provider is a small configuration task. Effort grows when you add recovery flows, separate providers per region, or a generic gateway that needs custom request and response handling. Testing is often the largest share, because delivery, formatting and failure behavior differ by carrier and country. Ask for the scope in writing, including the flows covered, the providers, and the test matrix before work starts.
What drives the cost of an SMS configuration project?
Cost follows the written scope. The main drivers are the number of flows and stages, the number of providers and sender numbers, the complexity of any generic gateway integration, and the number of countries and carriers to test. Provider charges for messages are paid to the SMS provider and recur with usage, so they are separate from any services fee. Ask a quote to separate one-time configuration and testing from recurring items such as provider fees, number rental, and ongoing support or review.
Can our internal team configure SMS codes in authentik alone?
Yes, a team with administrator experience in authentik can configure the SMS authenticator stage, the Twilio or generic provider settings, and the flow bindings without outside help. The harder parts are usually outside the admin console: negotiating provider terms, handling number registration rules in target countries, and writing expression policies that limit accepted numbers. Teams with no authentik operations experience often benefit from a fixed-scope review of the configuration before users depend on it.
What do we need to provide before the work starts?
Plan to provide a Twilio account or a generic SMS gateway with API documentation, a test sender number and test phone numbers in each country you serve, and named owners for the enrollment and recovery policies. You will also need an administrator account on your authentik instance and a non-production environment for testing. Policy owners should decide which countries and number types are accepted, because that decision drives the expression policy work. Confirm credential storage and rotation practices with your security team before any tokens are shared.
Is SMS acceptable as a second factor for our risk level?
That depends on your threat model and regulatory obligations, and the decision belongs to your risk owners. SMS codes can be intercepted through SIM swapping, number porting and phishing, and they are weaker than phishing-resistant options such as hardware keys. Many organizations accept SMS for lower-risk applications and require stronger factors for administrators and sensitive systems. Review the applicable control requirements with your compliance lead and your auditor, since DeployOpen prepares evidence but does not decide acceptability.
How do we stop SMS MFA from being used with numbers we do not control?
Use verify-only mode when you only need to confirm phone ownership at enrollment, because it stores a hash of the number rather than the number itself, so that number cannot later be used for MFA. For broader control, combine a prompt stage with an expression policy that checks the entered number against the countries and number types you accept. Test both paths with real numbers from each accepted country, and confirm the policy blocks the rest before rollout.
How long does a typical configuration review take?
A configuration review typically covers the SMS stage settings, the provider or gateway behavior on success and failure, the flow bindings, and the number restriction policy. The duration scales with the number of flows and providers and with how many test countries you need. Ask the provider of the review to state the duration in the written scope, and ask what is excluded, such as provider-side account setup or carrier registration work.
How DeployOpen works on this
DeployOpen scopes SMS one-time codes for authentik as a written, fixed-scope engagement, then configures the Twilio or generic gateway integration inside your own infrastructure. The work covers provider settings, number restrictions, failed-send behavior and the testing and handover your team needs to run it.
How we scope
- Confirm whether the SMS provider is Twilio or a generic HTTP gateway, and who holds the account and credentials
- Decide whether the SMS stage verifies phone ownership only or sends codes for ongoing MFA, and record that choice in writing
- Define accepted number ranges, country restrictions and the prompt and expression policy logic that limits which numbers users can register
How we build
- Configure the SMS stage with Twilio credentials or a generic API URL using Basic or Bearer authentication, stored as secrets
- Set failed-send handling so generic gateway responses with status 400 or higher block sign-in as intended, and test each path
- Test enrollment, verify-only mode, code validation and number restriction against a staging instance before production
How we hand over
- Deliver a configuration record listing the stages, flows, policies and provider settings, with secret locations named but not exposed
- Document the runbook for rotating gateway credentials, changing sender numbers and responding to delivery failures
- Walk your operations and security staff through the test results and the residual risks of SMS as a second factor
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer after handover
- Ask for the support scope in writing, including how authentik version upgrades and gateway changes are handled
- Confirm with your SMS provider and authentik release notes which versions and features apply to your environment before go-live

