passbolt/passbolt_api · error · ForbiddenException
Only guests are allowed to proceed with account recovery.
Error message
Only guests are allowed to proceed with account recovery.
What it means
ForbiddenException thrown by AccountRecoveryContinueController::get() when a non-guest (authenticated) user attempts to proceed with account recovery. Only anonymous (GUEST role) users may start the recovery flow.
Solutions
- Log out (and clear the session cookie) before using the recovery link
- Open the recovery link in a private/incognito window or a different browser profile
- Verify SSO settings aren't silently re-authenticating the user
- For tests, ensure the fixture sets no authenticated session
Example fix
// before
$this->loginAs('ada@passbolt.test');
$this->get('/account-recovery/continue/...'); // 403
// after
$this->logout();
$this->get('/account-recovery/continue/...'); // 200 Defensive patterns
Strategy: try-catch
Validate before calling
const role = await selfClient.getOwnRole();
if (role !== 'guest') {
throw new Error('log out before starting account recovery');
} Try / catch
try {
await accountRecoveryContinueService.get(userId, tokenId);
} catch (ApiError e) {
if (e.status === 403 && e.message.includes('Only guests')) {
await logout();
retryRecoveryFlow();
}
} Prevention
- Clear session cookies before using recovery links
- Open recovery links in incognito/private windows when already logged in
- Check SSO auto-login settings that may re-authenticate users
- In tests, avoid attaching authenticated sessions to guest-only endpoints
When it happens
Trigger: A logged-in user (admin or user role) opens an account recovery continue link in the same browser session; SSO/cookie auto-login occurring before the recovery flow completes.
Common situations: User clicks a recovery link while already logged in; session cookie from another account persisting; testing recovery while authenticated.
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
- Only admin can create or update subscription information.
- Only administrators can view reports.
- Only guests are allowed to create an account recovery…
- You are not allowed to access this location.
- You are not authorized to access that location.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/a5d5455ced2049ae.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Controller/AccountRecoveryContinue/AccountRecoveryContinueController.php:72
* @return void
* @throws \Cake\Http\Exception\BadRequestException if the data provided is not valid
*/
public function get(
?string $userId,
?string $tokenId,
AccountRecoveryContinueAggregatorService $accountRecoveryContinueService
): void {
if (!isset($userId) || !Validation::uuid($userId)) {
throw new BadRequestException(__('The user id is invalid.'));
}
if (!isset($tokenId) || !Validation::uuid($tokenId)) {
throw new BadRequestException(__('The authentication token id is invalid.'));
}
if ($this->getRequest()->is('json')) {
// Do not allow logged in user to recover
if ($this->User->role() !== Role::GUEST) {
throw new ForbiddenException(__('Only guests are allowed to proceed with account recovery.'));
}
(new AccountRecoveryRequestGetService())->getOrFail($userId, $tokenId);
$data = $accountRecoveryContinueService->get();
$this->success(__('The operation was successful.'), $data);
} else {
$this->renderHtml();
}
}
/**
* @return void
*/
protected function renderHtml(): void
{
$this->viewBuilder()View on GitHub (pinned to 31c1bbc10f)