Hi @rgrzesk Welcome!
Your global:admin plan won’t work — the setup wizard is gated on the settings key userManagement.isInstanceOwnerSetUp = true, not on whether a global:owner row exists, so demoting the owner leaves you with no owner and still no /setup. (global:admin is also an Enterprise-licensed role.)
Since you’re on Postgres, just overwrite that user’s bcrypt hash. One column, nothing else touched, no redeploy:
1. Generate the hash (n8n uses bcryptjs, cost 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))\""
Use a password that meets n8n’s rules (8–64 chars, 1 number, 1 uppercase) or you won’t be able to change it in the UI later.
2. Connect and update:
UPDATE "user"
SET password = '$2b$10$...your hash...'
WHERE email = 'owner@yourdomain.com';
Two things that trip people up: user is a reserved word in Postgres and must be double-quoted, and the hash must be in single quotes in your shell or bash will expand $2b/$10 and write garbage.
If that account had MFA on, also SET "mfaEnabled" = false, "mfaSecret" = NULL, "mfaRecoveryCodes" = NULL.
3. Log in from an incognito window — n8n derives part of the auth JWT from the password hash, so old sessions are invalidated and a stale cookie will bounce you. No container restart needed.
Avoid n8n user-management:reset here: you can’t docker exec into Cloud Run, and it wipes all user accounts and returns the instance to the setup wizard. Worth adding SMTP env vars on your Cloud Run services afterwards so this doesn’t recur across the fleet.