---
module: profile.security
title: Security
tab: Claude
order: 40
audience: dev
---

> **Internal · agent reference.** Confirmed against `hiveops-profile` frontend + `hiveops-auth` source 2026-07-01.

## Owner
- Service: **`hiveops-auth`** (port 8082, NGINX `/api/auth/`, DB `hiveiq_auth`).
- Frontend: `hiveops-profile/frontend` → `SecuritySettings.svelte` + `src/lib/api.ts` (`profileAPI`).
- No other service, **no Kafka**, no mgmt call for this screen.

## Endpoints (exact)
| Method | Path | Body | Guard |
|--------|------|------|-------|
| POST | `/auth/api/change-password` | `{newPassword, confirmPassword}` | authenticated (any role) |
| GET | `/auth/api/users/me/preferences` | — | authenticated |
| PUT | `/auth/api/users/me/preferences` | `{sessionTimeoutMinutes, ...}` | authenticated |

- Client sends `Authorization: Bearer <token>`; base URL = gateway (`__APP_CONFIG__.apiUrl`); paths already carry `/auth/api`.
- Identity = JWT principal email; no userId in body.

## Tables
- `users` — `password_hash`, `must_change_password`, `password_changed_at`; **`preferences` = one `jsonb` column** holding serialized `UserPreferences` POJO (`sessionTimeoutMinutes` is a JSON key inside it).
- `auth_audit_logs` — action `PASSWORD_CHANGED` per success.

## Topics
- None.

## Validation (server-authoritative)
- Password: **≥12 chars + uppercase + lowercase + digit + special** (`PasswordValidator`). Mismatch → `400 {"error":"Passwords do not match"}`; rule fail → `400 {"error":"Password must be at least 12 characters"}` (or specific rule).
- `sessionTimeoutMinutes`: `@Min(5) @Max(480)`.

## Gotchas
- Frontend + customer Overview claim **"min 8 characters"**; backend actually requires **12 + complexity**. Trust the backend (`PasswordValidator`).
- `change-password` does **not** verify current password — trusts the bearer JWT only.
- Success clears `must_change_password` and stamps `password_changed_at`.
- `GET .../preferences` returns default POJO (`sessionTimeoutMinutes=60`) when the user has no stored prefs — absence ≠ error.
- Session-timeout enforcement is client-side; auth JWT access TTL is 24h regardless.
- Admin/reset of *other* users is NOT here — that's `/auth/api/msp/**` (`MSP_ADMIN`/`BCOS_ADMIN`) or `/auth/api/admin/users/**` (`ADMIN`).

## Do NOT
- Do NOT tell users the password minimum is 8 — it is **12 + complexity**.
- Do NOT look for a `user_preferences` / `sessions` table — preferences are jsonb on `users`; there is none.
- Do NOT expect a Kafka event on password/preference change — there is none.
- Do NOT route this screen's calls through `mgmt`, `incident`, or `devices` — it is `hiveops-auth` only.
- Do NOT assume changing the timeout logs the user out server-side — it only stores a value.
- Do NOT PATCH other users' passwords via this endpoint — it always targets the JWT's own account.
