Moss · API

server.policyForRoles

Answers the Vex policy somebody holding exactly these roles is served under, compiled from their data grants and the app’s behaviors. Each role is compiled under its own scoping and the policies are merged, so a principal may do whatever any of its roles allows. Example: member reads its own bookings and usher every booking, so together they read every booking; the writes keep the member rules.

Usher and member roles
{
  usher: {
    actions: ['programme', 'door.*'],
    data: ['shows.read', 'bookings.read', 'members.read'],
  },
  member: {
    actions: ['programme', 'seats', 'me.*'],
    data: [
      'shows.read',
      'bookings.*',
      'passes.read',
      'members.read',
    ],
    scoping: 'personal',
  },
}
Behaviors
{
  shows: { read: [] },
  members: {
    default: { read: [] },
    personal: { read: [{ match: 'id', to: 'userId' }] },
  },
  passes: {
    default: { read: [] },
    personal: { read: [{ match: 'member_id', to: 'userId' }] },
  },
  bookings: {
    default: { read: [] },
    personal: {
      read: [{ match: 'member_id', to: 'userId' }],
      write: [{ match: 'member_id', to: 'userId' }],
    },
  },
}
Calls
server.policyForRoles(['member'])
server.policyForRoles(['usher', 'member'])
Policy for member
{
  default: 'deny',
  entities: {
    shows: { read: [] },
    bookings: {
      read: [{ match: 'member_id', to: 'userId' }],
      insert: [{ match: 'member_id', to: 'userId' }],
      update: [{ match: 'member_id', to: 'userId' }],
      delete: [{ match: 'member_id', to: 'userId' }],
    },
    passes: { read: [{ match: 'member_id', to: 'userId' }] },
    members: { read: [{ match: 'id', to: 'userId' }] },
  },
}
Policy for usher and member
{
  default: 'deny',
  entities: {
    shows: { read: [] },
    bookings: {
      read: [],
      insert: [{ match: 'member_id', to: 'userId' }],
      update: [{ match: 'member_id', to: 'userId' }],
      delete: [{ match: 'member_id', to: 'userId' }],
    },
    members: { read: [] },
    passes: { read: [{ match: 'member_id', to: 'userId' }] },
  },
}
Output matches the expected value

Computed when this site was built, by the installed package, which does not run in a browser. The site’s checks recompute it on every change.