Skip to content
Aabha AI Academy

Module 6 of 9 · Lesson 17 of 26

Enforce permissions with roles and ownership

Work through enforce permissions with roles and ownership using a runnable reference, a focused regression check and a local extension.

Read in any order. All lessons stay open, including after an unanswered or incorrect check.

In this lesson you will enforce permissions with roles and ownership. Work with the Equipment Rental API in the downloadable lab. The reference is a complete solution with separate lesson checks, so you can inspect the answer, make a deliberate local change and verify its behavior.
Authentication identifies a user; authorization decides whether that user may perform this action on this record. The local policy lets a customer read their own rentals, an operator check rentals in, and an admin read or check in. It denies unsupported actions and unknown roles. The diagram shows the two gates and the different meanings of 401 and 403.

Ownership must be evaluated against trusted database state. The request cannot supply another owner id to make a rental look permitted. Rental creation uses the resolved principal id, while list queries apply that owner's scope before pagination. Hiding a button in the browser does not protect an API route; direct requests must receive the same decision. The reference intentionally keeps operator read permission narrower than admin permission so tests expose accidental broadening. This matrix is for the Equipment Rental lab, not a platform staffing grant. A caller denied check-in must leave rental status and event records unchanged. Review the matrix before implementing extra roles; names alone do not define authority.
A protected request passes through authentication and then authorization; missing identity leads to 401 and insufficient permission leads to 403
Authentication identifies the caller; authorization decides whether this action is allowed.
Worked source: equipment/security.py, may.

Run lesson17. The customer's own read is allowed, another owner's read and customer check-in are denied, and an owner-scoped list does not return another user's rental. Trace the scope into page_statement before its cursor and limit. Read the diagram's accessible description if using a screen reader.
pythonCopyable
def may(principal, owner_id, action):
    if principal.role == "admin":
        return action in {"read", "check_in"}
    if principal.role == "operator":
        return action == "check_in"
    return (
        principal.role == "customer" and principal.id == owner_id and action == "read"
    )
TerminalPython 3.13 virtual environment; Docker running; extracted lab directory
python run_checks.py -k lesson17

Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.

Keep for reference

Equipment Rental lab and lesson checks

ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.

Download Equipment Rental lab and lesson checks

Practise locally

Create two synthetic owners and one operator. Test direct rental reads for each owner, then test a customer attempting check-in. Assert the denied request returns 403 and leaves active status and check-in count unchanged. Write the small permission matrix in your notes so every allow has a corresponding nearby deny.

The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.

Pause and reflect

What failure does this lesson prevent, and which assertion in lesson17 would expose it?

Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.

Optional knowledge check

Where must record ownership be enforced for a paginated list?

Only after rendering the list in the browser.

Try another answer. Browser hiding is not server-side authorization and can expose unauthorized data.

Filter other owners after collecting a full page.

Try another answer. Post-pagination filtering can distort pages and expose aggregate behavior.

In the database query before the cursor and limit are applied.

Correct. Early scope protects both the returned records and the page behavior.

This practice does not assess your project or award a certificate.

Your reading progress

Progress is saved in this browser when storage is available.

Sign in to save across devices · Create an optional account