{"record":{"id":"1ac2899afb8006a4","repo":"coollabsio/coolify","slug":"you-do-not-have-permission-to-create-tokens-with-w","errorCode":null,"errorMessage":"You do not have permission to create tokens with write permissions.","messagePattern":"You do not have permission to create tokens with write permissions\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Livewire/Security/ApiTokens.php","lineNumber":123,"sourceCode":"            }\n        }\n        sort($this->permissions);\n    }\n\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.","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Security/ApiTokens.php#L105-L141","documentation":"Same fresh policy re-evaluation in addNewToken(), this time for write abilities: the submitted permissions intersect ['write', 'write:sensitive'] but the user fails the useWritePermissions gate, so token creation aborts. Write abilities let a token mutate resources, so they are restricted to roles the policy trusts (admins/owners), independent of what the rendered UI suggested.","triggerScenarios":"A MEMBER-role user ticking 'write' or 'write:sensitive'; a demoted admin reusing a still-open tokens tab; a crafted Livewire update adding a write ability to the permissions array.","commonSituations":"Role downgrades after page load; inviting collaborators as members who then try to mint write tokens; expecting cloud-team semantics to differ from self-hosted root-team semantics.","solutions":["Request a token without write/write:sensitive abilities","Ask a team admin/owner to create the write-capable token and share it securely if appropriate","Reload the page so the checkboxes match your current standing, then resubmit","Verify the acting user's team role and the PersonalAccessTokenPolicy::useWritePermissions conditions"],"exampleFix":"// blade: before\n<input type=\"checkbox\" value=\"write\" wire:model=\"permissions\">\n\n// blade: after\n<input type=\"checkbox\" value=\"write\" wire:model=\"permissions\"\n    @if(!auth()->user()->can('useWritePermissions', \\App\\Models\\PersonalAccessToken::class)) disabled @endif>","handlingStrategy":"validation","validationCode":"use App\\Models\\PersonalAccessToken;\n\n$wantsWrite = array_intersect(['write', 'write:sensitive'], $permissions) !== [];\nif ($wantsWrite && ! auth()->user()->can('useWritePermissions', PersonalAccessToken::class)) {\n    // strip or reject write abilities before calling addNewToken\n}","typeGuard":null,"tryCatchPattern":"Catch \\Exception inside the token-creation action and dispatch('error', ...); order the checks root -> write -> deploy -> read:sensitive so the first failure names the offending ability.","preventionTips":["Gate write/write:sensitive checkboxes with the useWritePermissions ability at render time","Keep members on read-only tokens unless an admin mints the token","Re-check abilities server-side on every submit - snapshots go stale"],"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"}