# Автентифікація та OAuth

> API ключі, OAuth 2.1 з PKCE (SMART on FHIR standalone launch), OpenID Connect id_token, SMART v2 patient scopes, терміни дії токенів та життєвий цикл згоди.

Source: https://developers.anpheros.com/uk/guides/authentication

Anpheros Platform приймає три типи облікових даних. Кожен запит містить рівно один.

| Облікові дані | Виглядає як | Хто | Бачить |
|---|---|---|---|
| API ключ | `sk_test_…` (sandbox) / `sk_live_…` (production) | сервер проєкту | пацієнтів, створених проєктом (у sandbox, включаючи власну копію 30 синтетичних пацієнтів) |
| OAuth access token | `at_…` | застосунок, що діє від імені одного пацієнта за згодою | тільки цього пацієнта, в межах наданих SMART scopes |
| Firebase ID token | JWT | розробник у панелі керування або пацієнт у розділі "Connections" | свої власні організації / свої власні записи |

Надсилайте його як `Authorization: Bearer <credential>` (API ключі також працюють як `X-Api-Key`).

## Ключі API
- Створюються на панелі керування або через `POST /admin/projects/{id}/keys`; показуються один раз; зберігаються як хеш SHA-256.
- Області дії: `read`, `write`. Ключ ніколи не перетинає середовище свого проєкту (`sk_test_` не може отримати доступ до виробничих даних і навпаки).
- Ліміт запитів на ключ (за замовчуванням 600/хв) застосовується в масштабах платформи (спільне сховище), з `Retry-After` на 429. Також існує ліміт на IP-адресу 600/хв.
- Необов'язкові заголовки для записів: `X-Anpheros-Author-Type`, `X-Anpheros-Author-Ref`, `X-Anpheros-Source-System`, `X-Anpheros-Origin-Id`, `X-Anpheros-Acting-As` (Practitioner/PractitionerRole **з вашого власного каталогу**), `X-Anpheros-On-Behalf-Of` (Organization з вашого власного каталогу). Вони заповнюють Provenance.

## OAuth 2.1 (SMART on FHIR, standalone launch)
Discovery: `GET /.well-known/smart-configuration`.

1. `GET /oauth/authorize?response_type=code&client_id=…&redirect_uri=…&scope=…&state=…&code_challenge=…&code_challenge_method=S256[&purpose=treatment][&patient=<pairwise id>][&lang=ro]`
   Відображає сторінку згоди, що розміщена на платформі. PKCE S256 є обов'язковим; `redirect_uri` має бути зареєстровано точно.
2. Пацієнт входить в систему (через Google або електронну пошту за допомогою Firebase), обирає запис (власний або залежної особи), тривалість (30/90/180/365 днів) та надає дозвіл. Платформа видає одноразовий код (10 хвилин).
3. `POST /oauth/token` з `grant_type=authorization_code&code=…&code_verifier=…&redirect_uri=…&client_id=…` (конфіденційні клієнти додають `client_secret`).
   Відповідь: `access_token` (30 хв), `refresh_token` (30 днів, ротується), `patient` (ваш парний ідентифікатор для запису), `grant_id`, `scope`.
4. Оновлення: `grant_type=refresh_token`. Кожен токен оновлення використовується один раз. **Пред'явлення використаного токена оновлення анулює весь ланцюжок** (виявлення крадіжки). Паралельний дублікат запиту на оновлення відхиляється і може також анулювати ланцюжок, тому ніколи не ротуйте одночасно.
5. Анулювання: `POST /oauth/revoke` (token + client_id). Анулювання токена оновлення також анулює його токени доступу.

Відповіді токенів містять `Cache-Control: no-store` та `Pragma: no-cache`, як того вимагає SMART.

### OpenID Connect (`openid fhirUser`)
Запитуйте `openid fhirUser` поряд зі скоупами пацієнта, і відповідь токена також міститиме `id_token`: JWT, підписаний RS256, з `iss` (базовий URL платформи), `sub` (ваш парний ідентифікатор особи), `aud` (ваш `client_id`), `exp`, `iat` та `fhirUser` — абсолютний URL ресурсу Patient особи, який можна прочитати за допомогою токена доступу, який ви щойно отримали. Discovery знаходиться за адресою `GET /.well-known/openid-configuration`; публічні ключі за адресою `GET /oauth/jwks` (`kid` у заголовку токена). Параметр `nonce` ще не підтримується (він є необов'язковим у потоці authorization-code). `launch/patient` та `offline_access` приймаються; поле `patient` відповіді токена є контекстом запуску.

Інші типи грантів: `client_credentials` (конфіденційні клієнти; поводиться як ключ API) та грант ідентифікації першої сторони (тільки довірені клієнти).

### Ваш бренд на сторінці згоди

Додаток може відображати свій логотип та акцентний колір на сторінці згоди, що розміщена на платформі. Встановіть їх у консолі
(Applications → Brand) або за допомогою адміністративного API:

```http
PUT /admin/applications/{application_id}/branding
{"logo": "data:image/png;base64,…", "brand_color": "#1D4ED8"}
```

- **Логотип:** зображення у форматі PNG, JPEG або WebP як data URI, розміром до 64 КБ. Перевіряється вміст, а не заявлений тип;
  SVG не приймається. Зображення зберігається разом із додатком і вбудовується на сторінку, тому сторінка згоди
  не робить запитів до ваших серверів.
- **Акцентний колір:** `#RRGGBB`, використовується для основної кнопки. Білий текст на ньому повинен зберігати контраст щонайменше
  4.5:1 (WCAG AA); світліші кольори відхиляються.
- Поле, яке ви залишаєте порожнім, залишається як є; `null` або порожній рядок видаляє його.

Решта сторінки не змінюється: рядок "Secured by Anpheros Platform", список простими словами того, що запитує додаток, та банер TEST на пісочних проектах залишаються, тому люди завжди можуть зрозуміти, що згода надається Anpheros. AI-з'єднувачі (MCP) завжди відображають сторінку Anpheros без бренду додатка.

### Скоупи
Скоупи пацієнта SMART v2: `patient/<Type>.<cruds>` з необов'язковим фільтром `?category=<code>` (єдиний фільтр, який сервер застосовує; будь-який інший фільтр відхиляється під час авторизації). `patient/*.rs` читає все; `offline_access` додає токен оновлення. Демографічні дані пацієнта та каталог завжди доступні для читання під час надання гранту. Тип ресурсу поза грантом повертає 403; пацієнт поза грантом повертає 404.

### Життєвий цикл згоди
Згоди автоматично закінчуються, можуть бути анульовані пацієнтом у будь-який час (екран Connections / `/me`), і кожне читання під згодою логується з ідентифікатором додатка. Вебхуки `consent.granted` / `consent.revoked` сповіщають проект.

## Помилки
401 unknown/expired credential · 403 the credential exists but may not do this · 404 the resource does not exist *for you* · 429 rate limited (`Retry-After`). Див. [`errors.md`](https://developers.anpheros.com/uk/guides/errors).
