passbolt/passbolt_api · warning · ForbiddenException
Only administrators can view reports.
Error message
Only administrators can view reports.
What it means
ReportsViewController::view() restricts the reports HTML/API endpoint to administrators. If the authenticated user's role is not Role::ADMIN, it throws Cake\Http\Exception\ForbiddenException with 'Only administrators can view reports.' This is an intentional authorization gate, not a bug.
Solutions
- Log in as (or use credentials of) an administrator before requesting the report.
- Check the user's role in the database (users.role_id -> roles.name) and promote to admin if they should have access.
- Catch Cake\Http\Exception\ForbiddenException (HTTP 403) in the client and show an access-denied message.
- If programmatic access is needed, use an admin service account rather than weakening the controller check.
Example fix
// client-side
try { await api.get('/reports/workspace.json'); }
catch (e) { if (e.response?.status === 403) showAccessDenied(); } Defensive patterns
Strategy: try-catch
Validate before calling
$role = $this->User->role(); if ($role !== Role::ADMIN) { /* do not call the endpoint, or show access denied UI */ } Try / catch
try { $res = $client->get('/reports/' . $slug); } catch (\Cake\Http\Exception\ForbiddenException $e) { /* HTTP 403: render access denied */ } Prevention
- Check the logged-in user role before linking to report pages
- Hide admin-only report links in the UI for non-admins
- Use an admin service account for automated report retrieval
- Verify role assignment (users.role_id) when users report missing access
When it happens
Trigger: Any authenticated non-admin user (or guest/anonymous request resolving to role 'guest') requests a report route handled by ReportsViewController::view(), e.g. GET /reports/<slug> while logged in as a regular user.
Common situations: A regular user bookmarking or sharing an admin-only report URL; role misconfiguration where a user expected to be an admin actually has role 'user'; testing the endpoint without admin credentials; proxies forwarding unauthenticated requests.
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 guests are allowed to proceed with account recovery.
- You are not authorized to access that location.
- Access restricted to administrators.
- Only admin can create or update subscription information.
- Only administrators are allowed to create/update MFA…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/cf0ace1af5d64ce2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Reports/src/Controller/Reports/ReportsViewController.php:66
* @throws \Exception
*/
public function initialize(): void
{
parent::initialize();
$this->reportViewService = new ReportViewService();
$this->Users = $this->fetchTable('Users');
}
/**
* @param string $reportSlug Slug of the report to retrieve
* @throws \Exception
* @throws \Cake\Http\Exception\BadRequestException If the requested report does not exist
* @return void
*/
public function view(string $reportSlug)
{
if ($this->User->role() !== Role::ADMIN) {
throw new ForbiddenException(__('Only administrators can view reports.'));
}
// Retrieve the report argument passed as url parameters.
$arguments = func_get_args();
$reportArguments = array_slice($arguments, 1);
try {
$report = $this->reportViewService->getReport($reportSlug, $reportArguments);
} catch (InvalidArgumentException $exception) {
throw new BadRequestException(__('The requested report `{0}` does not exist.', $reportSlug));
}
$options = $this->formatRequestData($report->getSupportedOptions());
$creator = $this->Users->get($this->User->id(), contain: ['Profiles']);
$report
->setOptions($options)View on GitHub (pinned to 31c1bbc10f)