{"record":{"id":"6ab073a0e45781aa","repo":"coollabsio/coolify","slug":"you-do-not-have-permission-to-create-tokens-with-d","errorCode":null,"errorMessage":"You do not have permission to create tokens with deploy permissions.","messagePattern":"You do not have permission to create tokens with deploy permissions\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Livewire/Security/ApiTokens.php","lineNumber":127,"sourceCode":"\n    public function addNewToken()\n    {\n        try {\n            $this->authorize('create', PersonalAccessToken::class);\n\n            // Re-evaluate policies fresh against the current authenticated user.\n            // Never trust $this->canUse* booleans — they come from the Livewire\n            // snapshot which can be replayed from another user's session.\n            if (in_array('root', $this->permissions, true) && ! auth()->user()->can('useRootPermissions', PersonalAccessToken::class)) {\n                throw new \\Exception('You do not have permission to create tokens with root permissions.');\n            }\n\n            if (array_intersect(['write', 'write:sensitive'], $this->permissions) && ! auth()->user()->can('useWritePermissions', PersonalAccessToken::class)) {\n                throw new \\Exception('You do not have permission to create tokens with write permissions.');\n            }\n\n            if (in_array('deploy', $this->permissions, true) && ! auth()->user()->can('useDeployPermissions', PersonalAccessToken::class)) {\n                throw new \\Exception('You do not have permission to create tokens with deploy permissions.');\n            }\n\n            if (in_array('read:sensitive', $this->permissions, true) && ! auth()->user()->can('useSensitivePermissions', PersonalAccessToken::class)) {\n                throw new \\Exception('You do not have permission to create tokens with read:sensitive permissions.');\n            }\n\n            $this->validate([\n                'description' => 'required|min:3|max:255',\n                'expiresInDays' => 'nullable|integer|in:7,30,60,90,365',\n            ]);\n            $expiresAt = $this->expiresInDays ? now()->addDays($this->expiresInDays) : null;\n            $token = auth()->user()->createToken($this->description, array_values($this->permissions), $expiresAt);\n            $this->getTokens();\n            // Do NOT strip the numeric prefix (e.g. \"69|...\") — Sanctum uses it to index and look up tokens.\n            session()->flash('token', $token->plainTextToken);\n        } catch (\\Exception $e) {\n            return handleError($e, $this);\n        }","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Security/ApiTokens.php#L109-L145","documentation":"The third fresh gate in addNewToken(): 'deploy' is among the submitted permissions but auth()->user()->can('useDeployPermissions', PersonalAccessToken::class) is false, so creation aborts. Deploy abilities let a token trigger deployments and are gated independently of read/write - passing one gate does not imply the others.","triggerScenarios":"A member selecting the 'deploy' permission; a user whose deploy standing was revoked after the page rendered; a hand-crafted Livewire payload including 'deploy'.","commonSituations":"CI-oriented tokens requested by non-privileged teammates; role changes mid-session; assuming deploy is a 'safe' ability available to all members.","solutions":["Create the token without the deploy permission","Have an admin/owner mint the deploy-capable token for the pipeline","Refresh the API tokens page and resubmit with only the abilities still enabled for you","Check PersonalAccessTokenPolicy::useDeployPermissions to see the exact role/subscription conditions"],"exampleFix":"// blade: before\n<input type=\"checkbox\" value=\"deploy\" wire:model=\"permissions\">\n\n// blade: after\n<input type=\"checkbox\" value=\"deploy\" wire:model=\"permissions\"\n    @if(!auth()->user()->can('useDeployPermissions', \\App\\Models\\PersonalAccessToken::class)) disabled @endif>","handlingStrategy":"validation","validationCode":"use App\\Models\\PersonalAccessToken;\n\nif (in_array('deploy', $permissions, true)\n    && ! auth()->user()->can('useDeployPermissions', PersonalAccessToken::class)) {\n    // remove 'deploy' or block the submission\n}","typeGuard":null,"tryCatchPattern":"Catch \\Exception in addNewToken() and surface the message via dispatch('error', ...); treat the four ability gates as independent - passing one does not clear the others.","preventionTips":["Disable the deploy checkbox for users failing useDeployPermissions","Route CI pipelines' token creation through an owner/admin","Verify team role before requesting deploy-capable tokens"],"tags":["api-token","authorization","sanctum","permissions","livewire"],"backgroundTag":"authorization-denied","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}