# 4. Role-Based Access Control — Test Cases

User Type: **Super Administrator**
Source: *Mi Digital Academy - Education CRM Features Document*
Spec: role_based_access_control.md — every feature, sub-feature, and rule covered

---

## Test Execution Policy
- Zero tolerance: any deviation from documented behavior = FAILED = bug
- Every bug is immediately logged/reported (Bug ID, feature, sub-feature,
  expected vs actual, severity) and fixed 100% before the group passes
- Feature group passes only at 100% test pass rate

## Coverage Matrix
| Feature | Sub-feature / Rule | Test IDs |
|---------|--------------------|----------|
| 4.1 Enforce Role-Based Access Across the Platform | Per-request authorization check: roles → permissions → allowed/denied | TC-SA-02-04-001 |
| 4.1 Enforce Role-Based Access Across the Platform | Consistent enforcement across web UI and service/API surfaces | TC-SA-02-04-002 |
| 4.1 Enforce Role-Based Access Across the Platform | Deny-by-default: anything not explicitly permitted is denied | TC-SA-02-04-003 |
| 4.1 Enforce Role-Based Access Across the Platform | Feature, action, and data-scope enforcement in a single check | TC-SA-02-04-004 |
| 4.1 Enforce Role-Based Access Across the Platform | Prompt reflection of permission changes (next request, no re-login) | TC-SA-02-04-005 |
| 4.1 Enforce Role-Based Access Across the Platform | Denial responses: clear message plus a logged denial event | TC-SA-02-04-006 |
| 4.1 Enforce Role-Based Access Across the Platform | Super Administrator exemption: full access | TC-SA-02-04-007 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: enforcement is per-request and server-side | TC-SA-02-04-002 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: missing permission mapping results in denial, never silent allow | TC-SA-02-04-003 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: no stale-permission window after a change | TC-SA-02-04-005 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: the same permission governs web and service surfaces | TC-SA-02-04-002 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: denial events logged with user, role, target, timestamp | TC-SA-02-04-006 |
| 4.1 Enforce Role-Based Access Across the Platform | Rule: the Super Administrator role bypasses the check | TC-SA-02-04-007 |
| 4.2 Prevent Unauthorized Access to Features | Section-level access check on every navigation and direct request | TC-SA-02-04-008 |
| 4.2 Prevent Unauthorized Access to Features | Direct-URL and bookmark protection | TC-SA-02-04-009 |
| 4.2 Prevent Unauthorized Access to Features | Shared-link protection | TC-SA-02-04-010 |
| 4.2 Prevent Unauthorized Access to Features | Consistent denial message with optional "request access" path | TC-SA-02-04-011 |
| 4.2 Prevent Unauthorized Access to Features | Denial logging with the attempted target | TC-SA-02-04-012 |
| 4.2 Prevent Unauthorized Access to Features | No partial disclosure: a denied section reveals no data | TC-SA-02-04-013 |
| 4.2 Prevent Unauthorized Access to Features | Rule: a denied section reveals no data or metadata | TC-SA-02-04-013 |
| 4.2 Prevent Unauthorized Access to Features | Rule: direct URLs, bookmarks, shared links all subject to the same check | TC-SA-02-04-009 |
| 4.2 Prevent Unauthorized Access to Features | Rule: the denial message does not reveal why beyond "not permitted" | TC-SA-02-04-014 |
| 4.2 Prevent Unauthorized Access to Features | Rule: "request access" optional per policy; routes to Super Admin | TC-SA-02-04-011 |
| 4.2 Prevent Unauthorized Access to Features | Rule: repeated denials for a role/target signal misconfiguration/misuse | TC-SA-02-04-015 |
| 4.2 Prevent Unauthorized Access to Features | Rule: the check applies to authenticated users; unauthenticated handled by login | TC-SA-02-04-016 |
| 4.3 Prevent Unauthorized Access to Data | Record-level scope check on every read, write, search, export | TC-SA-02-04-017 |
| 4.3 Prevent Unauthorized Access to Data | ID-based access protection | TC-SA-02-04-018 |
| 4.3 Prevent Unauthorized Access to Data | Search and list scoping | TC-SA-02-04-019 |
| 4.3 Prevent Unauthorized Access to Data | Export scoping | TC-SA-02-04-020 |
| 4.3 Prevent Unauthorized Access to Data | Cross-institute isolation | TC-SA-02-04-021 |
| 4.3 Prevent Unauthorized Access to Data | Denial logging for out-of-scope record attempts | TC-SA-02-04-022 |
| 4.3 Prevent Unauthorized Access to Data | Consistent with feature enforcement (same per-request check) | TC-SA-02-04-023 |
| 4.3 Prevent Unauthorized Access to Data | Rule: record scope enforced on reads, writes, searches, exports | TC-SA-02-04-017 |
| 4.3 Prevent Unauthorized Access to Data | Rule: out-of-scope access by ID denied and logged (probing detection) | TC-SA-02-04-018 |
| 4.3 Prevent Unauthorized Access to Data | Rule: cross-institute isolation is a hard, non-configurable boundary | TC-SA-02-04-021 |
| 4.3 Prevent Unauthorized Access to Data | Rule: search/list results never include out-of-scope records | TC-SA-02-04-019 |
| 4.3 Prevent Unauthorized Access to Data | Rule: exports respect the same scope as the on-screen view | TC-SA-02-04-020 |
| 4.3 Prevent Unauthorized Access to Data | Rule: all out-of-scope attempts audit-logged | TC-SA-02-04-022 |
| 4.4 Access Denial Logging and Review | Denial event fields: user, roles, target, request type, timestamp, IP, device | TC-SA-02-04-024 |
| 4.4 Access Denial Logging and Review | Real-time and historical denial views with filters | TC-SA-02-04-025 |
| 4.4 Access Denial Logging and Review | Pattern detection: repeated denials for a user/role/target | TC-SA-02-04-026 |
| 4.4 Access Denial Logging and Review | Probing indicator: many distinct out-of-scope IDs by one user | TC-SA-02-04-027 |
| 4.4 Access Denial Logging and Review | Link from a denial to the user's role set and the target's required permission | TC-SA-02-04-028 |
| 4.4 Access Denial Logging and Review | Export of denial logs for audits | TC-SA-02-04-029 |
| 4.4 Access Denial Logging and Review | Retention per policy | TC-SA-02-04-030 |
| 4.4 Access Denial Logging and Review | Rule: denial events are append-only; cannot be edited or deleted | TC-SA-02-04-031 |
| 4.4 Access Denial Logging and Review | Rule: a denial reveals nothing about the protected resource | TC-SA-02-04-032 |
| 4.4 Access Denial Logging and Review | Rule: pattern detection raises review items; does not auto-block | TC-SA-02-04-026 |
| 4.4 Access Denial Logging and Review | Rule: the link to required permission distinguishes misconfiguration vs. misuse | TC-SA-02-04-028 |
| 4.4 Access Denial Logging and Review | Rule: exports access-controlled and audit-logged | TC-SA-02-04-029 |
| 4.4 Access Denial Logging and Review | Rule: denial logging covers feature and data denials in one stream | TC-SA-02-04-033 |

## 4.1 Enforce Role-Based Access Across the Platform

### TC-SA-02-04-001 — Per-request authorization check allows only permitted operations
**Type:** Positive
**Covers:** 4.1 → Per-request authorization check: user's roles → permissions → allowed/denied
**Preconditions:** A Content Reviewer with a known permission set is logged in.
**Steps:**
1. The reviewer opens the review queue (permitted feature).
2. Approves a content item (permitted action).
3. Loads a list (permitted data scope).
**Expected Result:** Each request passes the roles → permissions check and succeeds — enforcement is per-request.
**Priority:** Critical

### TC-SA-02-04-002 — Enforcement is consistent across web UI and service surfaces
**Type:** Positive
**Covers:** 4.1 → Consistent enforcement across web UI and service/API surfaces; Rule: server-side; Rule: no UI bypass
**Preconditions:** A Content Reviewer lacks billing permissions.
**Steps:**
1. The reviewer attempts a billing operation via the web UI.
2. The same billing operation is attempted via a direct service/API request.
**Expected Result:** Both are denied by the same permission check — enforcement is not UI-only; the same permission governs both surfaces.
**Priority:** Critical

### TC-SA-02-04-003 — Deny-by-default: a missing permission mapping results in denial
**Type:** Negative
**Covers:** 4.1 → Deny-by-default; Rule: a missing permission mapping results in denial, never a silent allow
**Preconditions:** A user's role has no mapping for a feature that exists in the catalog.
**Steps:**
1. The user attempts the unmapped feature.
**Expected Result:** The request is denied — anything not explicitly permitted is denied; there is no silent allow.
**Priority:** Critical

### TC-SA-02-04-004 — Feature, action, and data-scope enforcement in a single check
**Type:** Positive
**Covers:** 4.1 → Feature, action, and data-scope enforcement in a single check
**Preconditions:** A user's role permits a feature, one action within it, and a limited data scope.
**Steps:**
1. The user opens the feature (allowed).
2. Attempts a permitted action on an in-scope record (allowed).
3. Attempts an unpermitted action (denied).
4. Attempts the permitted action on an out-of-scope record (denied).
**Expected Result:** All three dimensions are enforced in the same per-request check with the correct allow/deny outcome for each.
**Priority:** Critical

### TC-SA-02-04-005 — Permission changes reflect on the next request with no stale window
**Type:** Positive
**Covers:** 4.1 → Prompt reflection of permission changes; Rule: no stale-permission window after a change
**Preconditions:** A Content Reviewer's role is about to gain resource-library approval; the reviewer has an active session.
**Steps:**
1. Add the permission to the role and save.
2. The reviewer makes their next request immediately.
**Expected Result:** The new permission is effective on the very next request — no stale-permission window, no re-login.
**Priority:** Critical

### TC-SA-02-04-006 — Denial responses include a clear message and a logged event
**Type:** Positive
**Covers:** 4.1 → Denial responses: clear user-facing message plus a logged denial event; Rule: logged with user, role, target, timestamp
**Preconditions:** A Content Reviewer attempts Pricing Management (not permitted).
**Steps:**
1. The reviewer opens Pricing Management.
2. Observe the user-facing response.
3. Super Admin checks the access log.
**Expected Result:** The reviewer sees "You don't have permission to access this section"; the denial event is logged with user, role, target, and timestamp.
**Priority:** Critical

### TC-SA-02-04-007 — The Super Administrator role bypasses the RBAC check
**Type:** Edge
**Covers:** 4.1 → Super Administrator exemption: full access; Rule: the Super Administrator role bypasses the check
**Preconditions:** Super Admin logged in.
**Steps:**
1. As Super Admin, open every module and perform actions across all of them.
2. Check the denial log for Super Admin entries.
**Expected Result:** Full access everywhere; no denial events are generated for the Super Administrator role.
**Priority:** High

## 4.2 Prevent Unauthorized Access to Features

### TC-SA-02-04-008 — Section-level access check on every navigation
**Type:** Positive
**Covers:** 4.2 → Section-level access check on every navigation and direct request
**Preconditions:** A user with a known feature set is logged in.
**Steps:**
1. Navigate through every permitted section.
2. Navigate to every unpermitted section.
**Expected Result:** Permitted sections load; unpermitted sections are denied — the check runs on every navigation.
**Priority:** Critical

### TC-SA-02-04-009 — Direct URLs and bookmarks to unpermitted sections are denied
**Type:** Negative
**Covers:** 4.2 → Direct-URL and bookmark protection; Rule: reachability never implies permission
**Preconditions:** A support admin previously had Marketing access; the permission was removed; a bookmark to the module exists.
**Steps:**
1. The support admin opens the Marketing module bookmark.
2. The support admin enters the Marketing module URL directly.
**Expected Result:** Both are denied with the standard message — direct URLs and bookmarks are subject to the same check.
**Priority:** Critical

### TC-SA-02-04-010 — Shared links to unpermitted sections do not grant access
**Type:** Negative
**Covers:** 4.2 → Shared-link protection: a link to an unpermitted section does not grant access
**Preconditions:** User A (permitted) shares a link to a section; user B (not permitted) receives it.
**Steps:**
1. User B opens the shared link.
**Expected Result:** User B is denied — the shared link grants no access beyond the user's own permissions.
**Priority:** Critical

### TC-SA-02-04-011 — Consistent denial message with an optional "request access" path
**Type:** Positive
**Covers:** 4.2 → Consistent denial message with an optional "request access" path; Rule: requests route to Super Admin with requester and target
**Preconditions:** "Request access" is enabled per policy; a user without section access is logged in.
**Steps:**
1. The user attempts the unpermitted section.
2. Review the denial message.
3. Submit an access request from the prompt.
4. Super Admin reviews the request in the queue.
**Expected Result:** The message is consistent; the request routes to Super Admin with the requester and target; the decision (grant/deny) is recorded and communicated.
**Priority:** High

### TC-SA-02-04-012 — Denials are logged with the attempted target
**Type:** Positive
**Covers:** 4.2 → Denial logging with the attempted target
**Preconditions:** A denial has just occurred.
**Steps:**
1. Open the denial log and locate the event.
**Expected Result:** The event records the attempted target (the specific section), the user, the role, and the timestamp.
**Priority:** High

### TC-SA-02-04-013 — A denied section reveals no data from it
**Type:** Negative
**Covers:** 4.2 → No partial disclosure: a denied section reveals no data; Rule: no partial disclosure, no metadata leakage
**Preconditions:** A user lacks access to a section containing known records.
**Steps:**
1. The user attempts the section via URL.
2. Inspect the response body and headers for any data or metadata from the section.
**Expected Result:** The response contains only the standard denial — no records, no counts, no metadata from the protected section.
**Priority:** Critical

### TC-SA-02-04-014 — The denial message does not reveal why beyond "not permitted"
**Type:** Edge
**Covers:** 4.2 → Rule: the denial message is consistent and does not reveal why beyond "not permitted" (avoiding enumeration)
**Preconditions:** A user triggers denials for several different unpermitted targets.
**Steps:**
1. Compare the denial messages across the different targets.
**Expected Result:** All messages are identical in substance — none discloses which specific permission is missing or why, preventing enumeration.
**Priority:** Medium

### TC-SA-02-04-015 — Repeated denials for a role/target surface as a misconfiguration signal
**Type:** Edge
**Covers:** 4.2 → Rule: a pattern of repeated denials for a role/target is a misconfiguration or misuse signal
**Preconditions:** A role's holders repeatedly hit denials on a feature they need.
**Steps:**
1. Generate repeated denials for the role/target.
2. Review the denial patterns.
**Expected Result:** The repeated-denial pattern is surfaced for review, enabling Super Admin to update the role's default set.
**Priority:** Medium

### TC-SA-02-04-016 — Unauthenticated requests are handled by the login flow, not RBAC
**Type:** Edge
**Covers:** 4.2 → Rule: the check applies to authenticated users; unauthenticated requests are handled by the login flow
**Preconditions:** No session exists.
**Steps:**
1. Attempt to open a protected section without authenticating.
**Expected Result:** The request is handled by the login flow (redirect/prompt to authenticate), not by an RBAC denial.
**Priority:** Medium

## 4.3 Prevent Unauthorized Access to Data

### TC-SA-02-04-017 — Record-level scope check on every read, write, search, and export
**Type:** Positive
**Covers:** 4.3 → Record-level scope check on every read, write, search, and export; Rule: no path bypasses it
**Preconditions:** A teacher's scope is "own records" for courses and students.
**Steps:**
1. Read: open the course list and a detail view.
2. Write: attempt to edit an in-scope course and an out-of-scope course.
3. Search: search for students by name.
4. Export: export the enrollment list.
**Expected Result:** Reads, writes, searches, and exports all contain/accept only in-scope records; out-of-scope writes are denied.
**Priority:** Critical

### TC-SA-02-04-018 — ID-based access to out-of-scope records is denied and logged
**Type:** Negative
**Covers:** 4.3 → ID-based access protection; Rule: out-of-scope access by ID denied and logged (probing detection)
**Preconditions:** A teacher knows a colleague's course ID.
**Steps:**
1. The teacher enters the colleague's course ID in the URL.
2. Check the denial log.
**Expected Result:** The record is denied (out of scope); the attempt is logged with user, target record, and timestamp — supporting probing detection.
**Priority:** Critical

### TC-SA-02-04-019 — Search and list results contain only in-scope records
**Type:** Positive
**Covers:** 4.3 → Search and list scoping; Rule: results never include out-of-scope records
**Preconditions:** A teacher's scope covers 3 courses with known students; other courses exist on the platform.
**Steps:**
1. The teacher runs a search for a student name that exists in both in-scope and out-of-scope courses.
2. Review the results.
**Expected Result:** Results are limited to students in the teacher's scoped courses — no leakage through result sets.
**Priority:** Critical

### TC-SA-02-04-020 — Exports include only in-scope records
**Type:** Positive
**Covers:** 4.3 → Export scoping; Rule: exports respect the same scope as the on-screen view
**Preconditions:** A teacher's on-screen enrollment list shows only in-scope students.
**Steps:**
1. The teacher exports the enrollment list.
2. Compare the export contents with the on-screen view.
**Expected Result:** The export contains exactly the in-scope students — identical to the on-screen scope.
**Priority:** High

### TC-SA-02-04-021 — Cross-institute isolation is a hard boundary
**Type:** Negative
**Covers:** 4.3 → Cross-institute isolation; Rule: a hard scope boundary, not configurable per user
**Preconditions:** Staff of institute A attempt to access an institute B student record by ID.
**Steps:**
1. Institute A staff enter the institute B student record ID.
2. Attempt the same via search.
3. Attempt to configure the boundary per user.
**Expected Result:** Both access attempts are denied and logged; the boundary is hard — no per-user configuration exists to weaken it.
**Priority:** Critical

### TC-SA-02-04-022 — Out-of-scope record attempts are audit-logged
**Type:** Positive
**Covers:** 4.3 → Denial logging for out-of-scope record attempts; Rule: all out-of-scope attempts audit-logged
**Preconditions:** Out-of-scope attempts (ID-guess and cross-institute) have occurred.
**Steps:**
1. Open the out-of-scope attempt log.
2. Inspect both attempts.
**Expected Result:** Both appear with user, target record, and timestamp — enabling intent assessment (accidental vs. deliberate).
**Priority:** High

### TC-SA-02-04-023 — Data enforcement is consistent with feature enforcement
**Type:** Edge
**Covers:** 4.3 → Consistent with feature enforcement (same per-request check)
**Preconditions:** A user can open a section but lacks scope for some records in it.
**Steps:**
1. The user opens the section (feature allowed).
2. Attempts an in-scope record and an out-of-scope record.
**Expected Result:** The same per-request check governs both: the section opens, the in-scope record loads, the out-of-scope record is denied — one consistent mechanism.
**Priority:** High

## 4.4 Access Denial Logging and Review

### TC-SA-02-04-024 — Denial events capture all required fields
**Type:** Positive
**Covers:** 4.4 → Denial event fields: user, role(s), target, request type, timestamp, IP, device
**Preconditions:** A denial has just occurred.
**Steps:**
1. Open the denial event in the Access Denial view.
2. Verify each field.
**Expected Result:** The event contains the user, role(s), target (feature or record), request type, timestamp, IP, and device.
**Priority:** High

### TC-SA-02-04-025 — Real-time and historical denial views with filters
**Type:** Positive
**Covers:** 4.4 → Real-time and historical denial views with filters (by user, role, target, type, time)
**Preconditions:** Denials exist across users, roles, targets, types, and time ranges.
**Steps:**
1. Open the real-time denial view for the last 24 hours.
2. Apply each filter: by user, role, target, type, time.
3. Switch to the historical view and filter by a past date range.
**Expected Result:** Both views render correctly; every filter narrows results accurately.
**Priority:** High

### TC-SA-02-04-026 — Pattern detection for repeated denials raises review items without auto-blocking
**Type:** Positive
**Covers:** 4.4 → Pattern detection: repeated denials for a user/role/target; Rule: raises review items; does not automatically block
**Preconditions:** A support admin has 12 denials on Pricing Management in one hour.
**Steps:**
1. Open the pattern view for the user.
2. Verify the user is not automatically blocked.
**Expected Result:** A review item is raised for the repeated-denial pattern; the user is not auto-blocked — blocking is a separate control.
**Priority:** High

### TC-SA-02-04-027 — Probing indicator for many distinct out-of-scope IDs
**Type:** Positive
**Covers:** 4.4 → Probing indicator: many distinct out-of-scope record IDs attempted by one user
**Preconditions:** A teacher has 30 distinct out-of-scope course-ID attempts in an hour.
**Steps:**
1. Filter the denial view by the teacher.
2. Review the probing indicator.
**Expected Result:** The probing pattern is flagged (30 distinct out-of-scope IDs), enabling intent review (accidental vs. deliberate) and action.
**Priority:** High

### TC-SA-02-04-028 — A denial links to the user's role set and the target's required permission
**Type:** Positive
**Covers:** 4.4 → Link from a denial to the user's role set and the target's required permission; Rule: distinguishes misconfiguration vs. misuse
**Preconditions:** A denial event exists for a user and target.
**Steps:**
1. Open the denial event.
2. Follow the link to the user's role set and the target's required permission.
**Expected Result:** The links resolve correctly, making it quick to determine whether the role genuinely lacks the permission (misconfiguration) or the user is misusing access.
**Priority:** High

### TC-SA-02-04-029 — Denial log export is access-controlled and audit-logged
**Type:** Positive
**Covers:** 4.4 → Export of denial logs for audits; Rule: exports access-controlled and audit-logged
**Preconditions:** Super Admin logged in; the denial view is open.
**Steps:**
1. Export the denial log for the audit evidence package.
2. Check the audit trail for the export action.
**Expected Result:** The export succeeds with the filtered data; the export action is access-controlled and audit-logged.
**Priority:** Medium

### TC-SA-02-04-030 — Denial events are retained per policy
**Type:** Positive
**Covers:** 4.4 → Retention per policy
**Preconditions:** Denial events older than the retention window exist.
**Steps:**
1. Query the denial view for events within the retention window.
2. Query for events beyond it.
**Expected Result:** Events within the policy retention window are available; retention behavior matches the configured policy exactly.
**Priority:** Medium

### TC-SA-02-04-031 — Denial events are append-only and cannot be edited or deleted
**Type:** Negative
**Covers:** 4.4 → Rule: denial events are append-only and retained per policy; they cannot be edited or deleted
**Preconditions:** Denial events exist; Super Admin logged in.
**Steps:**
1. Attempt to edit a denial event's fields.
2. Attempt to delete a denial event.
**Expected Result:** Both attempts are impossible — the events are append-only.
**Priority:** Critical

### TC-SA-02-04-032 — A denial reveals nothing about the protected resource
**Type:** Edge
**Covers:** 4.4 → Rule: a denial reveals nothing about the protected resource beyond the standard denial message
**Preconditions:** A user triggers denials on protected resources.
**Steps:**
1. Inspect the denial responses for any information about the protected resources (existence, names, counts).
**Expected Result:** The responses contain only the standard denial message — no information about the protected resource.
**Priority:** High

### TC-SA-02-04-033 — Feature and data denials appear in one reviewable stream
**Type:** Positive
**Covers:** 4.4 → Rule: denial logging covers both feature and data denials in one reviewable stream
**Preconditions:** Both feature denials and data denials have occurred.
**Steps:**
1. Open the Access Denial view without type filters.
2. Verify both denial types appear.
**Expected Result:** Feature and data denials are interleaved in a single reviewable stream, filterable by type.
**Priority:** Medium
