# Design ## Context See proposal.md. The a2loft `cropper-token-auth` change adds token mode to the profile-picture endpoints: `Authorization: Bearer `, identity from the token's phone, authorized with OpenFGA `crop_image` on `domain:` then `domain:idid`. This change consumes it. ## Goals / Non-Goals **Goals:** the cropper saves with the session token and no OTP; the save's domain is a2loft's own record of the picture; the panel is truthful about the profile's domain. **Non-Goals:** the fingerprint wizard's OTP flow; the cropper's lookup (there is none — pictures come from the queue); removing OTP support in a2loft. ## Decisions 1. **Token sent from the server**, never exposed to the browser beyond the page's existing injected session: the proxy attaches `Authorization: Bearer ${req.session.token}`. 2. **Domain from a2loft, not the client**: `dims/picture/{uploadId}` is the record of the picture; its `domainCode` is the profile's identity domain and its `domain` is the picture target (`core`). Sent as `domainCode`, displayed as both. Falls back to the queue item's label when a2loft has no record (custom ids), guarded by a path-safety pattern. 3. **The `core → uc` alias is deleted**: `core` is a2loft's own pseudo-domain (special-cased in `getUserByPhoneAsync`/`updatePicture`), so rewriting it — as the old bot did for its own calls — changed attribution and the notification. Authorization no longer depends on the domain, so no alias is needed. 4. **Queue loads are enriched** with `domainCode` for display (one extra read-only a2loft call per picture). ## Risks / Trade-offs - [a2loft record unavailable for an upload] → falls back to the queue label under the path-safety check; the save still carries the token for authz. - [Operators outside the domain's super-users] → irrelevant now: the OpenFGA check with the `domain:idid` fallback authorizes them. ## Migration Plan Deploy a2loft first (dual-mode, no client change), then this change; the cropper saves without an OTP. Rollback = revert the proxy and re-add the field. ## Open Questions None.