passbolt/passbolt_api · error · UnauthorizedException
Only admin can create or update subscription information.
Error message
Only admin can create or update subscription information.
What it means
SubscriptionsTable::beforeSave() enforces that only an admin UserAccessControl can create or update a subscription record; it throws UnauthorizedException when the 'uac' save option is missing, empty, or not an admin. This guards the subscription table from non-privileged writes.
Solutions
- Always pass a UAC in save options: `$table->save($entity, ['uac' => $uac])` or use SubscriptionsTable::createOrUpdate($uac, $key).
- Ensure the UAC is built for an admin user (role id of 'admin') — e.g. via UserAccessControl for an administrator identity.
- In CLI/root contexts, construct a UAC from an admin user record instead of skipping it.
Example fix
// before $this->Subscriptions->save($subscriptionEntity); // after $this->Subscriptions->save($subscriptionEntity, ['uac' => $uac]); // $uac->isAdmin() === true
Defensive patterns
Strategy: validation
Validate before calling
if (!$uac->isAdmin()) {
throw new \Cake\Http\Exception\ForbiddenException('Admin required to save subscription');
}
$table->save($entity, ['uac' => $uac]); Try / catch
try {
$this->Subscriptions->createOrUpdate($uac, $key);
} catch (\Cake\Http\Exception\UnauthorizedException $e) {
// caller lacks admin UAC or uac option missing
} Prevention
- Always pass 'uac' in save options for SubscriptionsTable
- Never bypass SubscriptionsTable by writing entities directly without a UAC
- Ensure CLI/automation jobs construct an admin-role UserAccessControl
When it happens
Trigger: Calling SubscriptionsTable::save()/createOrUpdate()/update() without passing 'uac' in the save options, or with a UAC belonging to a non-admin (e.g. a user role) — $options['uac'] is null or !isAdmin().
Common situations: Custom scripts or plugins saving to Subscriptions directly and forgetting the uac option; running subscription updates with a logged-in non-admin session; CLI tasks that build a UAC with the wrong role; calling save() on the entity from another plugin without compact('uac').
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 delete the subscription.
- Only guests are allowed to create an account recovery…
- Only guests are allowed to proceed with account recovery.
- You are not allowed to access this location.
- You are not authorized to access that location.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/9e761c9e4f4f1934.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Subscription/src/Model/Table/SubscriptionsTable.php:104
$query->where([
$this->aliasField('property_id') => $this->getPropertyId(),
]);
}
/**
* Ensure that an administration is provided in options before saving.
*
* @param \Cake\Event\Event $event the event
* @param \Passbolt\Subscription\Model\Entity\Subscription $entity entity
* @param \ArrayObject $options options
* @return void
*/
public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options): void
{
/** @var \App\Utility\UserAccessControl $uac */
$uac = $options['uac'] ?? null;
if (empty($uac) || !$uac->isAdmin()) {
throw new UnauthorizedException(__('Only admin can create or update subscription information.'));
}
if ($entity->isNew()) {
$entity->set('created_by', $uac->getId());
}
$entity->set('modified_by', $uac->getId());
}
/**
* Fields property and property_id are fixed.
*
* @param \Cake\Event\Event $event the event
* @param \ArrayObject $data data
* @param \ArrayObject $options options
* @return void
*/
public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options): void
{
$data['property'] = $this->getProperty();View on GitHub (pinned to 31c1bbc10f)