13 KiB
PERMISSIONS.md
Permission reference for autonomous.contact.
This document was built by crawling the codebase for:
- default permission assignment in public/api/users/index.ts
- server-side permission checks in public/api/
- frontend permission gates in public/tabs/ and related UI files
Sources of truth
Current default permission sets are defined in public/api/users/index.ts.
DEFAULT_USER_PERMISSIONSare assigned to normal users during signup.DEFAULT_SUPERUSER_PERMISSIONSare assigned to the first/bootstrap user.
How permissions work
There are two layers of access control in this codebase:
- Global permission strings stored on the user record.
- Object-level ACLs stored inside resources, especially channel
permissions.read,permissions.write,permissions.events.read, andpermissions.events.write.
Important consequence: a user may have a global permission and still be blocked by a channel-level ACL.
Generic permission families
These are not stored as standalone permissions, but the server checks for these prefixes:
events.create.*via public/api/events/index.ts and utils/prechecks.tsevents.write.*via public/api/events/:event_id/index.ts, public/api/events/:event_id/index.ts, and utils/prechecks.ts
Permissions bible
| Permission | Default user | Bootstrap superuser | Purpose | Where checked | Notes |
|---|---|---|---|---|---|
channels.read |
yes | yes | Allows listing channels. | public/api/channels/index.ts | Channel detail reads also require channel ACL membership; this permission gates the channel list endpoint only. |
channels.create |
no | yes | Allows creating channels. | public/api/channels/index.ts, public/tabs/chat/channel_sidebar.html | Fully wired. |
channels.delete |
no | yes | Intended to allow channel deletion. | Defined in public/api/users/index.ts | No direct server-side check found. Channel deletion currently uses channel.permissions.write membership instead of this string. See public/api/channels/:channel_id/index.ts. |
channels.write |
no | yes | Intended to allow channel updates. | Defined in public/api/users/index.ts | No direct server-side check found. Channel updates currently use channel.permissions.write membership instead of this string. See public/api/channels/:channel_id/index.ts. |
events.create.blurb |
yes | yes | Allows creating blurb events. |
utils/prechecks.ts, public/tabs/blurbs/new_blurb.html | Matches server behavior. |
events.create.chat |
yes | yes | Allows creating chat events. |
utils/prechecks.ts | UI mismatch: chat composer is gated by events.write.chat, not events.create.chat. See public/tabs/chat/chat.html. |
events.create.essay |
yes | yes | Allows creating essay events. |
utils/prechecks.ts, public/tabs/essays/new_essay.html | Matches server behavior. |
events.create.post |
yes | yes | Allows creating post events. |
utils/prechecks.ts, public/tabs/forum/new_post.html | Matches server behavior. |
events.create.presence |
yes | yes | Intended to allow creating presence events. |
utils/prechecks.ts | No dedicated UI or route-specific feature found beyond generic event creation. |
events.read.blurb |
yes | yes | Intended to allow viewing blurbs. | public/tabs/blurbs/blurbs.html | Frontend-only gate found. No matching server-side event-read check by permission string was found. |
events.read.chat |
yes | yes | Intended to allow viewing chat. | public/tabs/chat/chat.html | Frontend-only gate found. Server reads rely on authentication and channel ACLs, not this string. |
events.read.essay |
yes | yes | Intended to allow viewing essays. | public/tabs/essays/essays.html | Frontend-only gate found. |
events.read.post |
yes | yes | Intended to allow viewing posts. | public/tabs/forum/forum.html | Frontend-only gate found. |
events.read.presence |
yes | yes | Intended to allow viewing presence events. | Defined in public/api/users/index.ts | No active check found beyond the default assignment. |
events.write.blurb |
yes | yes | Allows updating/deleting blurb events. |
utils/prechecks.ts | Used by generic event update/delete endpoints. |
events.write.chat |
yes | yes | Allows updating/deleting chat events. |
utils/prechecks.ts, public/tabs/chat/chat.html | Also used by the chat composer UI, which appears to be stricter/different than server-side create rules. |
events.write.essay |
yes | yes | Allows updating/deleting essay events. |
utils/prechecks.ts | No dedicated UI gate found. |
events.write.post |
yes | yes | Allows updating/deleting post events. |
utils/prechecks.ts | No dedicated UI gate found. |
events.write.presence |
yes | yes | Intended to allow updating/deleting presence events. |
utils/prechecks.ts | No dedicated UI or route-specific usage found beyond generic event mutation logic. |
files.write.own |
yes | yes | Allows uploads only inside the current user's home path under /files/users/<user-id>/.... |
public/_pre.ts | Fully wired. |
files.write.all |
no | yes | Allows uploads anywhere under /files/.... |
public/_pre.ts, tests/11_file_uploads.test.ts | Fully wired. |
invites.create |
yes | yes | Allows creating invite codes. | public/api/users/:user_id/invites/index.ts | Fully wired. |
invites.read.own |
yes | yes | Allows reading invites for the path user when it is self. | public/api/users/:user_id/invites/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
invites.read.all |
no | yes | Allows reading invites across users. | public/api/users/:user_id/invites/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
self.read |
yes | yes | Allows reading the current authenticated user's own profile. | public/api/users/me/index.ts, public/api/users/:user_id/index.ts | Fully wired. |
self.write |
yes | yes | Allows updating/deleting the current user's own profile. | public/api/users/:user_id/index.ts, public/api/users/:user_id/index.ts | Fully wired. |
signups.read.own |
yes | yes | Allows reading signups for the path user when it is self. | public/api/users/:user_id/signups/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
signups.read.all |
no | yes | Allows reading signups across users. | public/api/users/:user_id/signups/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
users.read |
yes | yes | Allows reading/searching other users. | public/api/users/index.ts, public/api/users/:user_id/index.ts | Fully wired. |
users.write |
no | yes | Allows updating/deleting other users and editing permissions. | public/api/users/:user_id/index.ts, public/api/users/:user_id/index.ts, public/api/users/:user_id/index.ts | Fully wired. |
watches.create.own |
yes | yes | Allows creating watches for self. | public/api/users/:user_id/watches/index.ts | Fully wired. |
watches.create.all |
no | no | Allows creating watches for other users. | public/api/users/:user_id/watches/index.ts | Referenced but not granted by either default permission set. Must be assigned manually if needed. |
watches.read.own |
yes | yes | Allows reading watches for self. | public/api/users/:user_id/watches/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
watches.read.all |
no | yes | Allows reading watches across users. | public/api/users/:user_id/watches/index.ts | Route behavior currently has filtering issues; see REVIEW.md. |
watches.write.own |
yes | yes | Intended to allow updating/deleting own watches. | Defined in public/api/users/index.ts | No direct permission check found. Watch update/delete currently use ownership only. See public/api/users/:user_id/watches/:watch_id/index.ts and public/api/users/:user_id/watches/:watch_id/index.ts. |
watches.write.all |
no | yes | Intended to allow updating/deleting others' watches. | Defined in public/api/users/index.ts | No direct permission check found. Watch update/delete currently use ownership only. |
Summary: default permissions vs actual code
Normal-user defaults that are clearly used
These are present in DEFAULT_USER_PERMISSIONS and have matching checks in code:
channels.readevents.create.blurbevents.create.chatevents.create.essayevents.create.postevents.create.presenceevents.write.blurbevents.write.chatevents.write.essayevents.write.postevents.write.presencefiles.write.owninvites.createinvites.read.ownself.readself.writesignups.read.ownusers.readwatches.create.ownwatches.read.own
Defaults that are only partially matched or frontend-only
events.read.blurbevents.read.chatevents.read.essayevents.read.postevents.read.presencewatches.write.own
Bootstrap/superuser defaults that are present but not fully wired as permission strings
channels.deletechannels.writewatches.write.all
Referenced in code but not granted by default
watches.create.all
Biggest mismatches to know about
-
Channel update/delete do not use
channels.writeorchannels.delete. They use per-channel ACL membership instead. See public/api/channels/:channel_id/index.ts. -
Watch update/delete do not use
watches.write.ownorwatches.write.all. They use ownership checks only. See public/api/users/:user_id/watches/:watch_id/index.ts. -
events.read.*permissions are mostly UI gates, not server-enforced authorization. The event read endpoints do not generally check these strings. -
Chat creation UI uses
events.write.chat, but the server requiresevents.create.chatfor POST. This is the clearest create-vs-write mismatch in the current code. -
watches.create.allexists in code but is missing from both default sets.
Recommendation
If the goal is to make permissions predictable, the cleanest next step would be to choose one of these approaches:
- remove unused permission strings from defaults, or
- add explicit checks so every documented permission is actually authoritative
The most important cleanup targets are:
channels.writechannels.deletewatches.write.ownwatches.write.all- the
events.read.*family - the chat UI mismatch between
events.create.chatandevents.write.chat