Governance

Role System & Separation of Duties

Nine roles. Separation of duties enforced at the API. The Dean can’t move money. Finance can’t change grades. Registrar can’t wire payments. Audit-ready out of the box.

Why this matters

Most university software grants “administrator” access generously and trusts people not to misuse it. That works until an audit asks who can do what.

UniversitasAI enforces role boundaries at the API layer, not just the UI. A registrar logging in as themselves cannot — even via direct API call — modify a payroll record. A finance officer cannot post a grade change. A dean cannot wire money to a vendor. The check runs server-side on every protected endpoint via require_dean(), require_registrar(), require_finance(), and similar dependencies.

This isn’t a permissions screen. It’s the architecture: roles are baked into the data layer and enforced before any handler runs.

The 9 roles

Each role admits its own scope plus admin. ADMIN starts with wildcard during rollout and narrows organically as endpoint-level role checks land.

Dean

Can: approve academic escalations, read OBEF and governance dashboards, view executive briefings.

Cannot: touch finance writes, modify transcripts, wire money.

Default landing page: /executive-briefing

Registrar

Can: own transcripts, graduation workflows, government reports (CAA / MOHESR / ADEK / KHDA).

Cannot: wire money, modify financial records, change grades on behalf of faculty.

Default landing page: /students

Finance

Can: own accounting, procurement, payroll, vendor payments, financial reporting.

Cannot: modify academic records, transcripts, or grades.

Default landing page: /budget

Faculty

Can: grade entry, attendance, office hours, course materials — scoped to assigned sections only.

Cannot: see other faculty’s sections, modify finance records, access HR data.

Default landing page: faculty portal dashboard

Support

Can: own tickets, knowledge base, conversations, public-facing chat.

Cannot: see financial PII, modify academic records, access government-report drafts.

Default landing page: /support

Admin

Can: wildcard access during platform rollout.

Long-term: ADMIN narrows organically as every endpoint moves to a role-specific dependency. The goal is a small ADMIN scope, with day-to-day work routed through the specialised roles.

Staff

General institutional staff who don’t fit Dean / Registrar / Finance / Faculty / Support. Read access to most operational dashboards; limited writes.

Student

Self-service portal access. Sees own grades, schedule, financial aid, registration. Cannot see anyone else’s records.

Applicant

Pre-enrollment access. Application status, document upload, admission communications. Promoted to Student on enrollment confirmation.

Capability matrix

Who can write what.

Capability Dean Registrar Finance Faculty Support
Approve academic escalation Yes No No No No
Modify transcript No Yes No No No
Post journal entry No No Yes No No
Submit grades for assigned section No No No Yes No
Resolve support ticket No No No No Yes
Read OBEF dashboard Yes Yes Read-only No No
Submit government report (CAA / MOHESR / ADEK) Approve Submit No No No
Wire vendor payment No No Yes No No
Run payroll No No Yes No No
View financial PII No No Yes No No

How it’s enforced

API-layer dependencies

FastAPI dependencies (require_dean(), require_registrar(), require_finance(), require_support(), require_faculty()) run before any handler. A wrong role gets 403 before the SQL query is even constructed.

JWT-claim-based

The user’s role is encoded in their JWT and verified per request. No role lookup on each call — the check is constant-time. Token rotation invalidates old roles immediately.

Audit-logged

Every privileged action writes to an audit table with user, role, action, and timestamp. The audit log is read-only post-write. Compliance teams get the trail they ask for.

Audit-ready governance, day one

The role system is part of the platform — not a configuration screen, not an add-on. See it in the live demo with seeded test users for each role.