passbolt/passbolt_api · error · ForbiddenException

You are not allowed to access this location.

Error message

You are not allowed to access this location.

What it means

EditionSubscriptionsDeleteController::delete obtains the caller's UserAccessControl and throws ForbiddenException if the caller is not an administrator. Only admins may downgrade the instance from PRO to CE by deleting the subscription.

Solutions

  1. Authenticate as, or use credentials of, an administrator account
  2. Grant the admin role to the account performing the operation
  3. Update automation/service accounts to use admin credentials for edition management

Example fix

// before
await apiAsUser.delete('/edition/subscriptions'); // 403
// after
const apiAsAdmin = createClient(adminCredentials);
await apiAsAdmin.delete('/edition/subscriptions');
Defensive patterns

Strategy: type-guard

Validate before calling

const uac = getUserAccessControl();
if (!uac.isAdmin()) { /* abort: operation requires admin */ }

Type guard

function isAdminUser(user: {role: {name: string}}): boolean { return user.role?.name === 'admin'; }

Try / catch

try {
  await api.delete('/edition/subscriptions');
} catch (e) {
  if (e.status === 403) { /* re-authenticate with admin credentials */ }
}

Prevention

When it happens

Trigger: Calling DELETE on the edition subscriptions endpoint while authenticated as a non-admin user.

Common situations: Operations run with a regular service or user account instead of an admin; revoked admin role; automation using wrong API credentials; logged-in user lacking the admin role after role changes.

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/b23fd7eba0fc2e85. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/Edition/src/Controller/EditionSubscriptionsDeleteController.php:37

use App\Controller\AppController;
use Cake\Http\Exception\ForbiddenException;
use Passbolt\Edition\Service\EditionDowngradeService;

/**
 * HTTP entry point for the in-product downgrade.
 */
class EditionSubscriptionsDeleteController extends AppController
{
    /**
     * @return void
     * @throws \Cake\Http\Exception\ForbiddenException When the caller is not admin.
     * @throws \Cake\Http\Exception\ConflictException When the instance is already on CE.
     */
    public function delete(): void
    {
        $uac = $this->User->getAccessControl();
        if (!$uac->isAdmin()) {
            throw new ForbiddenException(__('You are not allowed to access this location.'));
        }

        // Throws ConflictException(409) if already on CE.
        (new EditionDowngradeService())->downgrade($uac);

        $this->success(__('The instance was downgraded to CE.'));
    }
}

View on GitHub (pinned to 31c1bbc10f)