---
module: fleet.task-permissions
title: Task Permissions Guide
tab: Internal
order: 20
audience: internal
---

Support-side view: what to check when a customer cannot push a command, and what we must never widen.

## Where It Lives
- **Service:** `hiveops-fleet` only (port 8097, DB `hiveiq_fleet`).
- **UI:** Fleet Mgmt → 🔐 Task Permissions. Admin-only submenu item.
- **Table:** `institution_task_permissions` in `hiveiq_fleet`.

## The Model in One Line
**Deny by default.** The absence of a row *is* the denial. An institution with no rows can push nothing, and nothing changed for anyone when #119 shipped — every institution started empty.

## Only Customers Are Gated
This is the point people get wrong. The gate applies to **CUSTOMER role only**:

| Role | Effect of these settings |
|---|---|
| CUSTOMER | Gated — may push only what their institution has been granted |
| MSP_ADMIN | **Not gated** — full command set, scoped to their institutions |
| ADMIN / BCOS_ADMIN | **Not gated** — full command set, unrestricted |

So "I ticked nothing and admins can still reboot" is correct behaviour, not a bug.

## Triage: "Customer cannot reboot"
1. **Check the grant.** Fleet Mgmt → Task Permissions → is **Reboot** ticked for their institution key?
2. **Check the role.** Are they actually CUSTOMER? An MSP_ADMIN is never gated, so if they are blocked the cause is elsewhere.
3. **Check the institution.** A customer can only target devices in their own institution. Wrong institution reads as a permission problem but is a scope problem.
4. **Read the error.** The API is explicit rather than silent:
   - *"Your institution is not permitted to push 'REBOOT'. Ask your service provider to enable it."* → no grant. Tick the box.
   - *"'CONFIG_UPDATE' can never be pushed by a customer."* → they are asking for a non-grantable command. Nothing to tick; this one is by design.

> A customer who presses Reboot and gets a cheerful nothing is worse than one who is told they lack permission — that is why these are 403s with messages, not silent drops.

## What We Will Never Grant
Only **REBOOT** and **RESTART_AGENT** are grantable. The rest are operator powers and are refused even if someone tries to set them through the API:

| Command | Why it is not grantable |
|---|---|
| `CONFIG_UPDATE` | Can brick every ATM an institution owns |
| `INSTALL_MODULE` | Runs arbitrary code on them |
| `UPDATE_AGENT` | Fleet-wide agent replacement |
| `PACKET_CAPTURE` | A data-exfiltration path |

Widening that set is a deliberate decision with a code change and a review — not a config toggle, and not a side effect of "let AICU reboot a machine". If a customer asks for more, it is an engineering conversation, not a support one.

## Escalate If
- A CUSTOMER successfully pushes something outside REBOOT/RESTART_AGENT. That is a security incident, not a bug.
- A customer can command a device outside their institution. Same.
- Grants vanish on their own. Setting an institution's grants **replaces** the whole set (see the Architect tab) — suspect a concurrent admin edit before suspecting the database.
