Enabling and Disabling Individual Steps
July 11, 2026 ยท View on GitHub
Every step in requiredSetupSteps and the login flow can be enabled or disabled
without removing it from the configuration. This is useful for feature flags, A/B
testing, or gradual rollouts.
Disabling a setup step
Add 'enabled' => false to the driver definition:
'drivers' => [
'smsOtp' => [
'enabled' => false, // step is skipped entirely
'options' => ['ttl' => 300],
],
],
When a step is disabled:
VerificationService::getDriver('smsOtp')returnsnull.VerificationService::getSteps()skips it.- It is never listed in
VerificationResult::pendingSteps(). - Users are not redirected to it.
Disabling the login flow (step-up 2FA)
To skip 2FA on every login, disable the plugin entirely via the master toggle:
// config/verification.php
'enabled' => false,
Or disable only the OTP driver the user enrolled in:
'drivers' => [
'totp' => ['enabled' => false],
],
When a driver is disabled, the login-time OTP step for users who enrolled in that driver is skipped.
Removing a step from requiredSetupSteps
Simply omit it from the array:
// Only email verification is required; TOTP and SMS are optional.
'requiredSetupSteps' => ['emailVerify'],
Runtime enable / disable (env-based)
You can drive enabled from an environment variable:
'drivers' => [
'smsOtp' => [
'enabled' => (bool)env('FEATURE_SMS_OTP', false),
],
],
Step order
Steps in requiredSetupSteps are evaluated in the order listed:
'requiredSetupSteps' => ['emailVerify', 'totp', 'smsOtp'],
emailVerifyis always evaluated first and blocks all other steps until complete.totpis evaluated next.smsOtpis evaluated last.
Disabled steps are excluded before the order is applied, so removing totp does
not shift the position of smsOtp.
Checking the effective step list
// Returns only enabled steps in configured order.
$steps = $this->Verification->getService()->getSteps();
Example: disable TOTP in development
// config/app_local.php (dev overrides)
Configure::write('Verification.drivers.totp.enabled', false);
Or use a conditional in config/verification.php:
'drivers' => [
'totp' => [
'enabled' => !Configure::read('debug'),
'options' => ['issuer' => 'MyApp'],
],
],
Documentation
Full documentation index: index.md