Lewati ke isi

T0-D Credential Surface Inventory

Item Value
Mode Server development /home/scola/odoo
Scope Credential lifecycle / recovery / session security (T0-U07 / DEC-014)
Basis Implemented code + known surfaces (post T0-D core wiring)
Docs read development-guide.md, workspace-governance.md, architecture-api.md, T0-D-preflight.md

Classification legend

Code Meaning
SUPPORTED_CANONICAL Retained V1 customer/admin path; must stay tested
INTERNAL_OPERATIONAL Ops/platform only; not a school credential-recovery product surface
LEGACY_REMOVE Dead/stub UI or obsolete path; remove or stop exposing
UNSAFE_DISABLE Previously unsafe; fixed in T0-D (no shared defaults / no secret logs)
DUPLICATE_MERGE Multiple entry points; merged to one canonical where done
DECISION_REQUIRED Still needs product/security follow-up outside V1 freeze
NOT_IMPLEMENTED / EXCLUDED Absent or explicitly out of V1; must stay absent/denied

A. Session / login

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
AUTH-LOGIN /login Login.vue; SPMB login POST /api/auth/login anon → user Authenticate public allowlist SUPPORTED_CANONICAL Session rotate + active-role bind app logs on error Payload includes must_change_password
AUTH-SESSION auth bootstrap POST /api/auth/session anon/authed Hydrate session public allowlist SUPPORTED_CANONICAL read-only Exposes force-change flags
AUTH-SESSION-PROBE api probe POST /api/auth/session-probe authed Cookie liveness auth=user SUPPORTED_CANONICAL none
AUTH-LOGOUT auth.service.logout POST /api/auth/logout authed Logout + clear active role public allowlist / auth=user SUPPORTED_CANONICAL clear_session_active_role + session.logout DUPLICATE_MERGE fixed: FE no longer prefers Odoo /auth/logout as primary
AUTH-SWITCH-ROLE RoleSwitcher POST /api/auth/switch-role authed Acting role switch authed SUPPORTED_CANONICAL (non-password) session role update warning logs Owned by T0-B; listed for adjacency only

B. Self-service password + force change

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
PWD-CHANGE-SELF ChangePassword.vue POST /api/auth/change-password self old→new; clear must_change users.profile.view SUPPORTED_CANONICAL revoke other sessions; keep current sid FE toast password_change audit Min length 8
PWD-FORCE-GATE App.vue non-dismissible dialog flag from login/session user with temp/force flag Block app until change authed SUPPORTED_CANONICAL none until change Driven by scola_must_change_password
PWD-REGISTER-STUB /register Register.vue public Empty stub public LEGACY_REMOVE n/a n/a n/a Not part of credential V1

C. Public forgot / reset

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
PWD-RESET-REQUEST /forgot-password ForgotPassword.vue POST /api/auth/password-reset/request public Request reset mail public allowlist SUPPORTED_CANONICAL none email if usable address password_reset_request (success/noop) Anti-enumeration: same success shape for exist / missing / disabled
PWD-RESET-CONFIRM /reset-password ResetPassword.vue POST /api/auth/password-reset/confirm public Consume token + set password public allowlist SUPPORTED_CANONICAL revoke all sessions for target password_reset_confirm Hash-at-rest token; single-use; TTL; purpose=password_reset
RECOVERY-TOKEN-SVC scola.credential.recovery.token + credential_token.py system Issue/validate tokens system SUPPORTED_CANONICAL n/a n/a issue logged without raw token Purposes: password_reset, activation, admin_reset

D. Admin reset / deactivate

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
PWD-ADMIN-RESET /admin/users modal; /admin/reset-password POST /api/v1/users/<id>/reset-password admin with user-mgmt authority Force reset users.manage / admin check SUPPORTED_CANONICAL revoke all target sessions no plaintext in response (DEC-014 §D: admin-provided ≥8; admin already knows the value) admin_reset Always scola_must_change_password=True; require password ≥8; no shared default
USER-DEACTIVATE UserList DELETE /api/v1/users/<id> admin Soft-disable admin SUPPORTED_CANONICAL revoke all sessions account_deactivate Disabled ≠ lockout policy
USER-ACTIVATE UserList PUT /api/v1/users/<id>/activate admin Soft-enable admin SUPPORTED_CANONICAL none app log Does not invent unlock-after-lockout
USER-CREATE-ADMIN UserFormModal POST /api/v1/users admin Create user + initial password admin DECISION_REQUIRED none Prefer random temp + must_change for V1 alignment (follow-up)

E. Parent / student account generation

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
ACCT-GEN-STUDENTS StudentList.vue CSV POST /api/v1/admin/accounts/generate-students admin Bulk student accounts admin SUPPORTED_CANONICAL none CSV; email skipped in bulk Temp passwords random (secrets); must_change set
ACCT-GEN-PARENTS ParentList.vue POST /api/v1/admin/accounts/generate-parents admin Bulk parent accounts admin SUPPORTED_CANONICAL none CSV UNSAFE_DISABLE fixed: no shared gbs123/gts123
ACCT-RESET-PARENTS ParentList.vue POST /api/v1/admin/accounts/reset-parent-passwords admin Re-issue parent temps admin SUPPORTED_CANONICAL (session revoke not yet bulk-wired — follow risk) CSV Random high-entropy only
ACCT-FACULTY-AUTO op.faculty._auto_create_user system/admin Auto teacher user internal UNSAFE_DISABLE fixed + INTERNAL_OPERATIONAL none info log without password Random password; not logged

F. SPMB OTP (separate from password reset)

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
SPMB-SIGNUP /spmb/register POST /api/SPMB/account/register public Applicant signup + password public allowlist SUPPORTED_CANONICAL creates user; login gated OTP email mail Not password-reset token
SPMB-VERIFY-OTP /spmb/verify-email POST /api/SPMB/account/verify-email public Email activation OTP public SUPPORTED_CANONICAL unlock login token model scola.spmb.email.token
SPMB-RESEND-OTP verify page POST /api/SPMB/account/resend-otp public Resend OTP public SUPPORTED_CANONICAL none OTP email Distinct channel from password_reset

G. Platform / foundation bootstrap

Surface ID FE BE Actor Purpose Auth Classification Session effect Notify Audit Notes
UNIT-CREATE-ADMIN Foundation school units POST /api/school/units/users/create-admin platform_operator / elevated Unit admin bootstrap elevated INTERNAL_OPERATIONAL none temp in response logs Uses must_change; not school self-service recovery
PLAT-SCHOOL-ADMIN-CREATE platform service POST /api/v1/platform/school-admins/create platform_operator School admin bootstrap elevated INTERNAL_OPERATIONAL none temporary_password JSON logs
FOUND-USER-LINK-CREATE Foundation HR POST /api/v1/foundation/hr/users/link-or-create foundation HR Link/create + temp foundation.users.manage SUPPORTED_CANONICAL (foundation domain) none must_change on create
FOUND-PWD-RESET-DEAD foundationHr.service.resetPassword Registry row without controller foundation HR (intended) Dead route registry only NOT_IMPLEMENTED / LEGACY_REMOVE n/a n/a n/a /api/v1/foundation/hr/users/reset-password — do not resurrect without DEC; use canonical admin reset

H. Explicitly excluded / not invented

Surface ID Presence Classification V1 posture
BREAK-GLASS-CREDENTIAL / customer login-as No customer credential break-glass UI/API EXCLUDED (EXCLUDED_AND_DENIED) Must remain absent/denied on customer surface
BREAK-GLASS-UNIT-RBAC _is_break_glass_admin for school-unit mutate INTERNAL_OPERATIONAL Not a password-recovery / impersonation product
IMPERSONATE / LOGIN-AS No implemented surface (comment-only elsewhere) EXCLUDED EXCLUDED_AND_DENIED
PWD-EXPIRY No periodic password expiry policy EXCLUDED / NOT_IMPLEMENTED Do not invent
PWD-LOCKOUT / unlock workflow No failed-attempt lockout product EXCLUDED / NOT_IMPLEMENTED Disabled account ≠ lockout; no customer unlock journey
LOGOUT-ALL dedicated API No separate logout-all route NOT_IMPLEMENTED Revocation is side-effect of reset/change/admin/deactivate via credential_session
OPS-SCRIPTS-PASSWORD provision/onboard/golden seed scripts INTERNAL_OPERATIONAL Secrets via env; never committed

I. Audit + ACL

Surface ID Model / service ACL Classification Notes
CRED-AUDIT-EVENT scola.credential.audit.event system-only (base.group_system in ir.model.access.csv) SUPPORTED_CANONICAL Never store passwords/raw tokens; unauthenticated request audits must not become enumeration oracles for normal users
CRED-TOKEN-ROW scola.credential.recovery.token system-only SUPPORTED_CANONICAL Hash only at rest

J. Classification summary (post-fix)

Classification Surfaces
SUPPORTED_CANONICAL login, session, probe, logout /api/auth/logout, change-password, force-change gate, public reset request/confirm, admin reset, deactivate(+revoke), activate, student/parent account gen, SPMB OTP trio, recovery token service, credential audit
INTERNAL_OPERATIONAL platform/unit admin bootstrap; break-glass unit RBAC; ops password scripts
LEGACY_REMOVE /register stub; foundation dead reset route (registry/FE leftover)
UNSAFE_DISABLE (fixed) shared GBS/GTS parent temps removed; faculty password plaintext logging removed
DUPLICATE_MERGE (fixed) FE logout → /api/auth/logout
DECISION_REQUIRED admin user-create must_change defaults; bulk parent-reset session revoke completeness
NOT_IMPLEMENTED / EXCLUDED customer break-glass, impersonation, password expiry, lockout/unlock product, dedicated logout-all API

K. Product exposure map (V1)

Task Canonical FE Canonical API
Login /login /api/auth/login
Session app bootstrap /api/auth/session
Logout auth store /api/auth/logout
Forced / self change ChangePassword.vue /api/auth/change-password
Forgot password /forgot-password /api/auth/password-reset/request
Reset with token /reset-password /api/auth/password-reset/confirm
Admin reset /admin/users / /admin/reset-password /api/v1/users/<id>/reset-password
Deactivate UserList DELETE /api/v1/users/<id>

SPMB OTP remains a separate activation channel and must not be conflated with password-reset tokens.