Install
openclaw skills install otp-challengerEnable agents and skills to challenge users for fresh two-factor authentication proof (TOTP or YubiKey) before executing sensitive actions. Use this for identity verification in approval workflows - deploy commands, financial operations, data access, admin operations, and change control.
openclaw skills install otp-challengerChallenge users for fresh two-factor authentication before sensitive actions.
Require OTP verification before:
kubectl apply, terraform apply)Verify a user's OTP code and record verification state.
./verify.sh <user_id> <code>
Parameters:
user_id - Identifier for the user (e.g., email, username)code - Either 6-digit TOTP or 44-character YubiKey OTPExit codes:
0 - Verification successful1 - Invalid code or rate limited2 - Configuration error (missing secret, invalid format)Output on success:
✅ OTP verified for <user_id> (valid for 24 hours)
✅ YubiKey verified for <user_id> (valid for 24 hours)
Output on failure:
❌ Invalid OTP code
❌ Too many attempts. Try again in X minutes.
❌ Invalid code format. Expected 6-digit TOTP or 44-character YubiKey OTP.
Check if a user's verification is still valid.
./check-status.sh <user_id>
Exit codes:
0 - User has valid (non-expired) verification1 - User not verified or verification expiredOutput:
✅ Valid for 23 more hours
⚠️ Expired 2 hours ago
❌ Never verified
Generate a new TOTP secret with QR code (requires qrencode to be installed).
./generate-secret.sh <account_name>
#!/bin/bash
source ../otp/verify.sh
if ! verify_otp "$USER_ID" "$OTP_CODE"; then
echo "🔒 This action requires OTP verification"
exit 1
fi
# Proceed with sensitive action
Required for TOTP:
OTP_SECRET - Base32 TOTP secretRequired for YubiKey:
YUBIKEY_CLIENT_ID - Yubico API client IDYUBIKEY_SECRET_KEY - Yubico API secret key (base64)Optional:
OTP_INTERVAL_HOURS - Verification expiry (default: 24)OTP_MAX_FAILURES - Failed attempts before rate limiting (default: 3)OTP_STATE_FILE - State file path (default: memory/otp-state.json)Configuration can be set via environment variables or in ~/.openclaw/config.yaml:
security:
otp:
secret: "BASE32_SECRET"
yubikey:
clientId: "12345"
secretKey: "base64secret"
The script auto-detects code type:
123456) → TOTP validationcccccc...) → YubiKey validationModHex alphabet: cbdefghijklnrtuv
Verification state stored in memory/otp-state.json. Contains only timestamps, no secrets.
See README.md for: