Skip to content

0037 — RBAC role expansion: infra_admin, ministry_leader promotion, media_steward, and homeschool portal roles ​

Status: Accepted

Date: 2026-06-23

ADO work item: AB#4348

Deciders: Kristopher Turner (platform owner)

Extends: ADR 0006 (two-plane RBAC, original five roles), ADR 0023 (comms_author)


Context ​

The platform launched with six Plane-2 roles defined across ADR 0006 and ADR 0023. Three gaps emerged during the platform foundation build:

1. No infrastructure admin tier. The admin role conflated community app administrators with platform infrastructure operators. A platform engineer deploying to Azure, rotating secrets, or managing CI/CD pipelines is not the same person as the community administrator approving member signups. The two need separate role representation.

2. No worship and media content management role. Persons responsible for uploading and curating sermons, managing the music library, and maintaining worship media needed a dedicated role scoped to the Sermons & Music portal. Granting them admin or ministry_leader for this purpose would over-provision access.

3. Homeschool portal planning. ADR 0015 establishes the homeschool education portal as a planned feature. Five distinct participant types exist in that program (administrator, teacher, advisor, high school student, general homeschool student) that do not map to any existing role. Defining the role slugs now, ahead of the portal build, ensures the schema and authorization layer are ready when the portal epic begins. Capabilities are intentionally deferred until that time.

4. ministry_leader hierarchy misalignment.ministry_leader was set at permission level 4, below admin at level 5. In practice, a minister has broader community authority — the ability to approve members, lead ministries, and act as spiritual authority — than a community app administrator. The hierarchy did not reflect this reality.


Decision ​

New roles added ​

infra_admin (level 7) — Infrastructure and Platform Administrator

God-mode access across the platform, intended exclusively for platform operators and DevOps engineers. Passes all hierarchical role checks. This role is not intended for day-to-day community administration; that function belongs to admin. Assignment requires deliberate provisioning by an existing infra_admin and is expected to cover a very small set of people (platform engineers, automated CI/CD service identities if applicable).

media_steward (feature role, permissionLevel 0) — Sermon and Music Manager

Manages worship media uploads, the music library, and sermon content in the Sermons and Music portal. Feature-gated: the role grants access to media management capabilities and nothing outside them. In hierarchical checks (requireRole) it is treated as member-level. Use requireAnyRole(['media_steward', 'admin', 'ministry_leader']) for media management endpoints.

Homeschool portal roles (all feature roles, permissionLevel 0)

Five roles are defined now for schema completeness. Capabilities are undefined and will be specified when the homeschool portal epic is planned and built.

SlugDescription
homeschool_adminAdministrates the homeschool program
homeschool_teacherTeaches classes in the program
homeschool_advisorAdvises and counsels students and families
highschool_studentEnrolled in the once-weekly high school program (science, writing, history, and theology classes)
homeschool_studentBase homeschool portal access

These roles carry no permissions outside the homeschool portal. They are treated as member-level in all hierarchical checks until portal-specific endpoint guards are authored.

Hierarchy change: ministry_leader promoted to level 6 ​

ministry_leader moves from permission level 4 to level 6, placing it above admin (level 5). This reflects actual ministry authority: a minister can approve members, lead any ministry area, and act with community authority that supersedes the administrative role. As a consequence, existing users holding ministry_leader will now pass requireRole('admin') checks. This is intentional and correct behavior.

Level 4 is reserved for future use.

Complete canonical role model (post-ADR 0037) ​

RoleLevelTypeDescription
infra_admin7ordinalInfrastructure and Platform Administrator
ministry_leader6ordinalMinister — community spiritual and ministry authority
admin5ordinalCommunity Administrator — day-to-day app administration
group_leader3ordinalSmall Group Leader
member2ordinalStandard member
visitor1ordinalVisitor — approval-gated, minimal read access
media_stewardfeatureSermon and Music Manager
comms_authorfeatureCommunications Author (defined in ADR 0023)
homeschool_adminfeatureHomeschool Administrator
homeschool_teacherfeatureHomeschool Teacher
homeschool_advisorfeatureHomeschool Advisor
highschool_studentfeatureHigh School Student
homeschool_studentfeatureHomeschool Student

Level 4 is reserved. Feature roles carry permissionLevel 0 and are treated as member-level in ordinal checks.


Alternatives considered ​

Multi-role assignment per user. Rejected. Allowing a user to hold multiple roles simultaneously adds substantial complexity to authorization checks, session handling, and audit logging. The single-role model (ADR 0006) is simpler and sufficient. Feature roles are a narrow exception that is handled via requireAnyRole() rather than multi-role assignment.

Update 2026-06-23 (ADR 0038): This decision has been reversed. See ADR 0038 for the accepted multi-role design.

Separate homeschool user table. Rejected. ADR 0007 establishes a single Users table. Creating a parallel table for homeschool participants fragments identity and creates two code paths for auth, session management, and family-group association.

Granting ministry_leader to media managers. Rejected. ministry_leader carries broad community authority. Using it as a proxy for media management over-provisions access and muddies role semantics.


Consequences ​

Schema ​

Prisma migration 20260623000000_rbac_role_expansion adds the new enum values to the Role enum: infra_admin, media_steward, homeschool_admin, homeschool_teacher, homeschool_advisor, highschool_student, homeschool_student.

The ministry_leader permission level constant in the authorization middleware changes from 4 to 6. No data migration is needed for existing users.

Authorization middleware ​

  • requireRole('admin') now passes for ministry_leader users (level 6 > 5). Audit all admin-only endpoints to confirm this is acceptable before deploying.
  • Feature roles must use requireAnyRole() — never requireRole() — for feature-specific endpoint guards, since their permissionLevel is 0.
  • infra_admin passes every hierarchical check. Endpoints that should be inaccessible to infra operators (e.g., community content endpoints) rely on the correct assignment of this role, not on authorization code exclusions. Provision infra_admin only to platform engineers.

Homeschool portal roles ​

Capabilities are undefined until the homeschool portal epic is planned. These slugs are schema-only additions. No endpoint guards referencing homeschool roles should be authored until that epic's design phase.

Positive ​

  • Infrastructure operators and community administrators are represented by distinct roles, enabling least-privilege assignment for each.
  • Media management is handled without over-provisioning ministerial authority.
  • Homeschool role slugs are in the schema before the portal build begins, avoiding a mid-build migration.
  • The ministry_leader hierarchy now matches actual community authority structure.

Negative / trade-offs ​

  • Thirteen roles is more to reason about than six. The ordinal vs. feature role distinction must be clearly communicated to anyone writing new endpoint guards.
  • The ministry_leader promotion is a breaking behavioral change for any endpoint that previously assumed ministry_leader could not pass an admin check. A pre-deploy audit of those endpoints is required.

References ​

Heritage Community Hub — Internal. Access restricted via Cloudflare Access + Entra ID.