Radiator Server Documentation — v10.33.3

yubikey

YubiKey OTP offline authentication action

Table of Contents
  • yubikey
  • Basic Syntax
  • Parameters
  • secret
  • range
  • Backend Mapping
  • Replay Protection
  • Related

yubikey

Validates a Yubico OTP presented as a RADIUS PAP response by decrypting it locally using the AES-128 key stored in yubikey.secret. No network call is made; validation is fully offline.

This action is only for offline validation. If you use the yubikey HTTP backend for cloud validation, configure secret on the backend block instead of this action.

The action extracts the public UID from the token identifier prefix and the 32-character modhex ciphertext, decrypts the OTP, and verifies the CRC16 checksum, private UID, and replay-protection counters.

Basic Syntax

YubiKey OTP is typically used as a second factor alongside a static password. The user enters their password and OTP concatenated in the PAP password field (<password><otp>). Use secret together with the yubikey() filter to extract the right portion of the field for each action:

@execute {
    backend {
        name "USERS";
        query "FIND_USER";
    }

    # Validate the static password portion that sits before the OTP
    pap {
      secret radius.request.password | yubikey(password-otp, password);
    }

    # Validate the YubiKey OTP portion
    yubikey {
      secret radius.request.password | yubikey(password-otp, otp);
    }
}

These examples omit the counter update step for brevity. See Replay Protection for the complete pattern including counter persistence.

For OTP-only authentication (single factor — possession only), omit secret:

yubikey;

Parameters

secret

Expression that produces the OTP value the action will validate. Use it together with the yubikey() filter to extract the OTP from a combined <password><otp> PAP field, or with any other expression that yields a Yubico OTP string.

When secret is set, its value replaces the protocol PAP response that the action would otherwise read. This is the recommended way to point the action at the right value.

range

Slices the PAP response by character offsets before passing it to the OTP validator. Prefer secret with the yubikey() filter for new configurations; range is limited to a single contiguous slice and remains supported mainly for backward compatibility.

Syntax: range <start> <end> [exclusive]

  • <start> - Starting index (negative values count from end)
  • <end> - Ending index (negative values count from end)
  • exclusive - Optional keyword to invert the range and keep everything except the specified slice
  • Indices are 0-based
# Validate only the trailing 44 characters as the YubiKey OTP
yubikey {
    range -44 0;
}

A standard Yubico OTP is 44 characters (12-character modhex public UID + 32-character ciphertext).

Backend Mapping

The backend must populate yubikey context variables before the yubikey action runs. At minimum, yubikey.secret (the AES-128 key) is required. Optional variables enable public/private UID checks and replay detection.

For a complete backend schema, query examples, and counter update configuration, see Offline Validation Configuration in the YubiKey Authentication article.

Replay Protection

When yubikey.counter is set, the action compares the decrypted usage counter against the stored value:

  • Counter is lower than stored: rejected as replayed OTP.
  • Counter equals stored: session counter is compared; lower value is rejected.
  • Counter is higher than stored: accepted; both counters are updated in the context.

Persist the updated counters after successful authentication to prevent replay on the next request. See Offline Validation Configuration for the complete pipeline pattern.

Navigation
  • accept

  • append

  • assert

  • backend

  • challenge

  • chap

  • conditions

  • copy

  • count

  • debug

  • discard

  • EAP

  • error

  • filter

  • hotp

  • http-basic-auth

  • if

  • ignore

  • invoke

  • log

  • map

  • message

  • modify

  • mschap

  • mschapv2

  • must

  • pap

  • reason

  • reject

  • reject_errors

  • replace

  • reply

  • rewrite

  • set

  • sleep

  • sometimes

  • stop

  • totp

  • trace

  • try

  • until

  • yubikey

Related
  • pap
  • articles/yubikey-context-variables
  • special