DOM-IDEN-002: Student Identity Architecture
| Reference Number | Version | Effective Date | Supersedes | Authority Level |
|---|---|---|---|---|
| DOM-IDEN-002 | 2.10 | 2026-10-14 | 2.9 | Constitutional |
Important
v2.10 (2026-10-14), documentation modernization. §IX named “balance cache” among records untouched by recovery. No BalanceCache model or table exists in v2 (CLAUDE.md); balances are derived from the ledger. Corrected to “ledger balance snapshot.” No behavior change.
I. Purpose
This document defines how the canonical identity objects defined by DOM-IDEN-001 are specialized for student participation within Classroom Token Hub. It governs student-specific credential structure, authentication, account recovery, and the claim data model.
This document is subordinate to DOM-IDEN-001 (Canonical Identity Model) and DOM-IDEN-005 (Identity Binding and Lifecycle). Those documents define the universal identity objects and lifecycle laws. This document specializes those definitions for the student role.
Important
This document defines the canonical v2 identity model. It does not preserve v1 data model constraints. Legacy tables (students, student_teachers, student_blocks, class_memberships) are migration artifacts and SHALL NOT be treated as identity authority.
II. Scope
This document governs:
- Student-specific credential fields on
users - Student-specific seat fields (claim artifacts)
- Student authentication flow
- Student session establishment
- Student account recovery
- Student-specific claim data model (field definitions for
roster_fingerprint,dedupe_code, claim hashes)
This document does not govern:
- The canonical identity objects themselves (DOM-IDEN-001)
- Identity binding and lifecycle rules (DOM-IDEN-005)
- Canonical context resolution (DOM-IDEN-006)
- Economic activity (Ledger domain)
- Attendance facts
- Store ownership
- Class policy
III. Authority Level
Tier 1 — Constitutional. This document defines structural enforcement mechanisms and domain-specific constraints that operationalize Foundational invariants. It is subordinate to INV-CORE-000, INV-CORE-001, INV-ARC-008, DOM-IDEN-001, and DOM-IDEN-005.
IV. Dependencies
INV-CORE-000_CORE_INVARIANTS.mdINV-CORE-001_CAPABILITY_BASED_ARCHITECTURE_AND_AUTHORITY_MODEL.mdINV-ARC-008_IDENTITY_RESOLUTION_AND_SEAT_SCOPE.mdINV-ARC-019_IDENTITY_AND_OWNERSHIP_MODEL.mdDOM-IDEN-001_CANONICAL_IDENTITY_MODEL.mdDOM-IDEN-005_IDENTITY_BINDING_AND_LIFECYCLE.md
V. Schema Authority Declaration
Owned Tables
This document does not own any tables exclusively but rather defines how student identity is handled within Classroom Token Hub.
Schema Contract
Student-specific fields on users: pin_hash, passphrase_hash, reset_code, reset_code_generated_at, reset_code_expires_at, recovery_setup_nonce_hash, and recovery_setup_expires_at.
Student-specific fields on seats: roster_fingerprint, dedupe_code, claim first-name/last-name lookup hashes, claimed_at.
Constraints
pin_hashandpassphrase_hashSHALL beNULLfor non-student users.roster_fingerprintanddedupe_codeSHALL beNULLfor non-student seats.UNIQUE(class_id, roster_fingerprint, dedupe_code)onseats.UNIQUE(user_id, class_id)onseats.
Derived / Cross-Domain Rules
Economic and activity records reference seat_id for actor identity per INV-ARC-019 §VII. This document does not define cross-domain table schemas.
VI. Student Identity Layers
Student identity follows the universal three-layer model defined by DOM-IDEN-001:
User: authentication principal — owns credentials, recovery, and global security stateSeat: class-local actor - the canonical participant record inside a classClass: economic universe boundary
Economic activity is always tied to seat_id, never directly to user_id.
Student User Fields
A student User is a users row with user_role = 'student'. Common users fields are defined by DOM-IDEN-001. This section defines only the student-specific delta.
Student-specific fields:
pin_hash— PIN verifier governed by the credential matrix in FEAT-IDEN-002. Preserved during recovery acceptance and replaced atomically at completion.passphrase_hash— passphrase verifier governed by the credential matrix in FEAT-IDEN-002. Preserved during recovery acceptance and replaced atomically at completion.username_hash— full username hash (shared field). Set during activation and replaced atomically at successful recovery completion.username_lookup_hash— principal username lookup hash (shared field). Set during activation and replaced atomically at successful recovery completion.recovery_setup_nonce_hash- server-side verifier of the accepting recovery session nonce; cleared on credential completion or teacher reissuance.recovery_setup_expires_at- original code deadline carried forward; every setup request checks it.reset_code- 8-digit alphanumeric code randomly generated and stored on the corresponding student user row for student to reclaim their accountreset_code_generated_at- timestamp of when the reset code was generated. Stored as UTC but rendered to canonical class timezone.reset_code_expires_at- set to 10 minutes afterreset_code_generated_at. Stored as UTC but rendered to canonical class timezone.
Teacher-specific fields (totp_secret_encrypted) SHALL be NULL for student rows.
Student-specific rules:
- A
usersrow may be provisioned before claim; credentials are activated when a student claims a seat and completes setup. - Recovery capability belongs to
usersand is implemented byreset_code,reset_code_generated_at,reset_code_expires_at,recovery_setup_nonce_hash, andrecovery_setup_expires_atfields (per INV-ARC-019 §XI), not byseats,classes, or display profiles.
Student Seat Fields
A student seat is a seats row with role = 'student'. Base seat fields and participation rules are defined by DOM-IDEN-001. This section defines only the student-specific delta.
Student-specific claim fields:
roster_fingerprint— derived from minimal claim identity after normalizationdedupe_code— short code for Duplicate-On-Paper-Only (DOPO) disambiguation- claim first-name/last-name lookup hashes
claimed_at
Student-specific rules:
user_idis nullable until the seat is claimed.- Claim lookup hashes belong on the seat because they prove entitlement to this class-local participant position (per INV-ARC-019 §VII).
Student IdentityProfile
Defined by DOM-IDEN-001. No student-specific delta. Profiles do not store claim lookup hashes, credentials, or recovery artifacts.
VII. Student Authentication
Login Flow
1. Student submits username.
2. Backend computes username_lookup_hash and finds the users row.
3. Backend verifies user_role == 'student'.
4. Student submits passphrase.
5. Backend verifies passphrase_hash.
6. On success: write current_session_started_at, current_session_expires_at,
current_session_nonce.Active seat and class context restoration follows DOM-IDEN-006.
Session Establishment
current_session_started_atis written at sign-in.current_session_expires_atis written once at sign-in (fixed window, does not slide forward on activity).current_session_nonceis regenerated at sign-in and binds requests to one specific login session.- All three session fields are replaced on the next successful sign-in.
Request-time session validation is governed by DOM-IDEN-006.
Financial Action Gate
The passphrase is the sign-in credential. It is also re-verified for irreversible expense actions (store and insurance purchases, insurance and rent payments, cancelling insurance, and using an entitlement other than a hall pass). The PIN covers non-monetary and reversible actions: clock actions, transfers between the student’s own accounts, and hall-pass use. The authoritative per-action assignment is the credential matrix in FEAT-IDEN-002 §II (Credential boundary).
VIII. Roster Provisioning and Claim
Roster provisioning and claim identity are governed by DOM-IDEN-005. This section specifies the student-specific claim data model.
Roster Provisioning
Roster provisioning rules are defined by DOM-IDEN-005 §VII. This section defines the student-specific claim artifacts that roster provisioning produces.
Roster Fingerprint
roster_fingerprint is derived from minimal claim identity after normalization:
HMAC-SHA-256(PEPPER_KEY, framed purpose + class_id + normalized names + optional dedupe code)
The canonical normalization, purpose labels and unambiguous field framing are defined in incorporated SPEC-SEC-001 §V.2. First/last-name digests use distinct labels and include the resolved class_id.
Duplicate-On-Paper-Only (DOPO) Handling
When two or more students in the same class roster share the same name during a single roster upload session:
- Generate a short
dedupe_codefor colliding seats. - Store that code on the seat.
- Include the code in the fingerprint input for the affected seats.
- Teacher communicates the code to the affected students during claim.
Claim Flow
- Student enters join code, first name, last name, and optional dedupe code.
- Backend resolves class context from the join code.
- Backend normalizes the entered name and computes
roster_fingerprint. - Backend looks up the matching seat in that class.
- If exactly one seat matches, claim proceeds.
- If duplicate-name seats exist, dedupe code is required to disambiguate.
- On successful claim, the seat is bound to
user_idand marked withclaimed_at; clear claim first/last-name hashes,roster_fingerprint, anddedupe_codein the same transaction. The same cleanup applies to authenticated class binding. Recovery and display-name edits SHALL NOT regenerate claim artifacts. - Credential setup activates login on
usersonly after server-authoritative username retention verification (FEAT-IDEN-002 / SPEC-IDEN-001). Temporary username staging is memory-only under INV-ARC-018 §IX; neither the browser cookie nor a database row may retain a readable student username. - Initialize
last_active_class_idandlast_active_seat_idto the newly bound class and seat context (per DOM-IDEN-006 §XIII, identity lifecycle documents define how these pointers are initialized).
The identity inference prohibition defined in DOM-IDEN-005 §VII applies: unauthenticated claim SHALL NOT search for or infer existing User identities outside the current claim transaction.
Student Seat State
Student seat state is limited to:
- unclaimed —
user_id IS NULL,claimed_at IS NULL - claimed —
user_id IS NOT NULL,claimed_at IS NOT NULL
No intermediate states, soft deletes, archived identities, or dormant participants exist.
Participation and Visibility of an Unclaimed Seat
An unclaimed seat is a teacher-provisioned placeholder whose runtime participation has not been activated (DOM-IDEN-005 §VII, INV-CORE-000). It is therefore not a valid participant in the class economy, and:
- No economic participation. An unclaimed seat SHALL NOT be the subject of any economic event — payroll, manual credit, class-wide bonus, savings interest, obligation assessment, entitlement grant — nor of attendance, which is paid time. Enforcement is fail-closed at the domain command, not left to each caller’s roster query.
- No display outside roster management. An unclaimed seat SHALL NOT appear in any teacher-facing count, total, aggregate, list, log or history. The sole exemptions are the Student Management roster (including its unclaimed-seat section), roster export intended for re-import, and terminal roster deletion accounting, which counts claimed and unclaimed seats alike (DOM-CLASS-001).
- Records are retained, not displayed. Exclusion is a filter, never a deletion. Unclaim preserves the seat’s economic, productivity and support facts (DOM-IDEN-005 §Explicit Unclaim, INV-ARC-019), and a balance retained this way remains the seat’s own on re-claim. Wiping, sweeping or reassigning it is prohibited: re-claim is an expected lifecycle event, not a forfeiture.
user_idis the test. An unclaimed seat holds an emptyuser_id. Economic reads, writes and histories filter on claim state explicitly; it is never inferred from the presence of activity rows, which unclaim preserves.
IX. Student Account Recovery
Important
Student account recovery operates solely on users table, which represents the authenticated principal on Classroom Token Hub. does not require class context, participation state, or personally identifiable information (PII). Any implementation of additional look up is prohibited by this document.
Recovery restores credential access to an existing student users identity and therefore seats bound to the users identity. Per DOM-IDEN-005 §IX, recovery restores authentication capability without altering participation, ownership, or identity bindings.
Core Invariants
- No new PII or external identity linkage. Recovery methods SHALL NOT require additional information not already collected by the platform.
- Ledger immutability. Recovery SHALL NOT modify, delete, merge, or rewrite historical economic records.
- Credential restoration only. Recovery replaces credential access on the same
usersrecord. It does not create a new user, create a new seat, merge two records, or transfer economic state. Per DOM-IDEN-005 §IX, recovery SHALL NOT modify participation, ownership, or identity bindings. - Single active code. Only one active reset code per student identity at any time. New code generation will overwrite the existing code.
- Teacher-initiated. Students cannot self-initiate recovery. A teacher must generate the reset code.
What Is Recoverable
Student recovery restores access to an existing users row. All economic state remains attached to the same seat_id and class_id.
Credentials that are fully replaced during recovery:
username_hash/username_lookup_hashpin_hashpassphrase_hash
Records that are NOT touched during recovery:
- Economic records (transactions, ledger balance snapshot)
- Entitlement records (student items, student insurance)
- Attendance records (attendance sessions, hall pass logs, seat attendance state)
- Obligation records (rent payments, insurance claims)
Recovery Flow
Step 1 — Teacher initiates
A teacher with an active administrative seat in the student’s class initiates a recovery reset for a claimed student seat. The system:
- Resolve the selected student Seat to its bound User, then issue a new recovery capability on the corresponding users row.
- Generates a new 8-character random alphanumeric reset code
- Clear any outstanding recovery-session nonce verifier and expiry, invalidating that session.
- Fill in
reset_codefield with generated code. Overwrites any existing reset code - Sets
reset_code_generated_at = now - Sets
reset_code_expires_at = reset_code_generated_at + 10 minutes
The code is displayed to the teacher and communicated verbally to the student. The teacher may redisplay the code until it expires or the student accepts it.
Note
Reset codes are short-lived (10-minute TTL), teacher-visible, and communicated in person. Plaintext storage is acceptable for this handoff artifact.
Step 2 — Student submits reset code
Student submits reset code. Backend validates:
- The submitted reset code matches the active recovery code on exactly one
usersrow. - Code has not been used
- Code has not expired (
now < reset_code_expires_at)
On failure: return a generic failure message. Do not reveal whether a specific identity exists.
On acceptance, atomically consume the code and all its timestamps and create a unique recovery-session nonce. Store only its verifier and expiry on the same User; place the nonce and User reference in the accepting browser session. The server record is the source of truth: every setup step must validate the session nonce against it. The nonce inherits the code’s original ten-minute deadline; acceptance does not extend it. Existing credentials remain unchanged.
A new session cannot reuse the consumed code. Losing or abandoning the authorized session, expiration, or teacher reissuance requires a new teacher-issued code. No Seat, class, or IdentityProfile lookup is permitted during student recovery.
Step 3 — Credential re-establishment
Student proceeds through the standard credential setup flow:
- Username
- PIN
- Passphrase
No identity verification fields (name, DOB, or any PII) are re-entered. All three credentials are fully replaced atomically. Old credentials become invalid immediately.
Step 4 — Completion
On successful credential setup:
- Validate and consume the server-held recovery-session nonce verifier and expiry
- Regenerate
current_session_nonce - Replace
users.username_hash,users.username_lookup_hash,users.pin_hash, andusers.passphrase_hashatomically - Log successful reclaim event without code, nonce, or verifier material
The nonce consumption, replacement of all credential fields, and session-nonce rotation commit in one transaction. Concurrent completion has exactly one winner. Failure rolls back all changes; the same authorized session may retry within its original deadline. The original recovery code remains consumed.
Recovery Security Constraints
- Reset codes must be random and non-sequential.
- Reset codes are single-use — consumed when accepted, before credential setup.
- Recovery-session nonces are single-use and server-validated; cleared on completion or teacher reissuance, unusable after expiry.
- Hard TTL: 10 minutes.
- Rate-limit reset code generation and submission.
- Lock recovery flow after repeated failed submission attempts per identity.
- Never reveal whether a specific student identity exists via error messages.
Recovery Hard Boundaries
The student recovery system SHALL NOT:
- Create a new identity record during recovery
- Merge two identity records automatically
- Transfer balances between accounts
- Copy, recreate, or void items or entitlements
- Issue refunds during recovery
- Modify transaction history
- Adjust economic balances
- Collect or verify DOB at any point
X. Credential Summary
| Credential | Student |
|---|---|
| Username | username_hash / username_lookup_hash |
| Sign-in | Username + passphrase (passphrase_hash) |
| Irreversible expense actions | Passphrase (passphrase_hash) |
| Non-monetary and reversible actions | PIN (pin_hash) |
| Recovery | Teacher-initiated reset code → credential re-establishment |
| Session | Nonce + fixed-window expiry |
XI. Forbidden Patterns
- Separate
studentstable as identity authority (legacy migration artifact) - Domain tables keyed primarily by
seat_idandclass_id - Separate roster-stage and claim-stage participant tables that duplicate
seat - Business tables using
join_codeas an internal foreign key after class resolution - DOB or DOB-derived fields for any purpose
- Merging or inferring identity across class boundaries during claim
XII. Amendment
Revisions to this document SHALL:
- Increment the version.
- Update the effective date.
- Maintain consistency with DOM-IDEN-001 and DOM-IDEN-005.
- Maintain consistency with INV-CORE-000.
Version 2.9 (2026-09-29): students sign in with username and passphrase (operator ruling, 2026-09-28). Version 2.8 and earlier said username and PIN at §VII and §X, contradicting FEAT-IDEN-002’s credential matrix and the implementation. §VII’s financial-action gate now defers to that matrix; it had listed transfers, which use the PIN.
Version 2.8 (2026-09-29): §VIII Claim Flow step 8: credential setup activates login only after server-authoritative username retention verification (FEAT-IDEN-002 / SPEC-IDEN-001). Temporary username staging is memory-only under INV-ARC-018 §IX.
Last updated: 2026-10-14