# Homelab MFA Biometric push-approval for your homelab logins. When you sign in through Authentik, your phone buzzes — approve with a fingerprint, or deny with one tap. A self-hosted alternative to Duo / Authy push, with **no third-party cloud** in the loop. ## How it works 1. You log in via **Authentik**. A flow step fires an **ntfy** notification to your phone with two action buttons: **Approve** and **Deny**. 2. The buttons are `homemfa://approve?token=…` / `homemfa://deny?token=…` deep links that open this app. 3. **Approve** opens an in-app review screen showing *who is asking* (see context params below), then triggers a biometric prompt (fingerprint / face / device PIN). On success the app POSTs `approve:` to `ntfy.khodak.me/mfa-approve`; your Authentik flow is listening on that topic and completes the login. You can also **Deny** right from that screen. 4. **Deny** POSTs `deny:` to `mfa-deny` and blocks the login — no biometric needed to reject. ### Optional context params The approve link may carry extra query params so you can see what you're approving before you do: | Param | Shown as | Example | |--------|---------------------|------------------------| | `app` | 🖥 application name | `app=Grafana` | | `user` | 👤 username | `user=amir` | | `ip` | 📍 source IP | `ip=203.0.113.44` | | `geo` | appended to the IP | `geo=Berlin, DE` | | `ts` | request timestamp (epoch ms) — used to **expire** stale prompts after 2 min | `ts=1750000000000` | All are optional and URL-encoded; with none present the app just shows a plain Approve / Deny prompt. The activity is `showWhenLocked` + `turnScreenOn`, so an approval works straight from the lock screen. ## Features - **Biometric gate** — `BIOMETRIC_STRONG` or device credential required to approve (deny is instant) - **Login context** — see the app, user, source IP and geo of the request before approving - **One-tap Deny** — reject a suspicious login straight from the approval screen, no biometric needed - **Stale-request expiry** — prompts older than 2 minutes can't be approved (replay safety net) - **Lock-screen ready** — wakes the screen and shows over the keyguard - **Self-hosted** — talks only to your own ntfy instance; no Firebase, no vendor cloud - **Zero stored secrets** — stateless; each request carries a one-time token - **Setup self-check** — a "Test Biometric" button confirms enrollment before you rely on it ## Screenshots

Setup / ready screen   Approval prompt with login context   Login approved

## Install 1. Download `homelab-mfa.apk` from the [latest release](../../releases/latest) 2. On your Android phone: **Settings → Apps → Install unknown apps** → allow your browser/file manager 3. Open the APK and tap Install 4. Open **Homelab MFA** and tap **Test Biometric** to confirm your fingerprint is enrolled ## Server side You need: - An **ntfy** instance reachable at `ntfy.khodak.me` (or change the host in `MainActivity.kt`) - An **Authentik** flow that, on login, publishes a notification with the two `homemfa://` action buttons, then waits on the `mfa-approve` / `mfa-deny` topics for the decision ## Requirements - Android 9.0+ (API 28) - A fingerprint, face, or device PIN enrolled