Monday at 12:41 PM1 day GitHub: https://github.com/Nebur692/ha-login-approvalImage: ghcr.io/nebur692/ha-login-approval:latestTemplate: https://raw.githubusercontent.com/Nebur692/ha-login-approval/main/ha-login-approval.xml====================================================================ENGLISH====================================================================Support thread for the ha-login-approval Docker container.WHAT IT DOESIt turns your Home Assistant Companion App into your login method. You typeyour email, you get a push notification with Approve / Reject buttons, andtapping Approve logs you in. No password is involved at any point — this istrue passwordless sign-in, not a second factor bolted on in front of apassword.It works by acting as a generic external OIDC identity provider, so any relyingparty that supports "log in with an external OIDC provider" can redirect to it:ZITADEL, Keycloak, Authentik, or in principle any other standards-compliant one.FEATURES- Real passwordless login, confirmed end-to-end against a real ZITADEL instance.The provider itself is a standard OIDC implementation (authorize / token /JWKS / discovery), also tested against Keycloak's own external-IDP flow.- Its own small account directory (email -> assigned devices) in a self-containedSQLite file. It never calls any identity provider's admin API, so it behavesidentically no matter which one sits in front of it.- Multiple devices per account, discovered live from your own Home Assistant.- The bridge page speaks the browser's language (English or Spanish, from thestandard Accept-Language header — no configuration needed).- One-time recovery codes as an emergency fallback if the push never arrives oryou lose the phone. Shown once at generation time, stored only as hashes.- Anti-abuse: an explicit Reject or a wrong recovery code counts toward a3-strikes block, scoped to that one account + IP, never a global block. Asilent timeout does not count. A definitively failed login always redirectsback to your identity provider with a proper OIDC error response instead ofleaving the browser stuck on a dead page.- Optional GeoIP enrichment (self-hosted MaxMind GeoLite2, no third-party APIcall per login) adds city / country / ISP to the audit log and to the pushnotification itself.- Admin panel at http://[IP]:8000/admin — overview, account directory,per-account login history, recovery codes, blocked IPs and page branding.REQUIREMENTS- Home Assistant, with the Companion App installed on at least one device, anda long-lived access token that can call notify.* services and readmobile_app_notification_action events over the WebSocket.- An OIDC-capable identity provider (ZITADEL, Keycloak, Authentik...) where youregister this service as a generic external identity provider.- A reverse proxy with a valid TLS certificate (Nginx Proxy Manager, Traefik,Caddy, nginx...).THE ONE THING PEOPLE GET WRONGIDP_ISSUER_URL must be a PUBLIC https:// URL behind your reverse proxy — not alocal LAN IP. Both your identity provider's server-to-server calls and thebrowser of whoever is signing in need to reach it. Put a LAN address there andsign-in will only ever work from inside your own network.Also: don't skip the /data volume. It holds the SQLite database (accounts,recovery codes, audit log, IP blocks, branding) and the GeoIP files. Withoutit, everything resets whenever the container is recreated.The full step-by-step guide — registering the IDP on the ZITADEL / Keycloak /Authentik side, the admin panel, and every single environment variable — is inthe README linked above.Post here for questions, bug reports and feature requests. Bug reports withcontainer logs attached are especially welcome. GitHub issues work too:https://github.com/Nebur692/ha-login-approval/issuesIf you find it useful, you can support the project here:https://ko-fi.com/nebur69265723====================================================================ESPAÑOL====================================================================Hilo de soporte del contenedor Docker ha-login-approval.QUÉ HACEConvierte la aplicación Home Assistant Companion en tu método de acceso.Escribes tu correo, te llega una notificación push con botones Aprobar yRechazar, y al pulsar Aprobar entras. En ningún momento interviene unacontraseña: es acceso sin contraseña de verdad, no un segundo factor colocadodelante de una contraseña de toda la vida.Funciona actuando como proveedor de identidad OIDC externo y genérico, así quepuede redirigir hacia él cualquier servicio que admita «iniciar sesión con unproveedor OIDC externo»: ZITADEL, Keycloak, Authentik o, en principio,cualquier otro que cumpla el estándar.CARACTERÍSTICAS- Acceso sin contraseña real, comprobado de principio a fin contra unainstancia real de ZITADEL. El proveedor es una implementación OIDC estándar(authorize / token / JWKS / discovery), probada también contra el flujo deproveedor externo del propio Keycloak.- Directorio de cuentas propio (correo -> dispositivos asignados) en un ficheroSQLite autocontenido. Nunca llama a la API de administración de ningúnproveedor de identidad, así que se comporta igual sea cual sea el que tengadelante.- Varios dispositivos por cuenta, descubiertos en vivo desde tu propio HomeAssistant.- La página puente habla el idioma del navegador (español o inglés, detectadocon la cabecera estándar Accept-Language, sin configurar nada).- Códigos de recuperación de un solo uso como salida de emergencia si lanotificación no llega o pierdes el móvil. Se muestran una única vez algenerarlos y se guardan solo como hash irreversible.- Antiabuso: un Rechazar explícito o un código de recuperación equivocado sumanpara un bloqueo a las 3 veces, limitado a esa cuenta y esa IP, nunca unbloqueo global. Que se agote el tiempo sin responder no cuenta. Un accesofallido de forma definitiva siempre devuelve al proveedor de identidad con larespuesta de error que marca OIDC, en lugar de dejar el navegador plantado enuna página muerta.- Enriquecimiento GeoIP opcional (MaxMind GeoLite2 alojado en tu propioservidor, sin llamadas a terceros en cada acceso): añade ciudad, país yproveedor al registro de auditoría y a la propia notificación.- Panel de administración en http://[IP]:8000/admin: resumen, directorio decuentas, historial de accesos por cuenta, códigos de recuperación, IPbloqueadas y personalización de la página.REQUISITOS- Home Assistant, con la aplicación Companion instalada en al menos undispositivo, y un token de acceso de larga duración que pueda llamar a losservicios notify.* y leer los eventos mobile_app_notification_action porWebSocket.- Un proveedor de identidad compatible con OIDC (ZITADEL, Keycloak,Authentik...) donde des de alta este servicio como proveedor de identidadexterno genérico.- Un proxy inverso con certificado TLS válido (Nginx Proxy Manager, Traefik,Caddy, nginx...).LO QUE TODO EL MUNDO SE EQUIVOCAIDP_ISSUER_URL tiene que ser una URL https:// PÚBLICA detrás de tu proxyinverso, no una IP local. Tienen que llegar hasta ella tanto las llamadas deservidor a servidor de tu proveedor de identidad como el navegador de quienestá entrando. Si pones ahí una dirección de tu red local, solo se podrá entrardesde dentro de tu propia red.Y otra cosa: no te saltes el volumen /data. Ahí viven la base de datos SQLite(cuentas, códigos de recuperación, registro de auditoría, IP bloqueadas,personalización) y los ficheros de GeoIP. Sin ese volumen se pierde todo cadavez que se vuelve a crear el contenedor.La guía completa paso a paso —cómo dar de alta el proveedor en ZITADEL,Keycloak o Authentik, el panel de administración y todas y cada una de lasvariables— está en el README enlazado arriba.Escribe por aquí para dudas, fallos y peticiones de mejora. Los avisos de fallocon el log del contenedor adjunto se agradecen especialmente. También valen lasissues de GitHub:https://github.com/Nebur692/ha-login-approval/issuesSi te resulta útil, puedes apoyar el proyecto aquí:https://ko-fi.com/nebur69265723
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.