passbolt/passbolt_api · error · Cake\Http\Exception\ForbiddenException

Only guests are allowed to start setup.

Error message

Only guests are allowed to start setup.

What it means

Thrown by SetupStartController::start when a JSON API request to begin an account setup arrives from an authenticated user whose role is not GUEST. The setup flow (recover or complete) is reserved for guests — users who have not finished registration. Any other role (admin, user) is refused before the setup start service is invoked.

Solutions

  1. Log out (or use a private/incognito window) before opening the setup link so the request carries no non-guest session.
  2. If an admin must trigger setup for a user, have the user open the link in their own unauthenticated session.
  3. If you control the client, strip the session/auth header for this request.

Example fix

// before (admin session cookie sent with request)
fetch('/setup/start/' + userId + '/' + token, { credentials: 'include' });
// after
fetch('/setup/start/' + userId + '/' + token, { credentials: 'omit' }); // or use an incognito session
Defensive patterns

Strategy: validation

Validate before calling

// ensure no privileged session is attached before starting setup
if (session?.role && session.role !== 'guest') {
  throw new Error('Logout required: setup can only be started by guests');
}

Type guard

function isGuest(session) { return typeof session?.role === 'string' && session.role === 'guest'; }

Try / catch

try { await startSetup(userId, token); } catch (e) { if (e.status === 403 && /Only guests/.test(e.message)) { logout(); retryInIncognito(); } else throw e; }

Prevention

When it happens

Trigger: Calling GET/POST /setup/start/<userId>/<token> while authenticated as an ADMIN or USER role, e.g. an admin testing the setup link in the same browser session as their logged-in account.

Common situations: Admin clicks a user's setup invitation link while logged in; QA replaying setup URLs with an authenticated session cookie; a user trying to recover their own account using the guest-only setup endpoint.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/63700cfe42ac0078. Report an issue: GitHub.

Appendix: source

Thrown at src/Controller/Setup/SetupStartController.php:57

        parent::beforeFilter($event);
    }

    /**
     * Setup start
     *
     * @param \App\Service\Setup\AbstractSetupStartService $infoService info service
     * @param string $userId uuid of the user
     * @param string $token uuid of the token
     * @return void
     * @throws \Cake\Http\Exception\BadRequestException if the token is missing or not a uuid
     * @throws \Cake\Http\Exception\BadRequestException if the user id is missing or not a uuid
     */
    public function start(AbstractSetupStartService $infoService, string $userId, string $token): void
    {
        if ($this->request->is('json')) {
            // Do not allow logged in user to start setup
            if ($this->User->role() !== Role::GUEST) {
                throw new ForbiddenException(__('Only guests are allowed to start setup.'));
            }
            $data = $infoService->getInfo($userId, $token);
            $this->success(__('The operation was successful.'), $data);
        } else {
            $this->set('title', Configure::read('passbolt.meta.description'));
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)