Device Unlock
How to unlock a locked kiosk device for maintenance.
Last updated: April 27, 2026
Accessing the Unlock Screen
The unlock screen is hidden to prevent accidental access:
- Long-press the bottom-left corner of the screen (200dp area) for 600ms
- Tap 6 times rapidly (anywhere in the bottom-left area) within 3 seconds
- The unlock screen appears as a fullscreen overlay
Method 1: NFC Unlock Card (Primary)
- Hold the technician's NFC unlock card near the device's NFC antenna
- The app reads the ECDSA-signed payload from the card
- Validates:
- Signature (ECDSA P-256 with SHA-256)
- Expiry timestamp (
expfield) - Scope must be
"unlock"
- On success: device exits Lock Task mode
Card Payload Structure
The NFC card contains 2 NDEF records:
- Record 0: JSON payload
- Record 1: Base64-encoded ECDSA signature over canonical JSON (sorted keys)
NDEF Record 0
json
{ "v": 1, "scope": "unlock", "exp": 1735689600, "iss": "...", "tid": "..." }Generating Unlock Cards
Unlock cards are generated via the technician dashboard:
- Open "Unlock Card" screen in the technician role
- Select expiry duration (default: 30 days)
- Tap "Generate" → hold an NTAG215/216 NFC tag to the phone
- Backend signs the payload with ECDSA private key
- App writes signed payload to the NFC tag
i
The public key is embedded in the kiosk APK at build time via
BuildConfig.UNLOCK_PUBLIC_KEY.Method 2: PIN Fallback
- On the unlock screen, tap "Use PIN instead"
- Enter the 6-digit PIN
- PIN is verified against a BCrypt hash stored in EncryptedSharedPreferences
The fallback PIN is set during device provisioning (generated server-side).
Anti-Brute-Force Protection
| Threshold | Action |
|---|---|
| 5 failed attempts within 10 minutes | 30-minute lockout |
| During lockout | All unlock attempts are rejected |
| After lockout expires | Counter resets |
!
Lockout state persists across reboots (stored in EncryptedSharedPreferences).
Audit Trail
Every unlock attempt (success or failure) is logged as a telemetry event to the backend:
| Event | Data |
|---|---|
| kiosk.unlocked | method (nfc_card/pin), technician_id (if NFC), timestamp |
| kiosk.unlock_attempt_failed | method, reason (invalid_signature/expired/wrong_pin/lockout) |
| kiosk.locked | trigger (boot/manual/post-update) |
This provides a full audit trail of who unlocked which device and when, visible in the fleet monitoring dashboard.
After Unlocking
Once unlocked, the device exits Lock Task mode. You can:
- Access Android Settings
- Install/uninstall apps
- Connect via ADB
- Re-provision the device
To re-lock, either:
- Reboot the device (auto-locks via BootReceiver)
- Or navigate back to the kiosk app (it auto-locks on resume)