Skip to content

UC-006: Backup Keyholder (Conditional Access)

Actor: Backup Keyholder (trusted community member) Priority: Should Status: Implemented (protocol + firmware allow-list evaluation + TOTP keypad)

Summary

A backup keyholder can only unlock the door after receiving real-time approval from a designated guarantor (role >= 0x40). The guarantor shares their key-ID and TOTP code by phone, which the keyholder enters on the CONLAN M1200 keypad.

Preconditions

  • Backup keyholder is registered with access type CONDITIONAL
  • At least one guarantor (role >= 0x40) has a TOTP entry in the allow-list
  • ESP32 has network connectivity (for sending the notification; not required for TOTP verification)

Main Flow

  1. Backup keyholder scans NFC card at the terminal
  2. ESP32 finds entry: CONDITIONAL
  3. LED blinks blue to indicate "waiting for approval"
  4. ESP32 queues conditional access event (sent to backend on next sync, if network available)
  5. Keyholder calls a guarantor they know (phone number known from community)
  6. Keyholder explains the situation; guarantor decides whether to approve
  7. Guarantor opens authenticator app, reads the current TOTP code
  8. Guarantor tells the keyholder their key-ID and the 6-digit code
  9. Keyholder enters <guarantor_key_id>#<code># on the CONLAN M1200 keypad
  10. ESP32 looks up the guarantor's TOTP entry, verifies the code (wide window T-10 to T+1)
  11. Code valid — ESP32 grants access, sends unlock command to NUKI via BLE
  12. Green LED + confirmation beep

Alternative Flows

A1: Guarantor denies the request

  1. Keyholder calls a guarantor who decides not to approve
  2. Guarantor does not share a TOTP code
  3. Keyholder cannot enter a valid code — access remains denied

A2: Guarantor uses HOTP backup code

  1. Guarantor does not have an authenticator app available
  2. Guarantor reads an HOTP backup code from a printed list
  3. Keyholder types <guarantor_key_id>#<backup_code># on the keypad
  4. ESP32 verifies against the guarantor's indexed HOTP bitmap — access granted

A3: Network unavailable

  1. ESP32 has no network connectivity — conditional access event queued for next sync
  2. Keyholder calls the guarantor directly (same as main flow — phone is always the primary channel)
  3. Guarantor opens authenticator app, shares key-ID and TOTP code by phone
  4. Keyholder enters the code on the keypad — access granted
  5. Network unavailability does not block access (TOTP verification is local)

Error Flows

E1: Wrong code entered

  1. Keyholder enters an incorrect code on the keypad
  2. ESP32 rejects — red LED flash
  3. Keyholder can retry (up to 3 attempts before keypad lockout)

E2: Keypad locked out

  1. After 3 failed code entries within 5 minutes, keypad is locked (duration escalates)
  2. NFC card access still works during keypad lockout
  3. Lockout duration doubles with each subsequent lockout

Postconditions

  • Door unlocks only after valid guarantor TOTP/HOTP code entry (which implies human approval)
  • Access event logged with the guarantor's key-ID for audit trail
  • TOTP counter updated to prevent replay

Access Rule

  • Access type: CONDITIONAL
  • Time slots: None (can request at any time)
  • Notifications: NOTIFY_ON_USE (approval events always logged)
  • Grace period: N/A

Notes

  • The keyholder initiates contact — they call a guarantor they know. There is no intercom at the door.
  • Unlike the previous synchronous design (60-second HTTP long-poll), the TOTP approach works even without network connectivity — the keyholder just needs to reach a guarantor by phone.
  • No signing key on the backend is needed. See ADR-008.
  • TOTP secrets are per-user — the guarantor's key-ID identifies which secret to check. The event log records which guarantor authorized entry.
  • The guarantor code uses a wide acceptance window (T-10 to T+1 = 5 min back) to account for phone communication delay.
  • During the approval process, the ESP32 provides visual feedback (pulsing blue LED) but does not hold a network connection open.
  • Future: The backend could forward conditional access events to a messenger group channel as an additional notification (smart scheduling by day of week/month). This is secondary to the direct phone call flow.
  • TOTP/HOTP parameters are configurable in config.h — see UC-011 for the full list.