Back to Skills
    šŸ¦ž

    otp-challenger

    Enable agents and skills to challenge users for fresh

    By @ryancnelson
    View on GitHub
    SKILL.md
    ---
    name: otp-challenger
    version: 1.0.3
    description: Enable 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.
    metadata: {"openclaw": {"emoji": "šŸ”", "homepage": "https://github.com/ryancnelson/otp-challenger", "requires": {"bins": ["jq", "python3"], "anyBins": ["oathtool", "node"]}, "install": [{"id": "jq", "kind": "brew", "formula": "jq", "bins": ["jq"], "label": "Install jq via Homebrew", "os": ["darwin", "linux"]}, {"id": "python3", "kind": "brew", "formula": "python3", "bins": ["python3"], "label": "Install Python 3 via Homebrew", "os": ["darwin", "linux"]}, {"id": "oathtool", "kind": "brew", "formula": "oath-toolkit", "bins": ["oathtool"], "label": "Install OATH Toolkit via Homebrew", "os": ["darwin", "linux"]}]}}
    ---
    
    # OTP Identity Challenge Skill
    
    Challenge users for fresh two-factor authentication before sensitive actions.
    
    ## When to Use
    
    Require OTP verification before:
    - Deploy commands (`kubectl apply`, `terraform apply`)
    - Financial operations (transfers, payment approvals)
    - Data access (PII exports, customer data)
    - Admin operations (user modifications, permission changes)
    
    ## Scripts
    
    ### verify.sh
    
    Verify a user's OTP code and record verification state.
    
    ```bash
    ./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 OTP
    
    **Exit codes:**
    - `0` - Verification successful
    - `1` - Invalid code or rate limited
    - `2` - 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-status.sh
    
    Check if a user's verification is still valid.
    
    ```bash
    ./check-status.sh <user_id>
    ```
    
    **Exit codes:**
    - `0` - User has valid (non-expired) verification
    - `1` - User not verified or verification expired
    
    **Output:**
    ```
    āœ… Valid for 23 more hours
    āš ļø Expired 2 hours ago
    āŒ Never verified
    ```
    
    ### generate-secret.sh
    
    Generate a new TOTP secret with QR code (requires `qrencode` to be installed).
    
    ```bash
    ./generate-secret.sh <account_name>
    ```
    
    ## Usage Pattern
    
    ```bash
    #!/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
    ```
    
    ## Configuration
    
    **Required for TOTP:**
    - `OTP_SECRET` - Base32 TOTP secret
    
    **Required for YubiKey:**
    - `YUBIKEY_CLIENT_ID` - Yubico API client ID
    - `YUBIKEY_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`:
    
    ```yaml
    security:
      otp:
        secret: "BASE32_SECRET"
      yubikey:
        clientId: "12345"
        secretKey: "base64secret"
    ```
    
    ## Code Format Detection
    
    The script auto-detects code type:
    - **6 digits** (`123456`) → TOTP validation
    - **44 ModHex characters** (`cccccc...`) → YubiKey validation
    
    ModHex alphabet: `cbdefghijklnrtuv`
    
    ## State File
    
    Verification state stored in `memory/otp-state.json`. Contains only timestamps, no secrets.
    
    ## Human Documentation
    
    See **[README.md](./README.md)** for:
    - Installation instructions
    - Setup guides (TOTP and YubiKey)
    - Security considerations
    - Troubleshooting
    - Examples