Permissions
The File Service decides, for every call made with a user token, whether that user may do that thing with that item. This page explains the model: one set of actions, granted at three levels, combined by union. It is for backend developers deciding how much to let the service enforce, for administrators, and for evaluators. Machine clients are not limited by it: see the last section.
Three levels, one union
Section titled “Three levels, one union”system level the Identity Server: files.* keys mapped onto roles, per application "this role may view everything" │ unionfolder level access entries on a folder, inherited by everything inside it "this team may edit this folder" │ uniondocument level access entries on one file, and the owner's rights "this user may download this file"A right granted at any level holds. There are no deny entries: you restrict by not granting, and by breaking inheritance on a folder so that it sees only its own entries. One thing sits above the actions: inside an application-managed folder people can view, download and copy out what their actions allow, but change nothing (folder_managed).
The six actions
Section titled “The six actions”| Action | On a file | On a folder |
|---|---|---|
view |
See it in listings and search, read its metadata, open previews (renditions, inline images, video, audio, PDF, text) | See the folder and list its children (each child still needs view) |
download |
Mint download URLs of the original, download through a share link | Nothing by itself; inherited by the children |
edit |
Upload a new version, rename, move, change metadata and tags, change the status (except approval decisions), restore a version, regenerate renditions | Create folders and files in it, rename and move it |
share |
Create share links; grant entries to others, limited to the actions the granter holds; set the visibility | The same on the folder |
delete |
Move to the trash and restore; purge with files.manage, or as the owner when the application allows it |
The same, for the whole subtree |
approve |
Set approved or rejected, reopen an approved file. A file in review is read-only for edit holders without approve |
Inherited by the children |
view is implied by every other action: whoever may download a file may see it. Nothing else implies anything.
The eleven keys
Section titled “The eleven keys”The system level is a set of permission keys that the tenant owner maps onto roles for each application, on the console’s Permissions page. They are stored at the Identity Server with your roles.
| Key | Grants | Group |
|---|---|---|
files.view |
view on everything in the application |
content |
files.download |
download on everything |
content |
files.edit |
edit on everything |
content |
files.share |
share on everything |
content |
files.delete |
delete on everything |
content |
files.approve |
approve on everything |
content |
files.manage |
All six actions on everything, plus: edit any access entry, break and restore inheritance anywhere, purge, reassign owners. Full content access in one key | content |
files.configure |
Both administration keys below, in one key | administration |
files.settings.manage |
Read and change the application’s settings: quota, types, sizes, retention, visibility, owner rights, taxonomies | administration |
files.audit.read |
Read the audit log and the usage of the application | administration |
files.permissions.manage |
See and change what every role may do in this application (every key but this one). Granted and withdrawn by the tenant owner only | delegation |
The tenant owner holds every key in every application, always. A social app might map files.view and files.download onto member and nothing else, keeping every write in its backend; a document library might map files.manage onto librarian. Either is one row in the matrix.
GET P/me/capabilities answers the caller’s keys, expanded: files.manage shows as the six action keys and files.manage, files.configure as the two administration keys.
Access entries
Section titled “Access entries”Folder and document levels are access entries on an item:
{ "principal": { "type": "role", "role_id": "editor-role-id" }, "actions": ["view", "download", "edit"], "expires_at": "2026-12-31T00:00:00.000Z" }| Principal | Matches |
|---|---|
{ "type": "user", "user_id": "…" } |
That user |
{ "type": "role", "role_id": "…" } |
Everyone with that tenant role, or that role of this application. Not tenant_owner |
{ "type": "application" } |
Everyone who has access to the application |
An item carries up to 200 entries of its own (too_many_entries). An entry may expire; an expired entry no longer counts. GET P/principals/roles lists the roles that may appear in an entry, GET P/principals/users searches the tenant’s members.
| Route | Does |
|---|---|
GET P/files/:file_id/permissions, GET P/folders/:folder_id/permissions |
The item’s own and inherited entries (inherited_from names the folder) and the effective list. Everything with share, otherwise the caller’s own entries only |
POST P/files/:file_id/permissions/entries, POST P/folders/:folder_id/permissions/entries |
Add one entry |
DELETE P/files/:file_id/permissions/entries/:entry_id, DELETE P/folders/:folder_id/permissions/entries/:entry_id |
Remove one of the item’s own entries |
PUT P/files/:file_id/permissions, PUT P/folders/:folder_id/permissions |
Replace the item’s entries and set inherit |
GET P/files/:file_id/me/permissions |
What the caller may do with a file, with via |
Granting. Whoever holds share on an item may add entries whose actions they hold on it themselves; anything more answers cannot_grant_more_than_held. files.manage may grant anything. Entry changes are rate limited to 30 per minute per user.
The owner
Section titled “The owner”Every item has an owner_id: the uploader, or the user your backend named. The owner holds the application’s owner_actions on their own items whatever the entries say: by default view, download, edit, share and delete, never approve unless the application adds it. A tenant whose backend should be the only writer sets owner_actions to view, download.
Inheritance
Section titled “Inheritance”An item with inherit: true (the default) has its own entries plus its parent’s effective entries, up to the root. A folder with inherit: false starts a new scope: it and everything inside it see only the entries from that folder down. The owner and the holders of system-level keys still see it.
- Breaking inheritance: replace the folder’s permissions with
{ inherit: false, copy_inherited: true }. The entries it inherited are copied into its own list, so nothing changes for anyone until you remove one. Withcopy_inherited: falseit starts empty. - Restoring inheritance:
{ inherit: true }clears the folder’s own list, unlesskeep_own: true. - An entry on a folder costs nothing per descendant: adding one to a folder of a million files is one write.
The matrix
Section titled “The matrix”How a user’s right to do action a on item i comes about:
| Source | Holds when |
|---|---|
| System level | A role of the user carries files.<a> (or files.manage) in this application, or the user is the tenant owner |
| Owner | i.owner_id is the user and a is in the application’s owner_actions |
| Visibility | i is application or public and a is view or download |
| Entries | An entry on i, or on a folder i inherits from, matches the user and names a |
| Implied view | a is view and any of the above gives the user another action on i |
Listings and search apply the same rule inside the query, so paging and counts are exact: a user without files.view sees in a folder the children they may view, and searches only the folders they may view (up to 5,000 folder scopes; beyond that search answers too_many_scopes and asks for a folder filter).
Errors
Section titled “Errors”| Answer | Means |
|---|---|
403 missing_action |
The caller may view the item but lacks the action |
404 file_not_found, folder_not_found |
The caller may not view it (or it does not exist: the service never says which) |
403 missing_capability |
A system-level key is needed: settings, audit, the role matrix |
403 partial_permission |
A subtree operation is blocked by some descendants; blocked lists them |
403 folder_managed |
The item is in an application-managed folder: people cannot change it, whatever their actions; managed_folder_id names the folder |
Machine clients
Section titled “Machine clients”A backend client with files:manage holds every action on every item of its context, and the entries never limit it; files:read holds view and download. Your backend is trusted to apply its own rules before it calls. When it acts for a user and wants the service’s answer for that user, it asks: GET P/files/:file_id/effective-permissions?user_id= answers { actions, via }, with via such as system:files.view, owner, visibility:application or role:editor@folder:01J9…. See Permissions from code.