Tienes ocho servicios en casa y ocho contraseñas distintas, o peor, la misma repetida ocho veces. Pocket ID resuelve eso por la vía rápida: un proveedor de identidad que habla OpenID Connect y que solo acepta passkeys, sin base de datos de contraseñas que proteger. Este artículo cubre la instalación real con Docker Compose, por qué HTTPS no es opcional, cómo se conecta la primera aplicación y qué ocurre el día que pierdes el móvil. Todo lo que viene a continuación se ejecutó contra la versión 2.14.0.

Puntos clave

  • Pocket ID es un proveedor OpenID Connect y OAuth 2.0 escrito en Go, con SQLite por defecto y PostgreSQL opcional; la imagen que probamos pesa 28,8 MB.
  • No admite contraseñas. El único método de acceso normal es una passkey, y el respaldo es un código de un solo uso que emite un administrador.
  • HTTPS es un requisito del navegador, no un capricho del proyecto: WebAuthn exige contexto seguro y ata la credencial al dominio.
  • El primer administrador se crea en /setup, una ruta que está abierta hasta que existe la primera cuenta y devuelve 404 justo después.
  • La OpenID Foundation certificó Pocket ID v2.10.0 el 7 de julio de 2026 en tres perfiles, algo que ni Authelia ni la mayoría de alternativas caseras tienen.

Qué hace un proveedor OIDC y por qué el modo solo passkeys cambia las cuentas

Un proveedor OpenID Connect es el sitio donde vive la identidad de tus usuarios. Tus aplicaciones dejan de tener usuarios propios: cuando alguien entra en Grafana o en Immich, la aplicación lo manda al proveedor, el proveedor comprueba quién es y devuelve un token firmado con el identificador, el correo y los grupos. La aplicación se fía de esa firma y ya está. Un alta, una baja, un sitio.

Lo que hace distinto a Pocket ID es que ese proveedor no guarda contraseñas. Ninguna. Una passkey es un par de claves: la privada nunca sale de tu teléfono, tu portátil o tu llave física, y el servidor solo almacena la parte pública. Si alguien roba la base de datos de Pocket ID no se lleva nada que pueda reproducir en otro sitio, porque ahí no hay secretos de usuario que robar. Y el ataque de suplantación deja de funcionar: como explica la documentación de MDN, "An attacker who creates a fake login website can’t login as the user because the signature changes with the origin of the website".

Los propios autores del proyecto explican por qué existiendo Keycloak decidieron escribir otro más: "There are other self-hosted OIDC providers like Keycloak or ORY Hydra but they are often too complex for simple use cases". Es una declaración de intenciones bastante honesta.

Por qué Pocket ID no arranca de verdad sin HTTPS

Esta es la parte que más gente se salta y la que después genera el mensaje de error incomprensible. La documentación de instalación lo dice sin adornos: "Pocket ID requires a secure context, meaning it must be served over HTTPS. This is necessary because Pocket ID uses the WebAuthn API".

La restricción no la impone Pocket ID, la impone el navegador. La especificación WebAuthn de la W3C define el identificador de la parte confiante, el RP ID, como el dominio para el que se registró la credencial, y añade una frase que conviene leer despacio: "A public key credential can only be used for authentication with the same entity (as identified by RP ID) it was registered with". El RP ID sale del dominio efectivo del origen y el esquema tiene que ser https, con una única excepción: el anfitrión localhost sobre http. Por eso puedes desplegar Pocket ID en tu propio equipo con APP_URL=http://localhost:1411 y registrar una passkey de verdad para probar, y por eso en cuanto le pones un nombre de dominio necesitas certificado.

De ahí salen tres consecuencias prácticas para el proxy inverso:

  • El certificado tiene que ser válido para el navegador. Un certificado autofirmado que el sistema no reconoce sirve para servir la página, pero el registro de la passkey falla.
  • El dominio que pongas en APP_URL es el que queda grabado en cada credencial. Si mañana mueves Pocket ID de id.midominio.es a sso.midominio.es, las passkeys registradas dejan de valer ahí y todo el mundo vuelve a empezar. Elige el nombre una vez y no lo toques.
  • Si el proxy termina el TLS, hay que decirle a Pocket ID que se fíe de él con TRUST_PROXY, porque de lo contrario el registro de auditoría y el limitador de peticiones ven la dirección IP del proxy en lugar de la del usuario. El valor por defecto es false y admite una lista de direcciones o rangos CIDR.

Si todavía no tienes esa capa montada, el camino corto es poner Traefik delante con Docker Compose y dejar que gestione los certificados.

Instalar Pocket ID con Docker Compose

El proyecto publica el fichero de composición y el de entorno, así que la instalación consiste en descargarlos y ajustar dos variables. Estos son los pasos reales:

  1. Descarga el fichero docker-compose.yml y el .env.example del repositorio y renombra el segundo a .env.
  2. Escribe en APP_URL la dirección pública completa, con https:// incluido.
  3. Copia en ENCRYPTION_KEY la clave que devuelve openssl rand -base64 32.
  4. Configura TRUST_PROXY si vas a servir el servicio detrás de un proxy inverso.
  5. Arranca el contenedor con docker compose up -d y comprueba el registro.

El fichero de composición del proyecto es exactamente este:

services:
  pocket-id:
    image: pocketid/pocket-id:v2 # or ghcr.io/pocket-id/pocket-id:v2
    restart: unless-stopped
    env_file: .env
    ports:
      - 1411:1411
    volumes:
      - "./data:/app/data"
    # Optional healthcheck
    healthcheck:
      test: [ "CMD", "/app/pocket-id", "healthcheck" ]
      interval: 1m30s
      timeout: 5s
      retries: 2
      start_period: 10s

Y el fichero de entorno mínimo, con las variables que la documentación marca como recomendables de revisar:

APP_URL=https://id.midominio.es
ENCRYPTION_KEY=  # openssl rand -base64 32
TRUST_PROXY=false
MAXMIND_LICENSE_KEY=
PUID=1000
PGID=1000

ENCRYPTION_KEY cifra los datos sensibles, incluidas las claves privadas de firma de tokens, y necesita al menos 16 bytes. Si prefieres no meterla en el entorno, existe ENCRYPTION_KEY_FILE apuntando a un fichero montado, compatible con los secretos de Docker. Cuidado con un detalle que la documentación resalta: el fichero se trata como binario, así que un salto de línea al final forma parte de la clave.

Del resto de variables, las que importan de entrada son pocas. PORT vale 1411, HOST escucha en 0.0.0.0, DB_CONNECTION_STRING apunta a data/pocket-id.db y basta con cambiarlo por una cadena postgres://usuario:clave@servidor:5432/pocketid para pasarse a PostgreSQL. AUDIT_LOG_RETENTION_DAYS conserva 90 días de auditoría y SESSION_DURATION mantiene la sesión 60 minutos.

En la prueba que hicimos para este artículo el contenedor pasó a estado saludable en unos nueve segundos, con la línea AppConfig actor created app=pocket-id version=2.14.0 en el registro, y el directorio data ocupaba 3,9 MB recién arrancado. Con eso ya responden /.well-known/openid-configuration y, desde la versión 2.14.0, también /.well-known/oauth-authorization-server.

Crear el primer administrador y registrar la passkey

Con el servicio arriba, la primera cuenta se crea entrando en https://tu-dominio/setup. No hay usuario por defecto ni contraseña inicial: rellenas nombre de usuario y correo, y la cuenta que sale es administradora.

Merece la pena entender cómo se cierra esa puerta, porque no es un enlace de un solo uso como en otros proyectos. Pocket ID consulta si la tabla de usuarios está vacía: mientras lo esté, /setup responde y cualquiera que llegue puede reclamar la instalación. Lo verificamos con dos llamadas seguidas: antes de crear nada, la ruta contestaba 204; medio segundo después de dar de alta al administrador, 404.

Así que publica Pocket ID y entra tú a crear la cuenta antes de anunciar el dominio a nadie. Si el servicio queda expuesto sin administrador durante una tarde, el primero que pase se queda con tu proveedor de identidad.

Justo después, la interfaz pide registrar la passkey. Registra dos desde el principio: la del dispositivo que usas a diario y una de respaldo, sea una llave física o el gestor de contraseñas de otro equipo.

Conectar una aplicación real como cliente OIDC

La documentación de Pocket ID incluye 96 guías de integración concretas, desde Immich y Grafana hasta Proxmox, Gitea o Vaultwarden. Tomemos Beszel, el monitor ligero que ya cubrimos aquí, porque el flujo es representativo.

En Pocket ID creas un cliente OIDC nuevo con el nombre que quieras y pones como URL de retorno https://tu-beszel/api/oauth2-redirect. Al guardarlo obtienes el identificador de cliente, el secreto y las tres direcciones que la aplicación va a necesitar: autorización, token e información de usuario. Además hay que activar Emails Verified en la configuración de la aplicación, porque Beszel se niega a crear usuarios si el proveedor no devuelve un correo verificado y falla con un "email": "cannot be blank" bastante críptico.

Pantalla Manage OIDC Clients del panel de administración de Pocket ID con el cliente beszel recién creado y las columnas de grupos permitidos, restricción, tipo y reautenticación.

En el lado de Beszel, la parte de administración de PocketBase permite editar la colección de usuarios y añadir un proveedor oidc con esos mismos valores, dejando PKCE activado. Después, DISABLE_PASSWORD_AUTH=true quita el formulario clásico y USER_CREATION=true permite que los usuarios nuevos se creen solos al entrar por primera vez.

Un cliente recién creado en nuestra instancia se quedó con 60 minutos de vigencia para el token de acceso y 43.200 minutos, es decir treinta días, para el de refresco. Aquí encontramos una discrepancia que merece la pena conocer: el formulario de la interfaz marca los clientes nuevos como restringidos por grupo, mientras que un cliente creado por la API llega con isGroupRestricted a falso, o sea sin restricción alguna. Mira la columna Restricted después de crear el cliente en lugar de dar por hecho el valor.

Sincronizar usuarios con LDAP y repartir permisos por grupos

Si ya tienes un directorio, Pocket ID lo consume en lugar de duplicarlo. Admite lldap, OpenLDAP y Active Directory, y sincroniza al arrancar el servicio y cada hora una vez activada la opción desde la interfaz web. Los usuarios y grupos que llegan del directorio quedan en modo lectura dentro de Pocket ID, que es lo razonable si la fuente de la verdad está fuera.

La configuración se hace por interfaz o por variables de entorno, con los campos habituales: dirección ldaps:// con su puerto, DN de conexión, base de búsqueda, filtros de usuarios y de grupos, y el mapeo de atributos. El que suele olvidarse es el nombre del grupo de administradores, porque de él depende quién puede tocar la configuración. Si arrancas ya con LDAP, necesitas al menos un usuario dentro de ese grupo antes de nada.

Los grupos sirven además para algo más fino: cada cliente OIDC puede quedar restringido a uno o varios grupos, de modo que el token solo se emite a quien pertenece a ellos. Es la forma de que el panel de administración lo vean dos personas y el servidor de fotos lo vea toda la familia, con el mismo proveedor.

Qué pasa si pierdes el dispositivo con la passkey

Es la primera pregunta que hace todo el mundo, y tiene respuesta concreta. Un administrador genera un código de acceso de un solo uso, y ese código sirve tanto para entrar una vez como para registrar una passkey nueva. Desde la interfaz está en la pestaña de usuarios, en el menú de tres puntos. Desde el servidor:

docker compose exec pocket-id /app/pocket-id one-time-access-token <usuario o correo>

La orden devuelve una dirección del tipo https://tu-dominio/lc/XraXjQDPwdSc y avisa de que el código vale una hora. La documentación insiste en enviarlo solo a la persona a la que pertenece y con caducidad corta, y con razón: durante esa hora es equivalente a la cuenta.

Existen otras dos salidas. La primera es el acceso desde otro dispositivo mediante código QR, pensada para cuando estás en un ordenador que no tiene tu passkey; la petición caduca a los cinco minutos y la pantalla de aprobación muestra ubicación y dispositivo. La segunda es el código por correo, que exige SMTP y que la documentación marca con una advertencia explícita: quien acceda al buzón accede a la cuenta.

Queda el caso extremo, el administrador único que pierde su único dispositivo. Ahí no hay magia: nadie puede emitirte un código porque el único que podía eras tú. Por eso conviene registrar dos passkeys y crear una segunda cuenta administradora antes de que el sistema empiece a importar.

Cuándo Pocket ID no es la herramienta

Pocket ID es deliberadamente pequeño. No habla SAML, no ejerce de servidor LDAP, no tiene motor de flujos de autenticación ni políticas condicionales, y no ofrece contraseña como alternativa. Si necesitas cualquiera de esas cosas, Authentik cubre ese terreno a cambio de arrastrar Python, PostgreSQL, Redis y un proceso trabajador. Authelia juega en otra liga distinta, la de la autenticación delegada en el proxy. Hemos comparado las tres opciones con detalle en Pocket ID frente a Authelia y Authentik.

A cambio, el trato de Pocket ID es difícil de igualar para una casa o un equipo pequeño: un contenedor de 28,8 MB, un puerto, un fichero de entorno y la certificación de la OpenID Foundation en tres perfiles desde el 7 de julio de 2026. Con 9.057 estrellas en GitHub y licencia BSD de dos cláusulas, tampoco es un experimento de fin de semana.

Preguntas frecuentes

¿Puedo instalar Pocket ID sin dominio propio ni certificado?

Solo para probar, y únicamente en http://localhost. Es la excepción que contempla la especificación WebAuthn. En cuanto accedas por dirección IP o por un nombre de dominio sin certificado válido, el registro de la passkey falla en el navegador antes de llegar al servidor.

¿Qué ocurre si cambio el dominio de Pocket ID después de instalarlo?

Las passkeys ya registradas dejan de servir en el dominio nuevo, porque están atadas al identificador de la parte confiante, que sale del dominio anterior. Cada usuario tendrá que registrar de nuevo su credencial, así que el cambio hay que planificarlo con códigos de acceso preparados.

¿Necesito PostgreSQL para usar Pocket ID en serio?

No para un homelab. Por defecto usa SQLite en data/pocket-id.db y aguanta decenas de usuarios sin despeinarse. PostgreSQL tiene sentido si ya tienes un servidor consolidado o si quieres varias réplicas; basta cambiar DB_CONNECTION_STRING.

Conclusión

Instalar Pocket ID es un contenedor, un puerto y dos variables de entorno, y en menos de diez minutos tienes un proveedor de identidad certificado delante de tus servicios. Lo que hay que decidir antes son dos cosas: el dominio definitivo, porque ata todas las passkeys que se registren después, y el plan de recuperación, porque un sistema sin contraseñas también es un sistema sin la red de seguridad a la que estamos acostumbrados. Resueltas esas dos, ya puedes ir apagando formularios de acceso por toda la casa. La versión en inglés de este artículo está en How to install Pocket ID for passkey SSO.

Fuentes

  1. Pocket ID, guía de instalación oficial
  2. pocket-id/pocket-id, repositorio del proyecto
  3. W3C, Web Authentication Level 3
  4. MDN, Web Authentication API
  5. OpenID Foundation, proveedores certificados