Skip to content

Actors and permissions

An actor is a human, system, or external participant. Permissions answer who may invoke an operation; scopes answer which records that authorized actor may reach. Both are required for real access control.

  • Human actors represent personas such as Patient, Receptionist, or Administrator. They can carry goals, pains, experience preferences, and session attributes.
  • System actors initiate scheduled or automated behavior.
  • External actors represent parties that initiate behavior from outside the product boundary.
  • An explicit anonymous/public actor represents unauthenticated access where the product requires it.

Use actors for distinct permissions or experiences, not for every organizational title.

Attach authorized actor identities to commands and queries. This is role-based access control.

ConfirmAppointment.permissionRequired = [Receptionist]
ViewOwnAppointments.permissionRequired = [Patient]

RBAC alone is sufficient only when every authorized actor can operate on every row in scope.

A scope restricts the rows within an authorized operation:

  • all: no row restriction beyond role authorization;
  • relationship/self scope: compare a row field with the current actor identity;
  • attribute scope: compare a row field with a session attribute such as clinicId;
  • any-of: allow one of several declared predicates;
  • membership: reach a row through an explicit membership or sharing aggregate.

Example:

Patient may invoke CancelAppointment
AND Appointment.patientId must equal the current Patient identity.

An administrator can be declared as a bypass actor for a self-owned operation without weakening the patient’s restriction.

Self-ownership links an actor to the aggregate representing that identity. Attribute-based scopes use values carried in the authenticated session, such as clinic, tenant, region, or department.

Attribute names must be unique and their referenced concepts must resolve. The runtime must hydrate them from a trusted identity source; a request body is not a trusted actor attribute.

An actor may inherit permission to invoke operations from another actor. The target operation’s scope still applies; inheritance must not silently broaden row access. Cycles are invalid.

Protect both queries and commands. A system is still vulnerable if a patient cannot edit another patient’s appointment but can list or retrieve it.

Apply scopes before pagination and counts so totals do not leak inaccessible rows.

For every user-reachable operation, ask:

  1. Which actors may invoke it?
  2. Which rows can each actor reach?
  3. What trusted identity or attribute proves that relationship?
  4. Are privileged bypasses explicit?
  5. Does the corresponding read path enforce the same boundary?
  6. What rejection should the user see when access fails?

The Health and validation layer checks structural coherence; generated applications must still perform runtime authentication and authorization.