Implementing FIDO2 and Passkeys for Wallet and Payment Platform Admins
authenticationdevguidesecurity

Implementing FIDO2 and Passkeys for Wallet and Payment Platform Admins

ddirham
2026-01-30
11 min read
Advertisement

Practical 2026 developer guide to deploy FIDO2 passkeys for admin portals and custodial services—step-by-step code, ops policies, and compliance tips.

Stop Password Takeovers: Implementing FIDO2 & Passkeys for Wallet and Payment Admins (2026)

Hook: If your custodial wallet or payment admin portal still depends on passwords, you are one successful phishing email or social-engineering campaign away from a catastrophic compromise. 2026 has already shown a surge in large-scale password attacks across major platforms—this guide gives engineers and IT admins a step-by-step, production-ready path to replace passwords with FIDO2 passkeys (WebAuthn) for admin-facing systems and sensitive custodial services.

Why this matters now (2026 context)

Late 2025 and early 2026 accelerated platform support and enterprise adoption of passkeys: major browsers and mobile ecosystems further stabilized passkey sync, and security teams are reporting significantly reduced phishing-driven account takeovers where WebAuthn is enforced. Simultaneously, targeted attacks against social platforms remind us that password-based flows remain the weakest link for administrative and custodial accounts. For wallet/payment operators in the UAE and the wider MENA region, moving to passkeys also aligns with rising regulatory expectations for strong customer authentication and operational security.

What you will get from this guide

  • A clear architecture for adding FIDO2/WebAuthn-based passkeys to admin portals and custodial UIs.
  • Step-by-step developer quickstart with client and server code (Node.js/Express).
  • Operational policies: onboarding, device management, loss/recovery, and attestation policy choices.
  • Security controls and compliance considerations for UAE/regional deployments.

High-level design decisions (before you code)

Make these choices up front — they shape UX and security.

  • Primary vs. second factor: For admin and custodial access, we recommend passkeys as the primary authentication factor (passwordless) and require an additional step-up (hardware key + session confirmation) for transaction approvals or custody operations.
  • Attestation policy: Enforce attestation for high-privilege admins (allowing verification of TPM, Secure Enclave or FIDO authenticator provenance). For regular staff, allow self-attested platform keys but track device risk.
  • Device classes: Differentiate platform passkeys (iCloud Keychain, Android/Chrome) vs roaming hardware keys (YubiKey). Mandate roaming keys for super-admins and custody signers.
  • Recovery model: Do not rely on passwords for recovery. Offer multi-device passkey onboarding, backup passkeys, and a short-lived recovery code escrowed in an enterprise secrets manager (HashiCorp Vault or equivalent) with strict KYC for recovery actions.
  • Session & privilege staging: Limit session lifetime and require step-up authentication for critical operations (withdrawals, key management, identity modifications).

Quick architecture: components you need

  • Frontend (admin portal): JavaScript code using WebAuthn (navigator.credentials.create / get).
  • Backend: WebAuthn server logic to generate options and verify attestation/assertion. Example below uses Node.js + Express.
  • Credential store: SQL/NoSQL table to store credentialId, publicKeyPem, signCount, transports, device metadata, attestation type.
  • Policy engine: To route high-risk sign-ins to additional attestation checks or deny access (SIEM + SOAR integration).
  • Audit & logging: Immutable logs (WORM storage) of registration and assertion events for compliance and incident response.

Step-by-step developer quickstart (Node.js / Express)

Below is an implementation blueprint you can use as a starting point. We focus on the two core flows: Registration (attestation) and Authentication (assertion).

Prerequisites

  • Node.js 18+
  • HTTPS in dev (localhost with mkcert or use ngrok)
  • Library: simplewebauthn (server+client) — or implement raw WebAuthn flows if you need custom attestation verification.

Database schema (simplified)

-- users table
CREATE TABLE admins (
  id UUID PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  display_name TEXT,
  is_super BOOLEAN DEFAULT FALSE
);

-- webauthn credentials
CREATE TABLE webauthn_credentials (
  id UUID PRIMARY KEY,
  admin_id UUID REFERENCES admins(id),
  credential_id BYTEA NOT NULL,
  public_key BYTEA NOT NULL,
  sign_count BIGINT DEFAULT 0,
  transports TEXT[],
  attestation_type TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);

Server: registration options

Generate registration options and store the challenge in the user's server-side session (or a short-lived store).

const express = require('express');
const { generateRegistrationOptions, verifyRegistrationResponse } = require('@simplewebauthn/server');
const app = express();
app.use(express.json());

const rpName = 'Acme Wallet Admin';
const rpID = 'admin.dirham.cloud';

app.post('/webauthn/register/options', (req, res) => {
  const { adminId, displayName } = req.body;
  const options = generateRegistrationOptions({
    rpName,
    rpID,
    userID: adminId,
    userName: displayName,
    attestationType: 'direct', // require attestation for admins
    authenticatorSelection: {
      residentKey: 'required',
      userVerification: 'required'
    }
  });
  // store options.challenge in session/store keyed by adminId
  saveChallenge(adminId, options.challenge);
  res.json(options);
});

Server: registration verification

app.post('/webauthn/register/verify', async (req, res) => {
  const { adminId, attestationResponse } = req.body;
  const expectedChallenge = loadChallenge(adminId);

  try {
    const verification = await verifyRegistrationResponse({
      response: attestationResponse,
      expectedChallenge,
      expectedOrigin: 'https://admin.dirham.cloud',
      expectedRPID: rpID
    });

    if (verification.verified) {
      const { credentialPublicKey, credentialID, counter } = verification.registrationInfo;
      // store credentialPublicKey, credentialID, counter
      await db.insert('webauthn_credentials', {
        admin_id: adminId,
        credential_id: credentialID,
        public_key: credentialPublicKey,
        sign_count: counter,
        attestation_type: verification.registrationInfo.attestationType
      });
      return res.json({ ok: true });
    }

    res.status(400).json({ ok: false });
  } catch (e) {
    console.error(e);
    res.status(500).json({ ok: false, error: e.message });
  }
});

Server: authentication options

const { generateAuthenticationOptions, verifyAuthenticationResponse } = require('@simplewebauthn/server');

app.post('/webauthn/auth/options', async (req, res) => {
  const { adminId } = req.body;
  const userCredentials = await db.select('webauthn_credentials', { admin_id: adminId });
  const options = generateAuthenticationOptions({
    allowCredentials: userCredentials.map(c => ({ id: c.credential_id, type: 'public-key', transports: c.transports })),
    userVerification: 'required'
  });
  saveChallenge(adminId, options.challenge);
  res.json(options);
});

Server: authentication verification

app.post('/webauthn/auth/verify', async (req, res) => {
  const { adminId, assertionResponse } = req.body;
  const expectedChallenge = loadChallenge(adminId);
  const cred = await db.findOne('webauthn_credentials', { admin_id: adminId, credential_id: assertionResponse.id });

  try {
    const verification = await verifyAuthenticationResponse({
      response: assertionResponse,
      expectedChallenge,
      expectedOrigin: 'https://admin.dirham.cloud',
      expectedRPID: rpID,
      authenticator: {
        credentialID: cred.credential_id,
        credentialPublicKey: cred.public_key,
        counter: cred.sign_count
      }
    });

    if (verification.verified) {
      // update sign_count
      await db.update('webauthn_credentials', { id: cred.id }, { sign_count: verification.authenticationInfo.newCounter });
      // create session
      createAdminSession(adminId);
      return res.json({ ok: true });
    }

    res.status(401).json({ ok: false });
  } catch (e) {
    console.error(e);
    res.status(500).json({ ok: false, error: e.message });
  }
});

Client: registration (browser)

Call the server /register/options, then use navigator.credentials.create()

async function registerPasskey(optionsFromServer) {
  const publicKey = optionsFromServer;
  // convert base64 to ArrayBuffers as needed
  const credential = await navigator.credentials.create({ publicKey });
  // send credential to /webauthn/register/verify
}

Client: authentication (browser)

async function authenticate(optionsFromServer) {
  const publicKey = optionsFromServer;
  const assertion = await navigator.credentials.get({ publicKey });
  // send assertion to /webauthn/auth/verify
}

Operational policies and best practices

1. Onboarding & device naming

  • Require admins to register at least two passkeys (primary device and backup) during onboarding.
  • Store metadata (device label, platform, transport) at registration time and present device names in the admin portal's device management UI.

2. Super-admin protections

  • Require roaming hardware keys (FIDO2 USB/NFC/BLE) for super-admins and custody operators.
  • Use attestation verification to allow only authenticators from approved vendors (e.g., Yubico, Feitian, platform TPMs) for these roles.

3. Recovery & lost devices

  • Do not fall back to password resets for super-admins. Use a strict recovery workflow combining KYC verification, video calls, and escrowed recovery codes.
  • Support multi-device passkeys and enterprise-managed backup passkeys stored encrypted in a corporate secrets manager with narrow access controls.

4. Session management & step-up

  • Short session lifetimes for admin logins (e.g., 15–60 minutes) and require fresh passkey authentication for any sensitive operation like key rotation, withdrawals, or KYC changes.
  • Log all assertions and monitor signature counters for abnormal resets (potential cloned key detection).

5. Device revocation

  • Provide immediate device revocation in the admin UI and alert security when a high-privilege credential is removed.
  • Automate SIEM alerts on suspicious sequences like credential removal + new credential registration within short windows.

Security details you must implement

  • TLS-only: Only serve origin and RP ID over TLS (HSTS, strong ciphers).
  • Origin & RPID checks: Enforce expectedOrigin and expectedRPID checks when verifying responses.
  • Attestation verification: Validate attestation certificates when attestationType is 'direct' and record CA chains for audit.
  • Counter checks: Ensure authenticator signCount monotonic increases. A sudden decrease can indicate a cloned authenticator; trigger alerts and require re-registration.
  • Rate limits: Throttle registration / authentication attempts and log IP geolocation anomalies.

Custodial & transaction-security considerations

Passkeys are a powerful anti-phishing control for portal access, but they are not a substitute for transaction signing controls:

  • Keep custody private keys inside HSMs or MPC; separate authentication (passkeys) from transaction-signing credentials.
  • For high-value transactions, require multi-party approvals where each approver authenticates with a passkey and separately authorizes the transaction via the custody HSM.
  • Use time-locked operations and pre-transaction risk scoring to require hardware keys when risk thresholds are exceeded.

Compliance & regional guidance (UAE and MENA)

While passkeys strengthen operational security, align implementations with regional compliance needs:

  • Data residency: Keep credential metadata and logs in the region if regulators require local storage.
  • KYC/AML: Use passkey authentication as part of strong access controls for personnel who can change KYC data or approve transactions.
  • Auditability: Retain attestation evidence and assertion logs for the retention periods required by supervisors and internal policies.
  • Change control: Document passkey onboarding and recovery flows in your ISMS and ensure SOC/ISO/CB assessments include these controls.

Testing, rollout and metrics

Pilot

  • Start with a small pilot group of developers and security admins. Require roaming keys for the pilot's high-risk users.
  • Track UX friction metrics: registration success rate, time to authenticate, support tickets for lost devices.

Canary & progressive rollout

  • Use progressive exposure: require passkeys for new sessions while allowing legacy password sessions for existing authenticated users for a short period.
  • Enforce passkeys for high-risk roles first (custody operators, finance, compliance).

Key success metrics

  • Reduction in password reset incidents and account takeovers.
  • Decrease in phishing click-throughs leading to admin access.
  • Lower mean time to detect (MTTD) for suspicious admin sessions.

Advanced strategies & future-proofing (2026+)

  • Attestation allowlists: Keep a whitelist of attestation CAs and device classes for super-admins; periodically update based on vendor firmware advisories.
  • MPC & HSM integration: Use passkeys for admin authentication and combine with MPC/HSM approvals for signing operations to maintain cryptographic separation of duties.
  • Policy-as-code: Encode access and step-up rules in a policy engine so you can tune thresholds without code releases.
  • Continuous compliance: Automate evidence collection (attestation + assertion logs) into your compliance pipeline for audits.

Common pitfalls and how to avoid them

  • Pitfall: Relying on password recovery for admin accounts. Fix: Enforce non-password recovery flows with KYC and strict human verification.
  • Pitfall: Weak attestation policy for high-privilege accounts. Fix: Require direct attestation and vendor allowlist.
  • Pitfall: Not monitoring signature counters. Fix: Alert on unexpected counter resets and require re-registration.

Operational checklist (quick)

  1. Enable TLS and set secure cookies/hsts.
  2. Implement WebAuthn registration & authentication flows on server and client.
  3. Require roaming keys + attestation for super-admins.
  4. Deploy device management UI with revoke and label actions.
  5. Set strict recovery process; avoid password fallback.
  6. Integrate logs with SIEM and set alerts for counter anomalies and attestation failures.
  7. Document procedures for audits and regulator queries.

Note: Recent large-scale password reset and takeover waves in early 2026 underscore why eliminating passwords for admin and custody roles is no longer optional.

Case example: reducing admin takeovers at a regional wallet operator

One mid-sized MENA wallet provider ran a pilot in Q4 2025: 40 security engineers and ops staff moved to passkeys with roaming-key requirements for custody operators. Within 90 days they reported:

  • 0 confirmed admin account takeovers (previously 3 incidents the prior 6 months).
  • 80% fewer support tickets for suspicious activity related to admin accounts.
  • Faster incident response due to deterministic logs of attestations and assertions.

Final recommendations

Make passkeys the baseline for admin authentication—enforcing them for any account that can move funds, change controls, or manage keys. Combine passkeys with strict attestation and hardware key requirements for custodial roles. Design recovery flows that don’t reintroduce passwords, and automate logging and monitoring so your security team can detect anomalies early.

Get started — practical next steps (30/60/90 day plan)

Day 0–30

  • Implement registration/authentication endpoints and a device management UI in a staging environment.
  • Run a developer & security team pilot with clear instrumentation.

Day 31–60

  • Expand to ops and compliance teams; require roaming keys for high privileges.
  • Integrate logs with SIEM and create alerts for counter anomalies and attestation failures.

Day 61–90

  • Enforce passkeys for all new admin sessions; deprecate password-only logins for privileged accounts.
  • Complete documentation, audits, and prepare for regulator inquiries with retained attestation evidence.

Call to action

Strong authentication for admin and custodial systems is a critical control you cannot postpone. Start a pilot this week: pick a small admin group, deploy the WebAuthn flows above, and report on reduction in password-based incidents. If you need a turnkey solution, dirham.cloud offers professional services and developer integrations tailored for UAE payment rails and custodial platforms—reach out to schedule a technical review and risk assessment.

Advertisement

Related Topics

#authentication#devguide#security
d

dirham

Contributor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-02-03T19:05:48.748Z