1fa7144a7b873f354d6346e97f5043e5f75cef41
Release APK / build (push) Successful in 1m59s
- Approve now opens an in-app review screen showing app/user/IP/geo of the request (optional deep-link params: app, user, ip, geo, ts) before biometrics - Add a Deny button on the approval screen (no biometric needed to reject) - Reject requests older than 2 min via the ts param (replay safety net) - README: context params table, new Features bullets, approve-context screenshot - Bump to v1.2 (versionCode 3)
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
- You log in via Authentik. A flow step fires an ntfy notification to your phone with two action buttons: Approve and Deny.
- The buttons are
homemfa://approve?token=…/homemfa://deny?token=…deep links that open this app. - 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:<token>tontfy.khodak.me/mfa-approve; your Authentik flow is listening on that topic and completes the login. You can also Deny right from that screen. - Deny POSTs
deny:<token>tomfa-denyand 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_STRONGor 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
Install
- Download
homelab-mfa.apkfrom the latest release - On your Android phone: Settings → Apps → Install unknown apps → allow your browser/file manager
- Open the APK and tap Install
- 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 inMainActivity.kt) - An Authentik flow that, on login, publishes a notification with the two
homemfa://action buttons, then waits on themfa-approve/mfa-denytopics for the decision
Requirements
- Android 9.0+ (API 28)
- A fingerprint, face, or device PIN enrolled


