Skip to content

Permissions

Admin-only endpoints to inspect and edit user permissions stored in MongoDB. The public API seeds the permission catalog on startup so the service and consent flows can reference known nodes right away.

Auth

All routes require a valid API JWT and are currently restricted to the super-admin user.

List permission nodes

GET /v1/admin/permissions

Response:

json
{
  "items": [
    { "id": "671f5b8a7a8a3e6f6e6d6e6d", "node": "profile:read" },
    { "id": "671f5b9e7a8a3e6f6e6d6e6e", "node": "totem:write" }
  ]
}

List user permissions

GET /v1/admin/users/{userId}/permissions

Response:

json
{
  "userId": "c959d9f9-dcbd-4054-8c4c-d5c305997bc0",
  "items": [
    {
      "node": "profile:read",
      "negated": false,
      "expiresAt": "2026-01-15T12:00:00Z",
      "value": { "value": 20, "unit": "gib" }
    }
  ]
}

value is optional and allows permissions to carry quantitative limits ("power"/quotas). Supported shapes:

json
{ "value": 20, "unit": "gib" }
json
10

Units (case-insensitive): bytes, kib, mib, gib, tib, seconds, minutes, hours, days, years, count, messages (common aliases like gb are accepted and mapped).

Quota nodes

Some permission nodes are treated as quantitative limits by specific endpoints. Examples:

  • social:friends.max (unit: count or unit-less number): maximum number of friends a user can have.
  • profile-share.max (unit: count or unit-less number): maximum number of active profile shares a user can create.

Upsert user permission

POST /v1/admin/users/{userId}/permissions

Body:

json
{
  "node": "profile:read",
  "negated": false,
  "expiresAt": "2026-01-15T12:00:00Z",
  "value": { "value": 20, "unit": "gib" }
}

Response:

json
{
  "userId": "c959d9f9-dcbd-4054-8c4c-d5c305997bc0",
  "node": "profile:read",
  "negated": false,
  "expiresAt": "2026-01-15T12:00:00Z",
  "value": { "value": 20, "unit": "gib" }
}

expiresAt is optional. When omitted, the grant/deny does not expire. value is optional. When omitted, it is not changed. To clear an existing value, send null:

json
{ "node": "profile:read", "value": null }

Delete user permission

DELETE /v1/admin/users/{userId}/permissions/{node}

Response:

json
{ "removed": 1 }