passbolt/passbolt_api · error · ForbiddenException

Only administrators can view the subscription details.

Error message

Only administrators can view the subscription details.

What it means

The Passbolt subscription plugin restricts viewing subscription key details to administrators. SubscriptionKeyGetService::get() checks UserAccessControl::isAdmin() before reading the key and throws ForbiddenException when the caller is not an admin. This protects sensitive license data from regular users.

Solutions

  1. Authenticate with (or elevate to) an administrator account
  2. Re-issue API credentials for a user with the admin role
  3. Skip this endpoint in non-admin tooling and surface a clear permissions message instead

Example fix

// before
const res = await fetch('/subscription/key.json', {headers: auth});
// after
if (!user.isAdmin) throw new Error('Admin role required to read subscription');
const res = await fetch('/subscription/key.json', {headers: adminAuth});
Defensive patterns

Strategy: try-catch

Validate before calling

// client: verify role before calling
if (!user.role || user.role.name !== 'admin') throw new Error('Admin role required');

Type guard

function isAdmin(u) { return !!u && u.role?.name === 'admin'; }

Try / catch

try { const dto = await getSubscriptionKey(uac); } catch (e) { if (e.status === 403) { /* show admin-required message */ } else throw e; }

Prevention

When it happens

Trigger: Calling the subscription GET endpoint (SubscriptionKeyGetService::get, invoked by view/check actions) while authenticated as a non-admin user.

Common situations: Developers testing the subscription API with a regular user account; automated scripts configured with a non-admin API user; role changes that demoted the account after integration.

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

Appendix: source

Thrown at plugins/PassboltEe/Subscription/src/Service/Subscriptions/SubscriptionKeyGetService.php:63

    protected SubscriptionsTable $Subscriptions;

    /**
     * SubscriptionKeyGetService constructor.
     */
    public function __construct()
    {
        $this->Subscriptions = $this->fetchTable('Passbolt/Subscription.Subscriptions');
        $this->SubscriptionValidateService = new SubscriptionKeyValidateService();
    }

    /**
     * @param \App\Utility\UserAccessControl $uac user access control object
     * @return \Passbolt\Subscription\Model\Dto\SubscriptionKeyDto
     */
    public function get(UserAccessControl $uac): SubscriptionKeyDto
    {
        if (!$uac->isAdmin()) {
            throw new ForbiddenException(__('Only administrators can view the subscription details.'));
        }
        $keyString = $this->readFromDB();
        if (!isset($keyString)) {
            $keyString = $this->readFromFile();
        }
        if (!isset($keyString) || empty($keyString)) {
            throw new SubscriptionRecordNotFoundException();
        }

        return $this->SubscriptionValidateService->validate($keyString);
    }

    /**
     * Try to read the key string from database (OrganizationSettings table)
     * Try new file name first then legacy name, log warnings if issues.
     *
     * @return string|null
     * @throws \Passbolt\Subscription\Error\Exception\Subscriptions\SubscriptionException if subscription key is invalid

View on GitHub (pinned to 31c1bbc10f)