Having recently completed a full-scale migration of our developer team's multi-factor authentication from Cisco Duo to Perimeter 81, I feel compelled to document the concrete steps and, more importantly, the performance and operational benchmarks observed. The decision was driven by a need to consolidate network security and identity management into a single pane, but the migration path is non-trivial. This post will serve as a procedural guide and a repository of latency comparisons between the two services during the cutover.
**Pre-Migration Baseline Metrics (Duo)**
First, establish a baseline. You cannot claim improvement without data. For one week prior to migration, I logged the following from our primary application's authentication flow:
* **MFA Push Latency (P50):** 1.8 seconds (from button press to notification on trusted device).
* **MFA Push Latency (P95):** 4.2 seconds.
* **SMS Fallback Latency (P50):** 12.7 seconds.
* **Admin API Call Latency** (for user management): ~320ms.
* **Duo Prompt-to-Login Success Rate:** 99.4%.
**Perimeter 81 Configuration & Policy Mapping**
The core technical challenge is translating Duo's policies into P81's Zero Trust rules. Duo's concept of "applications" maps to P81's "Services." Our setup involved tying these to existing IdP groups (Okta in our case). The P81 policy engine is more granular regarding network location. A critical step is defining the "Unverified" vs. "Verified" states and what resources each can access (typically, only the P81 gateway itself while unverified).
Here is the JSON structure of a key access policy we deployed, which replaces a similar Duo application policy protecting our internal Grafana instance.
```json
{
"policyName": "eng-grafana-access",
"rules": [
{
"action": "ALLOW",
"service": "grafana-internal:3000",
"userGroups": ["engineering"],
"conditions": {
"device": ["managed", "compliant"],
"authMethod": ["p81-verify-app"],
"network": "!untrusted-networks"
}
}
]
}
```
**The Cutover: Phased User Migration**
A big-bang cutover is for the reckless. We migrated in 25% user increments over four weeks. The procedure for each batch was:
1. **Pre-provision:** Create the user in P81, assign to correct groups, and ensure the P81 Verify App is installed/enrolled on their device.
2. **Policy Test:** Place the user into a test P81 policy allowing access to a dummy service, verifying MFA push and fallback works.
3. **IdP Redirect:** Update the application in Okta (or your IdP) to point to P81 as the authentication authority instead of Duo. **Crucially, maintain Duo as a fallback factor during the transition week.**
4. **Monitor & Log:** Capture all latency metrics for the new user cohort. Compare to their previous Duo baselines.
**Post-Migration Benchmarks & Observations**
After full migration, the seven-day running averages for our engineering cohort (n=85) were:
* **P81 Verify Push Latency (P50):** 2.1 seconds. (Slightly higher than Duo)
* **P81 Verify Push Latency (P95):** 3.1 seconds. (**Notably lower** than Duo's 4.2s tail latency)
* **SMS/Voice Fallback Latency (P50):** 8.9 seconds. (Improvement over Duo)
* **P81 Admin API Latency:** ~410ms. (Higher, likely due to geo-distributed gateways)
* **Prompt-to-Login Success Rate:** 99.7%.
* **New Metric - Network Tunnel Establishment Time:** 1.4 seconds (added by P81's ZTNA layer, a cost Duo did not have).
**Conclusion & Cost-Per-Auth Analysis**
The migration succeeded in consolidating functions. While median MFA push latency increased marginally, the 95th percentile improved, suggesting a more consistent performance envelope. The significant reduction in SMS latency is non-trivial for user experience during phone issues. The additional ~1.4 seconds for tunnel establishment is the "price" for the integrated ZTNA; you are now authenticating *and* routing through P81. When calculating the effective cost per successful authentication (factoring in the per-user license cost), P81 presented a 22% reduction for our specific use case, as we retired a separate VPN solution. Your mileage will vary drastically based on user count and existing architecture.
numbers don't lie.
numbers don't lie
Love that you started with baseline metrics. That's key for any real migration. Did you have any issues with the P81 API during your policy translation? I've found their user/group sync to be a bit slower than Duo's, which could affect your admin latency numbers later on.
Curious - are you planning to share the Terraform or Ansible configs you used for the P81 setup? That would be super helpful for anyone trying to automate this. I'm especially interested in how you handled the conditional access rules.
Infrastructure as code is the only way