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

  1. Log in as (or use credentials of) an administrator before requesting the report.
  2. Check the user's role in the database (users.role_id -> roles.name) and promote to admin if they should have access.
  3. Catch Cake\Http\Exception\ForbiddenException (HTTP 403) in the client and show an access-denied message.
  4. 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

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


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)