passbolt/passbolt_api · error · ForbiddenException
You are not authorized to access that location.
Error message
You are not authorized to access that location.
What it means
ForbiddenException thrown by DirectoryIgnoreController::toggle when the authenticated user's role is not Role::ADMIN. The ignore/un-ignore endpoint that controls which directory records are skipped during sync is admin-only; any non-admin (or unauthenticated) request is rejected with the standard CakePHP 'not authorized' message before the foreign model is even validated.
Solutions
- Authenticate as a user with the admin role, or grant the admin role to the account performing the operation.
- Check the auth token/cookie used by the client corresponds to the intended admin (inspect User->role() via /me.json).
- If this must be automated, run the equivalent server-side command (e.g. `passbolt directory_sync ignore-delete`) as a root/admin server operator instead of the HTTP endpoint.
- Ensure the session didn't expire and the role lookup isn't failing silently (re-login to refresh the identity).
Defensive patterns
Strategy: validation
Validate before calling
$me = $apiClient->get('/me.json');
if (($me['role']['name'] ?? null) !== 'admin') {
throw new RuntimeException('Directory ignore toggle requires an admin account');
} Type guard
function isAdmin(array $me): bool { return ($me['role']['name'] ?? '') === 'admin'; } Try / catch
try {
$apiClient->put('/directoryignore/' . $model . '/' . $id . '.json');
} catch (HttpException $e) {
if ($e->getCode() === 403) {
// switch to an admin-authenticated client or run server-side command
}
} Prevention
- Verify the authenticated user's role is admin before calling admin-only endpoints.
- Refresh sessions/tokens after role changes.
- For automation, prefer server-side cake commands over HTTP admin endpoints.
- Centralize auth-client construction so non-admin tokens aren't reused for admin calls.
When it happens
Trigger: Calling PUT/POST to the directory ignore toggle route (e.g. /directoryignore/<model>/<id>.json) while logged in as a non-admin user, or with missing/invalid authentication (User->role() not resolving to admin), or with a CSRF/auth token mismatch causing the identity to fall back to a lower role.
Common situations: UI automation or scripts run under a regular user account; stale session after the admin role was revoked; API token registered to a non-admin user; testing the endpoint unauthenticated.
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
- Only administrators can view reports.
- Access restricted to administrators.
- Directory sync settings endpoints are disabled.
- Only administrators are allowed to create/update MFA…
- Only administrators can add new users.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/accc2c1dcd3d9fc1.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/DirectorySync/src/Controller/DirectoryIgnoreController.php:63
$this->directoryOrgSettings = DirectoryOrgSettings::get();
$this->DirectoryIgnore = $this->fetchTable('Passbolt/DirectorySync.DirectoryIgnore');
}
/**
* Check if a record is ignored
*
* @param string $foreignModel foreign model
* @param string $foreignKey foreign key
* @throws \App\Error\Exception\ValidationException If the model name or id is not valid
* @throws \Cake\Http\Exception\ForbiddenException if the current user is not an admin
* @return void
*/
public function toggle(string $foreignModel, string $foreignKey): void
{
if ($this->User->role() !== Role::ADMIN) {
throw new ForbiddenException(__('You are not authorized to access that location.'));
}
$this->assertDirectoryEnabled();
$foreignModel = $this->normalizeForeignModel($foreignModel);
if (!Validation::inList($foreignModel, ['Groups', 'Users', 'DirectoryEntries'])) {
throw new BadRequestException(__('The record model is not valid.'));
}
$ignored = null;
try {
$ignored = $this->DirectoryIgnore->get($foreignKey);
$this->DirectoryIgnore->delete($ignored);
} catch (RecordNotFoundException $exception) {
}
$this->success(__('The record is currently ignored as part of directory synchronization.'), $ignored);
}
/**
* Check if a record is ignoredView on GitHub (pinned to 31c1bbc10f)