Skip to content

Authorization

Authorization is permission-based in dichit-backend: routes declare allowed roles, and ownership/scope checks run in the application layer.

Roles

Defined in prisma/schema.prisma (enum Role):

Role Description
SUBSCRIBER Individual program participant
COMPANY Company user / auctioneer staff
SUPERADMIN Platform administrator

Route-level: authorize(roles)

app.get(
  '/v2/admin/programs',
  {
    preValidation: [app.authenticate, app.authorize(['SUPERADMIN'])]
  },
  handler
);

authorize throws UnauthorizedError/ForbiddenError for role mismatches (see authentication.md and error-handling.md).

Application-level: ownership & scope

Route roles are necessary but not sufficient. For read/update/delete on tenant-scoped resources, the use case must verify ownership/scope. From AGENTS.md:

Never trust client-provided identifiers alone for access control. For update/delete operations, verify ownership, tenant/company scope, or role permissions before performing the write.

Examples of scope checks in the codebase:

  • company:<companyId> scopes for company resources.
  • user:<userId> / subscriber:<id> scopes for subscriber resources.
  • Do not reveal whether unauthorized records exist unless the contract requires it.

WebSocket authorization

WS messages are authorized per event (permission checks at the router, not just role). Roles map to permissions as documented in api/websocket/README.md:

SUBSCRIBER  → auction:subscribe, auction:bid:place, room:join, room:leave
COMPANY     → + auction:staff, broadcast:receive
SUPERADMIN  → + auction:staff, broadcast:receive

Decision flow

flowchart LR
    R["Request"] --> A{"authenticate"}
    A -->|fail| E["401 Unauthorized"]
    A -->|ok| Z{"authorize(roles)"}
    Z -->|fail| E
    Z -->|ok| O{"ownership / scope check (use case)"}
    O -->|fail| F["403 Forbidden"]
    O -->|ok| H["handler"]

Best practices

  1. Keep checks in the application flow, not buried in controllers.
  2. Combine route roles and resource ownership checks for write paths.
  3. Test both allowed and denied cases (see testing.md).
  4. Never trust client-supplied identifiers alone.