passbolt/passbolt_api · error · ForbiddenException

Only guests are allowed to create an account recovery…

Error message

Only guests are allowed to create an account recovery request.

What it means

Role guard in the account recovery request create action: although the action is unauthenticated, only users with the GUEST role (logged-out users with a valid recovery token context) may file a recovery request; any logged-in role gets a 403.

Solutions

  1. Log out and clear session cookies before initiating recovery
  2. Send the request without authentication credentials (no Authorization header/cookie)
  3. Open recovery flow in a private window for manual testing
  4. In tests, do not attach an authenticated session to the create call

Example fix

// before
$this->authenticateAs('ada');
$this->post('/account-recovery/requests.json', $data); // 403
// after
$this->post('/account-recovery/requests.json', $data); // guest request, 200
Defensive patterns

Strategy: try-catch

Validate before calling

const auth = getStoredAuth();
if (auth && auth.role !== 'guest') {
  await logout(); // recovery requests require guest role
}

Try / catch

try {
  await accountRecoveryRequestService.create(payload);
} catch (ApiError e) {
  if (e.status === 403 && e.message.includes('Only guests')) {
    await logout();
    retryCreate();
  }
}

Prevention

When it happens

Trigger: POST /account-recovery/requests.json while logged in as admin or user role; auto-login/SSO session present when creating the request.

Common situations: Recovering an account while still logged in with another account; leftover session cookie; test suite authenticating the request unintentionally.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryRequests/AccountRecoveryRequestsCreateController.php:52

     */
    public function beforeFilter(EventInterface $event)
    {
        $this->Authentication->allowUnauthenticated(['create']);

        parent::beforeFilter($event);
    }

    /**
     * Creates an account recovery request
     * Sends an email to the requesting user and the admins on success
     *
     * @return void
     * @throws \Cake\Http\Exception\BadRequestException if the data provided is not valid
     */
    public function create(): void
    {
        if ($this->User->role() !== Role::GUEST) {
            throw new ForbiddenException(__('Only guests are allowed to create an account recovery request.'));
        }

        $data = $this->getRequest()->getData();
        if (!isset($data) || !is_array($data) || empty($data)) {
            throw new BadRequestException(__('Invalid request. Please provide the required data.'));
        }

        $request = (new AccountRecoveryRequestCreateService())->create($data);

        $this->success(__('The operation was successful.'), $request);
    }
}

View on GitHub (pinned to 31c1bbc10f)