coollabsio/coolify · error · Exception
You do not have permission to create tokens with deploy…
Error message
You do not have permission to create tokens with deploy permissions.
What it means
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.
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
Example fix
// blade: before
<input type="checkbox" value="deploy" wire:model="permissions">
// blade: after
<input type="checkbox" value="deploy" wire:model="permissions"
@if(!auth()->user()->can('useDeployPermissions', \App\Models\PersonalAccessToken::class)) disabled @endif> Defensive patterns
Strategy: validation
Validate before calling
use App\Models\PersonalAccessToken;
if (in_array('deploy', $permissions, true)
&& ! auth()->user()->can('useDeployPermissions', PersonalAccessToken::class)) {
// remove 'deploy' or block the submission
} Try / catch
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. Prevention
- 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
When it happens
Trigger: A member selecting the 'deploy' permission; a user whose deploy standing was revoked after the page rendered; a hand-crafted Livewire payload including 'deploy'.
Common situations: CI-oriented tokens requested by non-privileged teammates; role changes mid-session; assuming deploy is a 'safe' ability available to all members.
Related errors
- You do not have permission to create tokens with root…
- You do not have permission to create tokens with write…
- You do not have permission to create tokens with…
- Container not found.
- Destination does not belong to the current team.
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/6ab073a0e45781aa.
Report an issue: GitHub.
Appendix: source
Thrown at app/Livewire/Security/ApiTokens.php:127
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',
]);
$expiresAt = $this->expiresInDays ? now()->addDays($this->expiresInDays) : null;
$token = auth()->user()->createToken($this->description, array_values($this->permissions), $expiresAt);
$this->getTokens();
// Do NOT strip the numeric prefix (e.g. "69|...") — Sanctum uses it to index and look up tokens.
session()->flash('token', $token->plainTextToken);
} catch (\Exception $e) {
return handleError($e, $this);
}View on GitHub (pinned to 70b9acc424)