Skip to main content

Security, MFA, and sessions

Use Authentication > Security to control the risk level of account access. This page covers MFA, session duration, bot prevention, step-up authentication, and privileged sessions.

Switera security settings page with MFA, sessions, CAPTCHA, step-up, and privileged session controls
Security settings should match the sensitivity of the app and the expectations of the organizations that use it.

Start with session policy​

Review:

  • how long a normal session lasts
  • when idle sessions expire
  • whether remember-me behavior is allowed
  • whether admins need shorter session duration
  • whether session changes should force reauthentication

Shorter sessions reduce risk but can frustrate users. Longer sessions improve convenience but require stronger safeguards.

Enable MFA intentionally​

MFA is useful when:

  • users have access to sensitive data
  • admins can change billing, security, or identity settings
  • enterprise customers require stronger assurance
  • account takeover risk is high

Before enforcing MFA:

  1. Confirm the recovery path works.
  2. Test enrollment with a small group.
  3. Communicate the change before enforcement.
  4. Keep a support process for lost factors.

Test authenticator enrollment​

Hosted two-factor authentication with authenticator and backup-code methods and an empty code input
A fresh sign-in asks for a second factor before returning to your app. This screenshot contains no enrollment secret or recovery code.

Use a dedicated app and end user before enabling a policy for customers. Enable optional authenticator MFA and backup codes in Authentication > Security, and register your application's OAuth callback URL. The end user must already be allowed to sign in under your app's email-verification policy.

With an authenticated @switera/auth client in your application:

const enrollment = await auth.setupTOTP();
// Display enrollment.qr_code_data_url in the user's private security page.
// The user scans it with their authenticator and enters its current code.
await auth.verifyTOTP(codeFromAuthenticator);

const { codes } = await auth.generateBackupCodes();
const status = await auth.getMFAStatus();
// status.totp_enabled is true; status.backup_codes_remaining is 10.

Do not log the enrollment secret, QR contents, authenticator codes or backup codes. Let the end user save their backup codes securely. Generating a new set invalidates the previous set.

  1. Open a fresh browser session and sign in to your app.
  2. Confirm that hosted login asks for an authenticator code before returning to your callback.
  3. Enter a current six-digit code and confirm that your application's SDK finishes the callback.
  4. In another fresh session, choose Backup Code and paste one of the SDK-generated codes. Both xxxx-xxxx and the compact eight-character form are accepted.
  5. Confirm that reusing the same backup code is rejected.

These are managed app end-user flows, not Switera builder-account MFA. The live test covers optional authenticator MFA and backup-code recovery; required enrollment, SMS and security-key flows are not covered by that result. See SDK validation limits.

If login cannot verify your app's sign-in requirements, retry or contact support. Do not disable MFA as a workaround for an unavailable security check.

Disable or recover MFA​

An authenticated end user can call auth.disableTOTP(). Check auth.getMFAStatus() afterward. TOTP disable currently removes the authenticator enrollment but does not remove backup-code records.

A builder with user-management permission can reset an end user's TOTP and backup codes through the end-user security controls or the trusted-backend endpoint DELETE /api/v1/apps/{appId}/users/{userId}/mfa. Verify the resulting state using GET on that endpoint: totp_enabled must be false and backup_codes_remaining must be zero. This reset does not remove security-key credentials. Never expose a builder or app secret in the end user's browser.

Read an end user's passkeys​

After the end user signs in to your app, use its authenticated Auth SDK client:

const passkeys = await auth.listPasskeys();
// Each item has id, display_name, created_at and optional last_used_at.

This calls GET /api/v1/connect/me/passkeys using the end user's access token. The app and identity come from that token, not an app ID supplied by the browser. A valid empty inventory returns []. Authentication failures, inactive app membership, and temporary service errors must not be displayed as "no passkeys". Do not send a builder session or secret app key from this security page.

This is an inventory read, not passkey enrollment. Second-factor security keys are separate. Registration, passkey login and deletePasskey(id) are not yet accepted customer journeys; keep those controls unavailable until their browser and policy checks pass. See SDK validation limits.

Bot prevention​

Bot prevention can include CAPTCHA, disposable email blocking, and sign-up or login rate limits.

Use it when:

  • public sign-up is enabled
  • trial abuse is likely
  • password guessing attempts appear in logs
  • provider login is exposed to a broad audience

Do not enable controls that block legitimate users without a recovery plan.

Step-up authentication​

Step-up asks a user to re-authenticate before sensitive operations. Use it for actions such as:

  • changing password or email
  • adding MFA
  • viewing or rotating keys
  • changing organization owner roles
  • changing SSO settings

Privileged sessions​

Privileged sessions are useful when admins perform high-risk actions. Keep the window short and require fresh authentication.

Launch checklist​

  • baseline sign-in method works
  • email verification and recovery work
  • MFA policy is clear
  • session duration matches risk level
  • bot prevention has been tested
  • step-up protects sensitive operations
  • support knows how to handle locked-out users

Related pages: