Skip to content
Aabha AI Academy

Module 6 of 9 · Lesson 15 of 26

Create local users and offload password hashing

Work through create local users and offload password hashing 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 create local users and offload password hashing. 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.
The local registration endpoint accepts an email and password, hashes the password and stores only the hash. It assigns the customer role on the server; a caller cannot submit operator or admin in UserIn. The demonstration email shape check is intentionally simple, and this standalone lab does not send verification mail or provide account recovery. Those are separate requirements for a deployed identity service.

Argon2 hashing is deliberately expensive. Calling it directly inside async def would occupy the event-loop thread. hash_password and verify_password use asyncio.to_thread so the synchronous hashing library runs off that thread. The reference does not log the password, return the hash or place it inside a token. A real deployment also needs admission limits for hashing work, abuse controls, account lifecycle and reviewed password policy. The lab's minimum length is an input example, not the platform's credential policy. Use synthetic local users, and never copy real learner credentials into these exercises. Failed login returns one generic credential error rather than revealing detailed password state.
Worked source: equipment/security.py, hash_password.

Read security.py and the register/token routes. The lesson15 test records the thread performing a hash and confirms it differs from the event-loop thread; it then verifies a correct and incorrect synthetic password. A digest is a password verifier, not a reversible encoding.
pythonCopyable
async def hash_password(password):
    return await asyncio.to_thread(HASHER.hash, password)
TerminalPython 3.13 virtual environment; Docker running; extracted lab directory
python run_checks.py -k lesson15

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

Write a registration request test that submits an extra role field and must receive 422. Confirm the stored role for a valid synthetic request is customer and that neither password nor password_hash appears in the response. Add a duplicate-email test expecting the documented conflict. Delete the local test users with the disposable database.

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 lesson15 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 should the registration role come from?

Put an encrypted password in a JWT so the API can recover it.

Try another answer. The reference stores a password hash and does not include credentials in claims.

A server-controlled default, with later grants through a reviewed process.

Correct. A new caller must not grant itself a privileged role by adding a request field.

Any role string supplied in the registration JSON.

Try another answer. Trusting the submitted role lets a caller create its own privileged identity.

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