API Documentation

Migrating from Duo

Moving from Duo's Auth API to WiraPass: what to change, what works and what does not.

Documentation Pages

A system that uses Duo's Auth API v2 today only changes three values. Your code and Duo's official libraries stay the same.

What to Change

ValueDuoWiraPass
API hostnameapi-xxxxxxxx.duosecurity.comauth.wiracode.com
Integration keyfrom the Duo Admin Panelfrom the WiraPass operator (how)
Secret keyfrom the Duo Admin Panelfrom the WiraPass operator
Python (duo_client)
# Before (Duo)
auth = duo_client.Auth(ikey="DIXXXXXXXXXXXXXXXXXX", skey="duo-secret", host="api-xxxxxxxx.duosecurity.com")

# After (WiraPass): the same code, three new values
auth = duo_client.Auth(ikey="DIYYYYYYYYYYYYYYYYYY", skey="wirapass-secret", host="auth.wiracode.com")

Usernames Are Emails

WiraPass knows users by the email they sign in to the WiraPass app with. Send that email as the username. If your usernames are not emails, map them to the user's email first. The user_id is the WiraPass user id (UUID), not a Duo id.

What Works

  • Endpoints /auth/v2/ping, /auth/v2/check, /auth/v2/logo, /auth/v2/enroll, /auth/v2/enroll_status, /auth/v2/preauth, /auth/v2/auth, /auth/v2/auth_status.
  • Factors auto, push (a WiraPass approval) and passcode (the WiraPass backup code), with or without async.
  • Signature versions 5, 4 and 2 (HMAC-SHA512 or HMAC-SHA1), JSON or form bodies, and X-Duo-* headers.
  • Duo's answer format, Duo's error codes and the status values allow, deny, fraud, timeout, locked_out, pushed.
  • type, display_username, pushinfo, ipaddr, hostname show on the user's phone.

What Does Not Work

  • SMS (factor=sms) and phone callback (factor=phone): refused with 40002 and a clear message.
  • Duo Universal Prompt and the OIDC web flow (/oauth/v1/…), and the old Web SDK v2.
  • Bypass codes and hardware tokens. The bypass_codes parameter of enroll is ignored.
  • Verified Duo Push and Remembered Devices: client_supports_verified_push and trusted_device_token are accepted and ignored, and preauth never answers allow.
  • The Admin API, the Accounts API and signature version 1.

Passcode Is the WiraPass Backup Code

The user opens the WiraPass app, then Settings, Approvals, Backup code. The code has 6 digits, changes every 30 seconds, and each code works once. Send it as passcode with factor=passcode.

  • mobile_otp in preauth only appears when the user has a backup code.
  • At most 5 checks per 5 minutes per user, then 42901.
  • After 10 wrong codes in a row the code locks and the answer is status=locked_out. The user creates a new code on an active phone.

Enrolling Users

There is no Duo Mobile activation. Users install WiraPass, sign in with the same email and turn on approvals. The enroll endpoint returns the download page and a QR code of it, and enroll_status answers success as soon as that email has an active approval phone. In WiraPass, username is required on enroll. The enroll_portal_url of preauth points to the download page too.

Other Small Differences

  • A push shows on every approval phone of the user that is signed in to WiraPass. device may be auto or a phone id from preauth.
  • When no phone is signed in, a push is answered deny without sending anything, and status_msg suggests the backup code.
  • After Not me, preauth answers deny and pushes are refused for 15 minutes for that integration.
  • status_msg is in Indonesian unless you send Accept-Language: en. number in devices is always empty.
  • txid is a UUID, and auth_status waits at most 8 seconds per call. Other limits.

TLS Certificates and CA Pinning

Duo's official libraries trust only their own list of root CAs by default (CA pinning). If your library refuses the WiraPass certificate, for example with CERTIFICATE_VERIFY_FAILED, turn pinning off with the option below. Normal TLS certificate checks still run against the system CA list.

LibraryOption
duo_client (Python)duo_client.Auth(..., disable_ca_pinning=True)
@duosecurity/duo_api (Node.js)new Client(ikey, skey, host, 5, false)
duo_api_php$auth->disableCaPinning()
duo_api_golangduoapi.NewDuoApi(ikey, skey, host, ua, duoapi.SetCAPinning(false))
duo-client (Java)new Http.HttpBuilder(...).disableCaPinning().build()

Duo is a trademark of Cisco. WiraPass is not affiliated with Duo or Cisco and only offers API compatibility.