Auto-alojado - restablecer contraseña sin configuración SMTP

¡Hola!

Estoy ejecutando n8n en GCP CloudRun con PostgreSQL. Tenemos un par de instancias configuradas para diferentes necesidades.
En una de las instancias, el primer usuario se registró y se convirtió en propietario. Es el único propietario/administrador en esta instancia. Olvidó su contraseña y no puede recuperarla porque no tenemos SMTP configurado.

¿Cuál es la forma más fácil de restablecer una contraseña?

¿Es seguro cambiar el rol a global:admin directamente en la base de datos y luego registrar un nuevo propietario que pueda generar un enlace de restablecimiento de contraseña?

Hola @rgrzesk, mientras esperas una respuesta, aquí hay algunas cosas que podrían ayudarte:

Recursos sugeridos

Emparejado automáticamente con tu pregunta.

Documentación:

Foro:

@moosa, @gusgvd, @mechanizedgrowth - habéis ayudado con problemas similares antes, ¿podéis echar un vistazo?

Sugerido automáticamente por el bot de la comunidad de n8n. Es un piloto - comparte tu opinión aquí.

Hola @rgrzesk

Aquí hay una forma de restablecer usuarios.
Esto no eliminará ningún otro dato como flujos de trabajo o credenciales. Solo usuarios.

Hola @rgrzesk

Ya que estás en el ecosistema de GCP, puedes usar Cloud Shell para conectarte directamente a tu instancia de Cloud SQL y actualizar manualmente el hash de contraseña. Esto evita la necesidad de ejecutar n8n localmente o administrar claves de cifrado.

  1. Abre GCP Cloud Shell desde tu Google Cloud Console.
  2. Conéctate a tu instancia de Cloud SQL usando el siguiente comando:
gcloud sql connect [YOUR_INSTANCE_NAME] --user=postgres
  1. Genera un nuevo hash bcrypt. Ya que n8n usa bcrypt, no puedes simplemente escribir una contraseña en texto plano. Puedes usar esta línea de Python en tu Cloud Shell para generar un hash para tu contraseña deseada (por ejemplo, NewPassword123!):
python3 -c 'import bcrypt; print(bcrypt.hashpw(b"NewPassword123!", bcrypt.gensalt()).decode())'

Copia la cadena resultante (comienza con $2b$...).

  1. Ejecuta la actualización SQL. En el símbolo del sistema de PostgreSQL, ejecuta el siguiente comando. Nota: user es una palabra clave reservada en PostgreSQL, por lo que debe estar envuelta en comillas dobles.
UPDATE "user" 
SET "password" = '[PASTE_YOUR_HASH_HERE]' 
WHERE "email" = '[OWNER_EMAIL_ADDRESS]';
  1. Verifica y sal:
SELECT email FROM "user" WHERE email = '[OWNER_EMAIL_ADDRESS]';
\q
  1. Inicia sesión en n8n con la nueva contraseña.

¡Hola @rgrzesk! ¡Bienvenido!

Tu plan global:admin no funcionará — el asistente de configuración está protegido por la clave settings userManagement.isInstanceOwnerSetUp = true, no por si existe una fila global:owner, así que degradar al propietario te deja sin propietario y sin acceso a /setup. (global:admin también es un rol con licencia Enterprise.)

Ya que usas Postgres, simplemente sobrescribe el hash bcrypt del usuario. Una columna, nada más modificado, sin redeploy:

1. Genera el hash (n8n usa bcryptjs, costo 10):

docker run --rm node:20-alpine sh -c \
  "npm i bcryptjs --silent --prefix /tmp >/dev/null 2>&1 && \
   node -e \"console.log(require('/tmp/node_modules/bcryptjs').hashSync('YourNewPass1',10))\""

Usa una contraseña que cumpla las reglas de n8n (8–64 caracteres, 1 número, 1 mayúscula) o no podrás cambiarla en la UI después.

2. Conecta y actualiza:

UPDATE "user"
SET password = '$2b$10$...your hash...'
WHERE email = 'owner@yourdomain.com';

Dos cosas que confunden a la gente: user es una palabra reservada en Postgres y debe estar entre comillas dobles, y el hash debe estar entre comillas simples en tu shell o bash expandirá $2b/$10 y escribirá basura.

Si esa cuenta tenía MFA, también ejecuta SET "mfaEnabled" = false, "mfaSecret" = NULL, "mfaRecoveryCodes" = NULL.

3. Inicia sesión desde una ventana incógnita — n8n deriva parte del JWT de autenticación del hash de contraseña, así que las sesiones antiguas se invalidan y una cookie obsoleta te rechazará. No se necesita reiniciar el contenedor.

Evita n8n user-management:reset aquí: no puedes hacer docker exec en Cloud Run, y borra todas las cuentas de usuario y devuelve la instancia al asistente de configuración. Vale la pena agregar variables de entorno SMTP en tus servicios Cloud Run después para que esto no se repita en toda la flota.

Aquí usamos self-hosted en Railway. Para poder resolver, incluí variables directamente en los servicios Primary y Worker. Después hice el deploy y se resolvió.

image

He intentado (en mi instancia de prueba) cambiar otro usuario de global:owner a global:admin y funcionó. Después de ingresar a la instancia, volví a ver la pantalla /setup. Así que el truco funciona bien.
La pregunta es: ¿es seguro? ¿No se guardan/utilizan esos roles también en otros lugares?

Eso es lo que planeo hacer como solución sólida y a largo plazo :slight_smile: En este momento solo intento recuperar la instancia rápidamente sin implementaciones adicionales.

Tienes razón, fue culpa mía — n8n más nuevo decide si mostrar /setup basándose en si existe una fila global:owner, no en la clave de configuración que cité. Gracias por probarlo.

Sobre seguridad: hay tres columnas role diferentes, y son cosas separadas. user.role es el rol de instancia (el que cambiaste). project_relation.role y shared_workflow/shared_credentials.role manejan la membresía del proyecto y la propiedad de recursos — y están vinculados a projectId, no a userId. Así que nada de lo que hiciste afecta quién es dueño de qué flujo de trabajo o credencial. Esa parte está bien.

Lo único que cambiaría: usa global:member en lugar de global:admin. Admin es un tipo de cuenta Pro/Enterprise, así que en Community has asignado un usuario a un rol que la instancia no puede licenciar — y la interfaz tiende a desactivar roles sin licencia, por lo que quizás no puedas cambiarlo sin otro acceso a la BD. Member te da la misma pantalla de configuración sin ninguno de esos problemas.

Entonces: haz una copia de seguridad de la BD → establece el propietario anterior en global:member → registra un propietario temporal → Configuración → Usuarios → copia el enlace de restablecimiento de contraseña de la cuenta antigua (funciona bien sin SMTP) → restablece → devuelve los roles → elimina el usuario temporal. No dejes dos filas global:owner al mismo tiempo.

De cualquier forma, vale la pena poner N8N_EMAIL_MODE=smtp en todos tus servicios Cloud Run — con un propietario por instancia, esto volverá a ocurrir.

Hola @rgrzesk
A partir de n8n 2.17.0, el propietario de la instancia puede aprovisionarse desde variables de entorno, lo que restablece la contraseña sin tocar la base de datos en absoluto. Establécelas en el servicio Cloud Run, utilizando el correo electrónico del propietario existente:

N8N_INSTANCE_OWNER_MANAGED_BY_ENV=true
N8N_INSTANCE_OWNER_EMAIL=owner@yourdomain.com
N8N_INSTANCE_OWNER_FIRST_NAME=Firstname
N8N_INSTANCE_OWNER_LAST_NAME=Lastname
N8N_INSTANCE_OWNER_PASSWORD_HASH=<bcrypt hash>

n8n reaaplica estos valores a la cuenta del propietario existente en cada inicio, así que la revisión se activa con la contraseña ya cambiada. Mientras la bandera esté activada, ese usuario es de solo lectura en la interfaz de usuario y las escrituras de API para ellos se rechazan, así que una vez que estés dentro, establece N8N_INSTANCE_OWNER_MANAGED_BY_ENV=false, los valores que aplicó permanecen en su lugar y la interfaz de usuario se desbloquea nuevamente.
Cuesta una revisión, pero sin ediciones de roles y nada que deshacer en la BD después, que es la parte que se escala en el resto de tus instancias.