# Admin credential authentication handoff

## Current production state

`admin.gorbushka.market` can authenticate through the existing Telegram
session flow. Login/password authentication is not implemented by the live
backend, so the frontend must not validate or embed administrator credentials.

The existing `/admin-login` Ed25519 page is also not production-ready because
the backend challenge/verify endpoints do not exist.

## Required backend API

Tenant identity comes only from nginx's trusted `X-Storefront-Host` header.
Never accept a tenant or marketplace identifier from the login request body.

### Create session

```http
POST /api/identity/v1/session
Content-Type: application/json

{
  "login": "gorbushka",
  "password": "<secret>"
}
```

Success:

```json
{
  "accessToken": "<short-lived JWT>",
  "refreshToken": "<rotating opaque token>",
  "expiresAt": "2026-08-21T04:00:00Z",
  "mustChangePassword": true,
  "user": {
    "id": "<id>",
    "login": "gorbushka",
    "displayName": "Gorbushka administrator",
    "roles": ["MARKETPLACE_ADMIN"],
    "tenantId": "<tenant-id>"
  }
}
```

Errors:

- `400` malformed request.
- `401 INVALID_CREDENTIALS` with one generic message for unknown login and
  wrong password.
- `403 TENANT_DISABLED` or `TENANT_MISMATCH`.
- `429 RATE_LIMITED` with `Retry-After`.

### Session lifecycle

```http
POST   /api/identity/v1/session/refresh
DELETE /api/identity/v1/session
POST   /api/identity/v1/session/change-password
GET    /api/identity/v1/session/permissions
```

`change-password` accepts `{ currentPassword, newPassword }`. While
`mustChangePassword` is true, every non-auth admin endpoint returns
`403 PASSWORD_CHANGE_REQUIRED`.

## Provisioning and security requirements

- Generate a random one-time bootstrap password. Do not use the documented
  deterministic `{slug}2026$` pattern in production.
- Store only an Argon2id password hash with a unique salt.
- Never log passwords, refresh tokens, authorization headers, or session IDs.
- Rate-limit by tenant, login, and source IP; add exponential backoff.
- Rotate refresh tokens and revoke the full token family on reuse.
- Enforce tenant and role authorization on every admin endpoint. Angular
  guards are UI only.
- Audit login success/failure, password change, refresh-token reuse, logout,
  and lockout without recording secrets.

## Required nginx invariants

Backend nginx changes must preserve:

```nginx
proxy_set_header X-Storefront-Host $storefront_host;
proxy_set_header Origin "";

add_header Access-Control-Allow-Headers \
  "Authorization, Content-Type, AdminWebSessionID, WebSessionID, Currency, X-Language, X-Region, X-Requested-With" always;
```

For `Origin: https://admin.gorbushka.market`, `$storefront_host` must be
`gorbushka.market`. The API upstream remains `https://127.0.0.1:445` unless
the backend team deliberately changes the listening address.

## Frontend follow-up after backend delivery

Add the credential form to the admin-only login shell, submit only over HTTPS,
store the returned admin session separately from customer auth, force the
password-change screen when requested, and keep Telegram as an optional
fallback. Do not expose a non-functional credential form before the API ships.
