{"record":{"id":"c7acf2b325e0d238","repo":"coollabsio/coolify","slug":"you-do-not-have-permission-to-create-tokens-with-r-c7acf2","errorCode":null,"errorMessage":"You do not have permission to create tokens with read:sensitive permissions.","messagePattern":"You do not have permission to create tokens with read:sensitive permissions\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Livewire/Security/ApiTokens.php","lineNumber":131,"sourceCode":"            $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        }\n    }\n\n    public function revoke(int $id)\n    {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Security/ApiTokens.php#L113-L149","documentation":"The fourth fresh gate in addNewToken(): 'read:sensitive' is submitted but the user fails useSensitivePermissions, so creation aborts before auth()->user()->createToken() is reached. Sensitive-read abilities expose masked fields (credentials, env vars) and are therefore gated like the other privileged abilities, re-checked server-side on every submit.","triggerScenarios":"A user without sensitive-read standing ticking 'read:sensitive'; a replayed snapshot from before the ability was revoked; crafted wire updates appending the ability.","commonSituations":"Automation that needs env values requested by non-privileged members; post-audit permission tightening followed by stale tabs; multi-user teams with mixed roles.","solutions":["Submit the token without read:sensitive","Route the request through a user who holds the sensitive-read ability","Reload the tokens page and resubmit with the abilities actually offered to you","Verify conditions in PersonalAccessTokenPolicy::useSensitivePermissions if access seems wrong"],"exampleFix":"// blade: before\n<input type=\"checkbox\" value=\"read:sensitive\" wire:model=\"permissions\">\n\n// blade: after\n<input type=\"checkbox\" value=\"read:sensitive\" wire:model=\"permissions\"\n    @if(!auth()->user()->can('useSensitivePermissions', \\App\\Models\\PersonalAccessToken::class)) disabled @endif>","handlingStrategy":"validation","validationCode":"use App\\Models\\PersonalAccessToken;\n\nif (in_array('read:sensitive', $permissions, true)\n    && ! auth()->user()->can('useSensitivePermissions', PersonalAccessToken::class)) {\n    // drop read:sensitive from the request\n}","typeGuard":null,"tryCatchPattern":"Catch \\Exception in the creation action, dispatch('error', $e->getMessage()); do not catch-and-continue - a partially-privileged token must not be silently created.","preventionTips":["Bind the read:sensitive checkbox state to the live ability check","Prefer non-sensitive tokens for automation; request elevation explicitly","After audits/permission changes, refresh the page before creating tokens"],"tags":["api-token","authorization","sanctum","permissions","sensitive-data"],"backgroundTag":"authorization-denied","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}