Skip to content

Roles & capabilities

This page describes the role and permission model at a technical level. It is aimed at developers. The user-facing version is under Roles & permissions.

KanzleiSynchron distinguishes two axes (backend/api/src/auth.rs):

  • Tenant roles — users of a client (Mandant). Shown in the invite form under /settings/team.
  • Internal ops roles — KS internal staff. Access only via /ops/**, not tenant users.

When inviting under /settings/team, exactly these three roles are offered (frontend/src/app/(app)/settings/team/page.tsx):

Role keyDisplay nameMay
reviewerStaff / clerk (Sachbearbeiter)Daily work: imports, reconciliation, exceptions. No team management, no settings changes.
merchant_adminFirm admin (Kanzlei-Admin)Invite/suspend team, change tenant settings, trigger erasure. Owner of a tenant.
internal_opsInternal operatorCross-tenant visibility. Assigned at invite time by a merchant_admin.

The frontend gates admin surfaces through frontend/src/lib/role-capabilities.ts rather than hard role comparisons:

HelperAllowed for
canViewAdmin(r)super_admin, support, compliance_officer, read_only, merchant_admin
canMutateTenant(r)super_admin, merchant_admin
canManageTeam(r)super_admin, merchant_admin
canRunErasure(r)super_admin, compliance_officer, merchant_admin

Additionally, /me returns a capabilities: string[] array. Ops users have role: null and a separate ops_role, so role-based gates fail-closed for them; use hasCapability(caps, cap) with the constants from OPS_CAPS / TENANT_CAPS instead.

Four scoped internal roles replace the former broad internal_ops (backend/api/src/auth.rs, Sprint 10 §13.2). merchant_admin remains allowed in all ops gates as a migration path.

RoleTenantsDPR / erasureIssuesMutate?
super_adminyesyesyesyes
supportreadnoyesissues
compliance_officerreadyesreadDPR
read_onlyreadreadreadno

The corresponding backend gates:

  • require_super_adminsuper_admin (plus merchant_admin for compatibility).
  • require_supportsuper_admin or support.
  • require_compliancesuper_admin or compliance_officer (DPR records, GDPR Art. 17 erasure).
  • require_read_only_ok — all ops roles may run read GETs; read_only fails the mutating gates.

OPS_ROLES covers super_admin, support, compliance_officer, read_only, and the compatibility-retained internal_ops.

Closing a period requires that a different person closes it than the one who created it. It follows that a tenant needs at least two users with access, otherwise the close cannot be performed. More on this under Roles & permissions.