How TREK Implements Passkey WebAuthn Authentication: A Complete Technical Guide

TREK implements passkey WebAuthn authentication through a three-layer architecture that combines a feature-toggle guard, a stateful service managing single-use cryptographic challenges, and REST controllers that generate standard JWT sessions upon successful verification.

The open-source TREK repository provides a production-ready implementation of WebAuthn (passkey) authentication that integrates seamlessly with existing session-based security. Unlike bolt-on solutions that treat WebAuthn as a separate identity provider, TREK embeds the protocol directly into its native authentication stack, using the same session cookies and audit trails as password or OIDC logins.

Feature Toggle and RP Guard

Before any WebAuthn ceremony executes, TREK validates that the functionality is enabled and properly configured.

The PasskeyEnabledGuard

The PasskeyEnabledGuard in server/src/nest/auth/passkey-enabled.guard.ts acts as a mandatory prerequisite for all passkey endpoints. This guard checks two conditions:

  • Admin Configuration: Verifies that the Passkey feature flag is enabled in application settings.
  • Relying Party (RP) Resolution: Ensures a valid WebAuthn Relying Party ID (RP ID) can be resolved from the environment.

If either check fails, the guard returns a 404 Not Found response before any authentication logic executes, effectively hiding the endpoints rather than exposing disabled functionality.

RP ID Resolution

The RP configuration is centralized in server/src/services/webauthnConfig.ts. TREK dynamically determines the RP ID by examining the APP_URL environment variable or falling back to an explicit WEBAUTHN_RPID setting. This configuration also defines the allowed origins, ensuring that credentials are scoped strictly to the deployed domain and preventing phishing attacks from unauthorized origins.

Cryptographic Ceremony Management

All WebAuthn protocol logic resides in server/src/services/passkeyService.ts, which orchestrates registration and authentication ceremonies using the @simplewebauthn/server library.

Challenge Lifecycle and Replay Protection

TREK stores cryptographic challenges in a dedicated webauthn_challenges table defined in server/src/db/migrations.ts. The implementation enforces strict security controls:

  • Time-bound: Challenges expire after 5 minutes.
  • Single-use: Upon verification, the service executes a DELETE … RETURNING query to atomically remove the challenge, making replay attacks impossible.
  • User-scoped: Challenges are associated with specific user IDs to prevent cross-user replay.

Registration Ceremonies

The registration flow consists of two distinct phases:

  1. Options Generation: The passkeyRegisterOptions method calls generateRegistrationOptions to create a challenge scoped to the user's ID. This includes the RP ID, user details, and cryptographic preference settings (e.g., resident key requirements for discoverable credentials).

  2. Attestation Verification: The passkeyRegisterVerify method processes the client's attestation response using verifyRegistrationResponse. Upon successful validation, the service extracts the credential's public key, credential ID, authenticator type, transports, and initial counter value, persisting them to the webauthn_credentials table.

Authentication and Counter Verification

The login flow supports discoverable credentials (passkeys) for passwordless authentication:

  1. Challenge Creation: passkeyLoginOptions invokes generateAuthenticationOptions to create a challenge that allows the browser to select any credential registered for the current RP ID.

  2. Assertion Verification: passkeyLoginVerify uses verifyAuthenticationResponse to validate the cryptographic signature. Critically, TREK implements counter verification to detect cloned authenticators: the service compares the stored counter value against the assertion's counter and rejects the request if the new value is less than or equal to the stored value.

  3. Counter Update: On successful verification, the stored counter is atomically updated to prevent future replay attempts using the same assertion.

HTTP Controller and Security Hardening

The PasskeyController in server/src/nest/auth/passkey.controller.ts exposes the WebAuthn functionality through REST endpoints, applying additional security layers.

Endpoint Structure

The controller routes requests to the service layer while enforcing authentication boundaries:

  • /api/auth/passkey/register/options – Requires existing session authentication and password re-confirmation to prevent account takeover during registration.
  • /api/auth/passkey/register/verify – Accepts the attestation response and credential name (e.g., "My Phone").
  • /api/auth/passkey/login/options – Public endpoint serving authentication challenges for passwordless login.
  • /api/auth/passkey/login/verify – Public endpoint verifying assertions and issuing sessions.
  • /api/auth/passkey/credentials – Authenticated endpoints for listing, renaming, or deleting a user's own passkeys.

Rate Limiting and Audit Logging

Every controller method is protected by RateLimitService to prevent brute-force attempts against challenge endpoints. Additionally, all successful and failed attempts are logged via writeAudit, creating a forensic trail of passkey registrations and logins alongside traditional authentication events.

Timing Attack Protection

To prevent timing analysis that could reveal whether a user has passkeys registered, the login endpoints implement constant-time padding. The LOGIN_MIN_LATENCY_MS constant (set to 350 ms) ensures that responses take at least this duration regardless of whether the credential lookup succeeds or fails, masking the difference between "user not found" and "invalid credential."

Session Integration

Upon successful WebAuthn verification, TREK does not create a separate token type. Instead, passkeyLoginVerify calls the existing generateToken function and server/src/services/cookie.ts to issue the same JWT session cookie used for password and OIDC authentications. This architectural decision ensures that:

  • Session management remains centralized and consistent.
  • Passkeys are treated as a first-class authentication method, not a secondary factor requiring additional steps.
  • Existing authorization logic (role checks, session expiry) functions identically regardless of authentication type.

Summary

  • Guarded Activation: The PasskeyEnabledGuard and webauthnConfig.ts ensure WebAuthn endpoints are only exposed when properly configured, preventing security misconfigurations.
  • Stateless Challenges: Single-use, expiring challenges in webauthn_challenges eliminate replay attack vectors.
  • Ceremony Orchestration: passkeyService.ts handles registration (generateRegistrationOptions/verifyRegistrationResponse) and login (generateAuthenticationOptions/verifyAuthenticationResponse) with mandatory counter verification to detect cloned devices.
  • Unified Sessions: Successful passkey authentication immediately mints standard JWT sessions via generateToken, integrating seamlessly with TREK's existing security model.
  • Hardened Delivery: Rate limiting, audit logging, and timing attack mitigation (350 ms padding) protect the endpoints from enumeration and brute-force attacks.

Frequently Asked Questions

How does TREK prevent replay attacks during WebAuthn ceremonies?

TREK stores challenges in a webauthn_challenges table with a 5-minute expiration. When a client submits a response, the service executes a DELETE … RETURNING SQL statement to atomically remove the challenge. This single-use design ensures that once a challenge is consumed for verification, it cannot be reused, effectively neutralizing replay attacks.

What session mechanism does TREK use after a successful passkey login?

After verifyAuthenticationResponse succeeds in passkeyService.ts, the service calls generateToken and sets the session cookie using the same cookie.ts utilities employed by password authentication. This means passkey users receive identical JWT session tokens to other authentication methods, maintaining a unified security boundary.

How does TREK detect cloned or compromised authenticators?

During passkeyLoginVerify, the service validates the authenticator's counter value against the stored counter in webauthn_credentials. If the assertion's counter is less than or equal to the stored value, TREK rejects the authentication attempt, as this indicates the credential may have been extracted and cloned onto another device.

Can administrators disable WebAuthn passkeys in TREK?

Yes. The PasskeyEnabledGuard in server/src/nest/auth/passkey-enabled.guard.ts checks an administrative feature flag before allowing access to any passkey endpoint. If the feature is disabled or the RP ID cannot be resolved from webauthnConfig.ts, the application returns a 404 response, effectively hiding the functionality without exposing error details.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →