{"record":{"id":"d80f113335d42f03","repo":"passbolt/passbolt_api","slug":"only-administrators-can-update-the-subscription-details","errorCode":null,"errorMessage":"Only administrators can update the subscription details.","messagePattern":"Only administrators can update the subscription details\\.","errorType":"http","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"plugins/PassboltEe/Subscription/src/Service/Subscriptions/SubscriptionKeySaveService.php","lineNumber":58,"sourceCode":"     * @param \\Passbolt\\Subscription\\Model\\Table\\SubscriptionsTable|null $Subscriptions subscriptions table\n     */\n    public function __construct(?SubscriptionsTable $Subscriptions = null)\n    {\n        $this->SubscriptionsTable = $Subscriptions\n            ?? TableRegistry::getTableLocator()->get('Passbolt/Subscription.Subscriptions');\n        $this->SubscriptionKeyValidateService = new SubscriptionKeyValidateService();\n    }\n\n    /**\n     * @param string|null $keyString key\n     * @param \\App\\Utility\\UserAccessControl $uac user access control object\n     * @return \\Passbolt\\Subscription\\Model\\Dto\\SubscriptionKeyDto\n     * @throws \\Passbolt\\Subscription\\Error\\Exception\\Subscriptions\\SubscriptionException if key format or signature or content is invalid\n     */\n    public function save(?string $keyString, UserAccessControl $uac): SubscriptionKeyDto\n    {\n        if (!$uac->isAdmin()) {\n            throw new ForbiddenException(__('Only administrators can update the subscription details.'));\n        }\n        $keyDto = $this->SubscriptionKeyValidateService->validate($keyString);\n        $this->SubscriptionsTable->createOrUpdate($keyDto->data, $uac);\n\n        return $keyDto;\n    }\n}\n","sourceCodeStart":40,"sourceCodeEnd":66,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Subscription/src/Service/Subscriptions/SubscriptionKeySaveService.php#L40-L66","documentation":"SubscriptionKeySaveService::save() requires an administrator UserAccessControl; non-admin callers get ForbiddenException 'Only administrators can update the subscription details.' Updating/importing a subscription key is an admin-only operation in Passbolt EE.","triggerScenarios":"POST/PUT to the subscription update endpoint (or calling save() directly) while logged in as a non-admin user.","commonSituations":"CI or provisioning scripts using a non-admin API account to install the license; testing the endpoint with a regular user session; role demotion after credentials were generated.","solutions":["Use an administrator account/token to import the subscription key","Grant the admin role to the service user in Passbolt administration","Restrict license automation to admin credentials only"],"exampleFix":"// before\nawait fetch('/subscription/key.json', {method: 'POST', headers: userAuth, body: key});\n// after\nif (!isAdmin(user)) throw new Error('Admin role required to set subscription key');\nawait fetch('/subscription/key.json', {method: 'POST', headers: adminAuth, body: key});","handlingStrategy":"try-catch","validationCode":"if (!$uac->isAdmin()) { throw new Error('Admin role required to update subscription'); }","typeGuard":"function canManageSubscription(uac) { return uac?.isAdmin?.() === true; }","tryCatchPattern":"try { await updateSubscriptionKey(key); } catch (e) { if (e.status === 403) { /* admin required */ } else throw e; }","preventionTips":["Run license automation with admin credentials","Do not share non-admin tokens for provisioning scripts","Verify role assignments after account changes"],"tags":["authorization","passbolt","subscription"],"backgroundTag":"permission-denied","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}