4.2.3.2 Configure user roles

Following the guidance explained regarding the possible authorization user scopes that are available, now you can configure the user roles that are applied to each employee.

👥 Configuring User Roles

Once you understand the authorization scopes available in OpenCRVS, you can configure the user roles that are assigned to each employee.

Roles are defined in TypeScript in:

src/data-seeding/roles/roles.ts

This file contains all roles for your country, including the example roles used in the Farajaland configuration.


🧩 Role structure in roles.ts

A role has three main properties: id, label, and scopes.

import { SCOPES, Scope } from '@opencrvs/toolkit/scopes'
import { MessageDescriptor } from 'react-intl'

type Role = {
  id: string
  label: MessageDescriptor
  scopes: Scope[]
}

export const roles: Role[] = [
  {
    id: 'FIELD_AGENT',
    label: {
      id: 'userRole.fieldAgent',
      defaultMessage: 'Field Agent',
      description: 'Name for user role Field Agent'
    },
    scopes: [
      SCOPES.RECORD_DECLARE_BIRTH,
      SCOPES.RECORD_DECLARE_DEATH,
      SCOPES.RECORD_DECLARE_MARRIAGE,
      SCOPES.RECORD_SUBMIT_INCOMPLETE,
      SCOPES.RECORD_SUBMIT_FOR_REVIEW,

      SCOPES.SEARCH_BIRTH,
      SCOPES.SEARCH_DEATH,
      SCOPES.SEARCH_MARRIAGE,

      'search[event=birth,access=all]',
      'search[event=death,access=my-jurisdiction]',
      'search[event=tennis-club-membership,access=all]',
      'workqueue[id=assigned-to-you|recent|requires-updates-self|sent-for-review]',
      `record.create[event=birth|death|tennis-club-membership]`,
      'record.declare[event=birth|death|tennis-club-membership]',
      'record.notify[event=birth|death|tennis-club-membership]'
    ]
  },

  // ... other roles (POLICE_OFFICER, HOSPITAL_CLERK, COMMUNITY_LEADER, etc.)
]

The rest of the file follows this pattern, defining additional roles such as POLICE_OFFICER, HOSPITAL_CLERK, LOCAL_REGISTRAR, NATIONAL_SYSTEM_ADMIN, etc.


🔑 id: Internal role identifier

  • Must be unique for each role.

  • Is the canonical identifier used in:

    • default-employees.csv / prod-employees.csv (role column)

    • The employee seeding process

  • Once used in a real environment, do not rename or reuse this ID for a different role.


🏷 label: What users see in the UI

  • label.id is a react-intl / FormatJS key, used in translations.

  • defaultMessage is the default English role name.

  • description helps translators understand how the label is used.

ℹ️ Appropriate translations must exist in your client.csv file for each label.id. For details, see the section “Managing Language Content”.


🎯 scopes: What the role is allowed to do

  • The scopes array defines all permissions assigned to this role.

  • Supported scopes are imported from @opencrvs/toolkit via the SCOPES constant.

  • You can also see some string-based scopes (e.g. search[...], workqueue[...]), which are used for dynamic or event-specific permissions.

You design which scopes belong to which roles in your Users & Scopes design (e.g. spreadsheet), then encode that mapping here in roles.ts.


⚠️ Deprecated scopes (still present in examples)

Some scopes used in the Farajaland example roles are deprecated. They are still present for backward compatibility, but should not be used as the reference for new configurations.

Deprecated scopes include:

🔴 Important

These scopes appear in our example configuration for legacy reasons, but they are considered deprecated. We plan to remove or refactor them in a future release.


📘 Source of truth

For the authoritative, up-to-date list of scopes and how they should be used:

Page “user scopes ” is the source of truth.

  • Always follow the guidance on page user scopes when:

    • Designing new roles

    • Assigning scopes

    • Updating or cleaning up legacy roles

  • Treat the examples in roles.ts (especially those using deprecated scopes) as historical examples only, not the canonical model.

Last updated