> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lmrp.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> Every permission key in Argus, what it allows, and which endpoints check it.

Argus decides what a caller may do from a flat list of permission keys. There are 32, and this page lists all of them. Each endpoint in the [API reference](/api-reference/overview) states the key it checks on its **Permission** line.

## How permissions work

* **Checked on the server, on every request.** The web application hides what you cannot use, but that is a convenience. `GET /api/me` returns the permissions in effect for you.
* **Exact.** A check names one key, and no key implies another. Holding `admin.manage` alone does not let you dispatch, and `cad.dispatch` is no use without `cad.view`.
* **From roles.** An administrator gives a staff member one or more roles. Each role is a set of keys, and a person holds the union of their roles.
* **Only while the staff profile is active.** Deactivating a profile removes every role permission at once. The session stays signed in.
* **Read again on every request.** A change to a role or to someone's membership applies to their very next request.

A missing permission returns `403 FORBIDDEN`, and the message names the key.

### Held by everyone

Every active signed-in account holds two permissions, with or without a staff role:

* `civilians.create`
* `civilians.manage_own`

That is what lets any member use the civilian portal. Everything else comes from roles.

### Service credentials

A service credential's scopes are permission keys from the same catalogue. It can hold any of them except `admin.manage` and `staff.manage`. Holding a scope is not always enough: endpoints that need a signed-in person refuse credentials whatever their scopes. See [Authentication](/authentication#service-credentials).

### Developer Access

While temporary Developer Access is on, the session holds every permission in the catalogue. It is internal tooling, described under [Authentication](/authentication#developer-access).

## The catalogue

### CAD: Control

Held by dispatchers. Every Control endpoint checks `cad.view` first; each kind of change checks one more.

| Permission | Allows | Checked by |
| - | - | - |
| `cad.view` | Read incidents, units, calls, crew history and the operational history. | Every endpoint under `/cad/incidents`, `/cad/units`, `/cad/calls` and `/cad/events`, including those that check a second permission |
| `cad.incidents.create` | Create incidents, and convert calls into them. | `POST /cad/incidents`<br />`POST /cad/calls/{id}/convert` |
| `cad.incidents.manage` | Edit, close and reopen incidents. | `POST /cad/incidents/{id}/edit`<br />`POST /cad/incidents/{id}/close`<br />`POST /cad/incidents/{id}/reopen` |
| `cad.dispatch` | Assign units to incidents and release them. | `POST /cad/incidents/{id}/assign`<br />`POST /cad/incidents/{id}/remove` |
| `cad.units.manage` | Create and edit units, change their crew and status, and list who can crew a unit. | `GET /cad/units/eligible-crew`<br />`POST /cad/units`<br />`POST /cad/units/{id}/edit`<br />`POST /cad/units/{id}/status` |
| `cad.calls.manage` | Record, attach, convert and resolve calls. | `POST /cad/calls`<br />`POST /cad/calls/{id}/attach`<br />`POST /cad/calls/{id}/convert`<br />`POST /cad/calls/{id}/resolve` |

### MDT: unit self-service

Held by people who crew units. These endpoints also need an active staff profile.

| Permission | Allows | Checked by |
| - | - | - |
| `cad.unit.self` | Book on, join a unit, change your own unit's status, and list units on duty. | `GET /cad/me/units`<br />`POST /cad/me/unit/book-on`<br />`POST /cad/me/unit/join`<br />`POST /cad/me/unit/status` |

### Civilians

The first two are held by every signed-in account.

| Permission | Allows | Checked by |
| - | - | - |
| `civilians.create` | Create characters on your own account. | `POST /civilians` |
| `civilians.manage_own` | Read and edit your own characters, issue their licence, and register, edit and transfer their vehicles. | `GET /civilians`<br />`GET /civilians/{id}`<br />`PATCH /civilians/{id}`<br />`POST /civilians/{id}/licence`<br />`POST /civilians/{id}/vehicles`<br />`PATCH /civilians/{id}/vehicles/{vehicleId}`<br />`POST /civilians/{id}/vehicles/{vehicleId}/transfer` |
| `civilians.manage` | Administrative override: act on any character, correct a locked name or date of birth, change a registration number, and see which account owns a character. | Every `/civilians/{id}` endpoint, for a character you do not own<br />`PATCH /civilians/{id}`, to change a locked name or date of birth<br />`PATCH /civilians/{id}/vehicles/{vehicleId}`, to change `plate`<br />`GET /pnc/civilians/{id}` and `GET /pnc/events`, to see the owning account |

### PNC

Reading and each kind of official change are separate.

| Permission | Allows | Checked by |
| - | - | - |
| `pnc.view` | Search people and vehicles, and read records, warrants, markers and history. | `GET /pnc/civilians`<br />`GET /pnc/civilians/{id}`<br />`GET /pnc/vehicles`<br />`GET /pnc/vehicles/{id}`<br />`GET /pnc/events`<br />`GET /pnc/records`<br />`GET /pnc/warrants`<br />`GET /pnc/markers` |
| `pnc.records.manage` | Create and amend official records. | `POST /pnc/records`<br />`PATCH /pnc/records/{id}` |
| `pnc.licences.manage` | Suspend, revoke, reinstate and amend licences; add and remove endorsements. | `POST /pnc/licences/{id}/status`<br />`PATCH /pnc/licences/{id}`<br />`POST /pnc/licences/{id}/endorsements`<br />`POST /pnc/licences/{id}/endorsements/{endorsementId}/remove`<br />`POST /pnc/records`, when `endorseLicence` is set |
| `pnc.warrants.manage` | Issue, amend, execute and cancel warrants. | `POST /pnc/warrants`<br />`PATCH /pnc/warrants/{id}` |
| `pnc.markers.manage` | Add and clear markers, including stolen-vehicle markers. | `POST /pnc/markers`<br />`POST /pnc/markers/{id}/clear` |
| `pnc.vehicles.manage` | Change a vehicle's official registration, insurance, MOT and tax status. | `PATCH /pnc/vehicles/{id}` |

### Staff, shifts and sessions

| Permission | Allows | Checked by |
| - | - | - |
| `staff.view` | Read staff profiles. | `GET /staff`<br />`GET /staff/{id}` |
| `staff.manage` | Reserved. No endpoint checks it; changing staff membership needs `admin.manage`. | None |
| `shifts.view` | Read anyone's shifts. Active staff can always read their own. | `GET /shifts`, for anyone's shifts but your own |
| `shifts.manage` | Start and end shifts for other staff. Active staff can always manage their own. | `POST /shifts/start` and `POST /shifts/end`, for anyone's shift but your own |
| `sessions.view` | Read sessions. | `GET /sessions` |
| `sessions.manage` | Start and end sessions. | `POST /sessions/start`<br />`POST /sessions/end` |

### Moderation

| Permission | Allows | Checked by |
| - | - | - |
| `moderation.view` | Read the general punishment list. | `GET /moderation/punishments`, without `targetRobloxId` |
| `moderation.history` | Read one player's punishment history. | `GET /moderation/punishments`, with `targetRobloxId` |
| `moderation.warn` | Record warnings. | `POST /moderation/warnings` |
| `moderation.kick` | Kick players. | `POST /moderation/kicks` |
| `moderation.ban` | Ban players. | `POST /moderation/bans` |

### Oversight and administration

| Permission | Allows | Checked by |
| - | - | - |
| `audit.view` | Read the audit log. | `GET /audit` |
| `admin.manage` | Manage accounts, roles, staff membership and service credentials. It cannot be given to a service credential. | `POST /staff`<br />`GET /admin/users`<br />`PATCH /admin/users/{id}`<br />`GET /admin/roles`<br />`POST /admin/roles`<br />`PATCH /admin/roles/{id}`<br />`GET /admin/services`<br />`POST /admin/services`<br />`DELETE /admin/services/{id}` |

### ER:LC

| Permission | Allows | Checked by |
| - | - | - |
| `server.view` | Read the live server summary. | `GET /server` |
| `players.view` | List players in the server. | `GET /players` |
| `players.lookup` | Look up one player in the server. | `GET /players/{robloxId}` |

## Rules that are not a single key

Some endpoints decide by ownership or membership instead of, or as well as, a permission.

| Rule | Where |
| - | - |
| **Your own character.** You may act on characters you own. Anyone else's needs `civilians.manage`. | Every `/civilians/{id}` endpoint |
| **Your own shifts.** Active staff may read, start and end their own shift. Anyone else's needs `shifts.view` or `shifts.manage`. | `/shifts`, `/shifts/start`, `/shifts/end` |
| **Active staff.** Booking on, joining, changing status and listing units on duty need an active staff profile as well as `cad.unit.self`. Control can only add active staff to a crew. | MDT endpoints, unit crew lists |
| **Crew of the unit.** You may change the status of, or book off from, only a unit you are crewing. | `/cad/me/unit/status`, `/cad/me/unit/book-off` |
| **Two permissions.** Converting a call needs `cad.calls.manage` and `cad.incidents.create`. Adding a record's points to a licence needs `pnc.records.manage` and `pnc.licences.manage`. | `/cad/calls/{id}/convert`, `POST /pnc/records` |
| **A signed-in person.** The civilian portal, official PNC changes, administration and MDT self-service refuse service credentials. | Each endpoint's **Access** line |
| **Not yourself.** Administrators cannot change their own staff membership or account status. | `POST /staff`, `PATCH /admin/users/{id}` |

## Endpoints with no permission key

These need a signed-in user and check no permission.

| Endpoint | Note |
| - | - |
| `GET /auth/roblox` | Links a Roblox account to the caller's own account. |
| `GET /auth/roblox/callback` | Completes that link. |
| `POST /auth/logout` | Ends the caller's own session. |
| `GET /me` | Returns the caller's own account and permissions. |
| `POST /auth/developer` | Needs the deployment's Developer Access password. Temporary internal tooling. |
| `DELETE /auth/developer` | Turns Developer Access off for the caller's own session. |
| `GET /cad/me/unit` | Returns the unit the caller is crewing, or `null`. |
| `POST /cad/me/unit/book-off` | Active crew of the unit only. No permission is checked, so someone who has lost their role can still leave. |

Sign-in itself is public: `GET /auth/discord` and its callback need no session.

## Default roles

Seeding a deployment creates these roles. Administrators can add others through the API.

| Role | Permissions |
| - | - |
| Administrator | Every permission in the catalogue (32) |
| Dispatcher | `cad.view`, `cad.dispatch`, `cad.incidents.create`, `cad.incidents.manage`, `cad.units.manage`, `cad.calls.manage` |
| Police officer | `cad.unit.self`, `pnc.view`, `pnc.records.manage`, `pnc.licences.manage`, `pnc.warrants.manage`, `pnc.markers.manage`, `pnc.vehicles.manage` |
| Moderator | `server.view`, `players.view`, `players.lookup`, `sessions.view`, `shifts.view`, `staff.view`, `moderation.view`, `moderation.warn`, `moderation.kick`, `moderation.history` |
| Session host | `server.view`, `players.view`, `players.lookup`, `sessions.view`, `sessions.manage`, `shifts.view`, `staff.view` |

* **Administrator is fixed.** The API refuses to rename it or change its permissions, and every seed brings it up to the full catalogue.
* **Other roles are created once.** Seeding leaves a role that already exists exactly as it is. When a release adds a key to a default role, a deployment seeded earlier does not gain it; an administrator has to add it to that role.
* **Dispatcher and Police officer are separate.** A dispatcher cannot use the PNC and an officer cannot open Control unless they hold both roles.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.