coollabsio/coolify · error · Exception

You do not have permission to create tokens with root permis

Error message

You do not have permission to create tokens with root permissions.

What it means

addNewToken() on the API tokens screen re-authorizes requested abilities server-side: if 'root' appears in the submitted permissions array but the current user fails the useRootPermissions gate, token creation aborts. The component deliberately ignores the cached $canUse* booleans because Livewire snapshots can be replayed from another session - the policy is evaluated fresh against auth()->user().

Source

Thrown at app/Livewire/Security/ApiTokens.php:119

            $this->permissions = ['deploy'];
        } else {
            if (count($this->permissions) == 0) {
                $this->permissions = ['read'];
            }
        }
        sort($this->permissions);
    }

    public function addNewToken()
    {
        try {
            $this->authorize('create', PersonalAccessToken::class);

            // Re-evaluate policies fresh against the current authenticated user.
            // Never trust $this->canUse* booleans — they come from the Livewire
            // snapshot which can be replayed from another user's session.
            if (in_array('root', $this->permissions, true) && ! auth()->user()->can('useRootPermissions', PersonalAccessToken::class)) {
                throw new \Exception('You do not have permission to create tokens with root permissions.');
            }

            if (array_intersect(['write', 'write:sensitive'], $this->permissions) && ! auth()->user()->can('useWritePermissions', PersonalAccessToken::class)) {
                throw new \Exception('You do not have permission to create tokens with write permissions.');
            }

            if (in_array('deploy', $this->permissions, true) && ! auth()->user()->can('useDeployPermissions', PersonalAccessToken::class)) {
                throw new \Exception('You do not have permission to create tokens with deploy permissions.');
            }

            if (in_array('read:sensitive', $this->permissions, true) && ! auth()->user()->can('useSensitivePermissions', PersonalAccessToken::class)) {
                throw new \Exception('You do not have permission to create tokens with read:sensitive permissions.');
            }

            $this->validate([
                'description' => 'required|min:3|max:255',
                'expiresInDays' => 'nullable|integer|in:7,30,60,90,365',
            ]);

View on GitHub (pinned to 70b9acc424)

Solutions

  1. Untick the root permission and create the token with ordinary abilities (read, and others you are allowed)
  2. Have the instance/team root (or owner) create the root-scoped token instead
  3. Reload the API tokens page so the permission checkboxes reflect your current gates before submitting
  4. If you believe you should have the ability, verify your team role and the PersonalAccessTokenPolicy::useRootPermissions conditions

Example fix

// blade: before
<input type="checkbox" value="root" wire:model="permissions">

// blade: after
<input type="checkbox" value="root" wire:model="permissions"
    @if(!auth()->user()->can('useRootPermissions', \App\Models\PersonalAccessToken::class)) disabled @endif>
Defensive patterns

Strategy: validation

Validate before calling

use App\Models\PersonalAccessToken;

if (in_array('root', $permissions, true)
    && ! auth()->user()->can('useRootPermissions', PersonalAccessToken::class)) {
    unset($permissions[array_search('root', $permissions, true)]);
    // or block submission in the UI
}

Try / catch

Keep the try/catch in addNewToken(); catch \Exception and dispatch('error', $e->getMessage()). Never precompute ability booleans into the snapshot - always re-evaluate gates server-side at submit time.

Prevention

When it happens

Trigger: A non-root team member (or a user who lost root standing) submitting a token creation with the 'root' permission ticked; a tampered Livewire request injecting 'root' into the permissions array; a page rendered before a role/subscription downgrade.

Common situations: Team role changes after the tokens page was loaded; attempts to self-elevate via browser devtools; cloud instances where root abilities depend on the team's root status.

Related errors


AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17). Data as JSON: /api/errors/66c53391fadb44f0. Report an issue: GitHub.