Remote / foldkit-remote-server

Authentication vs authorization

Keep these boundaries separate:

authentication
  "Who is making this request?"
  Effect RPC middleware / application
             |
             v
          Principal
             |
             v
authorization
  "Which semantic fields may this principal read?"
  RemoteServer.entity(... authorize ...)

RemoteServer.handlers(Server, principal) deliberately receives a resolved principal. It does not inspect headers, sessions, cookies, or bearer tokens. The principal is a value, or a Context key that each call reads, so one handler set (one RPC layer) answers every request and authentication provides the key per request:

ts
class CurrentUser extends Context.Service<CurrentUser, Principal>()('app/CurrentUser') {}
const handlers = RemoteServer.handlers(Server, CurrentUser)

// per request, once authentication has resolved `user`
RemoteServer.answer(handlers, body).pipe(Effect.provideService(CurrentUser, user))

Every handler then needs CurrentUser, which the types carry: a key holding another type than the Server's principal is a type error.

For Entity reads:

  • undeclared fields are dropped first;
  • authorize receives only declared, requested fields;
  • omitting authorize means the requested declared fields are readable;
  • a withheld field is answered as settled, without its reason;
  • an id whose every requested field is withheld is not read from the Source: its fields are settled and no entity is contributed, so it looks the same as an id the Source does not know, and existence is not leaked.

Mutation and Query policy belongs in their Sources because those operations are application-specific rather than field-selection policy.