{"record":{"id":"bef370f9a0eddcd0","repo":"passbolt/passbolt_api","slug":"the-sso-key-id-should-be-a-uuid-ssokeysdeleteservice","errorCode":null,"errorMessage":"The SSO key id should be a uuid.","messagePattern":"The SSO key id should be a uuid\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Service/SsoKeys/SsoKeysDeleteService.php","lineNumber":39,"sourceCode":"use Cake\\Http\\Exception\\BadRequestException;\nuse Cake\\Http\\Exception\\InternalErrorException;\nuse Cake\\Http\\Exception\\NotFoundException;\nuse Cake\\ORM\\TableRegistry;\nuse Cake\\Validation\\Validation;\n\nclass SsoKeysDeleteService\n{\n    /**\n     * Delete a Sso key\n     *\n     * @param \\App\\Utility\\UserAccessControl $uac user access control\n     * @param string $id uuid\n     * @return void\n     */\n    public function delete(UserAccessControl $uac, string $id): void\n    {\n        if (!Validation::uuid($id)) {\n            throw new BadRequestException(__('The SSO key id should be a uuid.'));\n        }\n\n        $SsoKeys = TableRegistry::getTableLocator()->get('Passbolt/Sso.SsoKeys');\n        try {\n            $entity = $SsoKeys->find()->where(['id' => $id, 'user_id' => $uac->getId()])->firstOrFail();\n        } catch (RecordNotFoundException $exception) {\n            throw new NotFoundException(__('The SSO key does not exist.'));\n        }\n\n        if (!$SsoKeys->delete($entity)) {\n            throw new InternalErrorException(__('The SSO key could not be deleted.'));\n        }\n    }\n}\n","sourceCodeStart":21,"sourceCodeEnd":54,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Service/SsoKeys/SsoKeysDeleteService.php#L21-L54","documentation":"SsoKeysDeleteService::delete() requires the SSO key id parameter to be a valid UUID and throws BadRequestException('The SSO key id should be a uuid.') when Validation::uuid() fails. It is a cheap input guard before any database access.","triggerScenarios":"Calling the delete endpoint/service with an id that is not a UUID: empty string, numeric id, URL-encoded garbage, or a truncated identifier from a client-side bug.","commonSituations":"Client code passes a route parameter placeholder that never got substituted; using a database row number instead of the UUID; copy/paste truncation of the key id.","solutions":["Pass the full UUID of the SSO key as returned by the SSO keys listing endpoint","Fix client-side code that builds the URL so the id placeholder is populated","Validate the id format client-side before issuing the DELETE request","Check for double URL-encoding that corrupts the id"],"exampleFix":"// before\nawait fetch(`/sso/keys/${key.rowNumber}`, {method: 'DELETE'});\n// after\nawait fetch(`/sso/keys/${key.id}`, {method: 'DELETE'}); // key.id is a UUID","handlingStrategy":"validation","validationCode":"// pre-validate the id client-side\nif (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(keyId)) {\n    throw new Error('SSO key id must be a UUID');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $service->delete($uac, $id);\n} catch (BadRequestException $e) {\n    // invalid id format — fix client URL building\n    throw $e;\n}","preventionTips":["Always use UUIDs returned by the API, never internal row numbers","Validate id format before issuing DELETE requests","Beware of double URL-encoding when interpolating ids into paths"],"tags":["sso","uuid","bad-request","invalid-argument"],"backgroundTag":"invalid-argument-format","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"}