# Uwierzytelnianie i OAuth

> Klucze API, OAuth 2.1 z PKCE (SMART on FHIR standalone launch), OpenID Connect id_token, zakresy SMART v2 dla pacjentów, czas życia tokenów i cykl życia zgody.

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

Platforma Anpheros akceptuje trzy rodzaje poświadczeń. Każde żądanie zawiera dokładnie jedno.

| Poświadczenie | Wygląda jak | Kto | Widzi |
|---|---|---|---|
| Klucz API | `sk_test_…` (sandbox) / `sk_live_…` (production) | serwer projektu | pacjentów, których projekt utworzył (w sandboxie, w tym własną kopię 30 syntetycznych pacjentów) |
| Token dostępu OAuth | `at_…` | aplikacja działająca dla jednego pacjenta w ramach zgody | tylko tego pacjenta, w ramach przyznanych zakresów SMART |
| Token Firebase ID | JWT | deweloper w panelu, lub pacjent w sekcji "Połączenia" | swoje własne organizacje / swoje własne rekordy |

Wyślij go jako `Authorization: Bearer <credential>` (klucze API działają również jako `X-Api-Key`).

## Klucze API
- Tworzone w panelu lub przez `POST /admin/projects/{id}/keys`; wyświetlane raz; przechowywane jako skrót SHA-256.
- Zakresy: `read`, `write`. Klucz nigdy nie przekracza środowiska swojego projektu (`sk_test_` nie może uzyskać dostępu do danych produkcyjnych i odwrotnie).
- Limit żądań na klucz (domyślnie 600/min) jest egzekwowany w całej platformie (współdzielony magazyn), z `Retry-After` na 429. Istnieje również limit na adres IP wynoszący 600/min.
- Opcjonalne nagłówki przy zapisie: `X-Anpheros-Author-Type`, `X-Anpheros-Author-Ref`, `X-Anpheros-Source-System`, `X-Anpheros-Origin-Id`, `X-Anpheros-Acting-As` (Practitioner/PractitionerRole **z własnego katalogu**), `X-Anpheros-On-Behalf-Of` (Organization z własnego katalogu). Wypełniają one 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]`
   Wyświetla hostowaną stronę zgody. PKCE S256 jest obowiązkowe; `redirect_uri` musi być zarejestrowane dokładnie.
2. Pacjent loguje się (Google lub e-mail przez Firebase), wybiera rekord (własny lub zależnego), czas trwania (30/90/180/365 dni) i zezwala. Platforma wydaje jednorazowy kod (10 minut).
3. `POST /oauth/token` z `grant_type=authorization_code&code=…&code_verifier=…&redirect_uri=…&client_id=…` (klienci poufni dodają `client_secret`).
   Odpowiedź: `access_token` (30 min), `refresh_token` (30 dni, rotacyjne), `patient` (Twoje identyfikatory parami dla rekordu), `grant_id`, `scope`.
4. Odświeżanie: `grant_type=refresh_token`. Każdy token odświeżania jest jednorazowy. **Przedstawienie użytego tokenu odświeżania unieważnia cały łańcuch** (wykrywanie kradzieży). Równoległe duplikaty żądania odświeżenia są odrzucane i mogą również unieważnić łańcuch, dlatego nigdy nie należy rotować równocześnie.
5. Unieważnienie: `POST /oauth/revoke` (token + client_id). Unieważnienie tokenu odświeżania unieważnia również jego tokeny dostępu.

Odpowiedzi tokenów zawierają `Cache-Control: no-store` i `Pragma: no-cache`, zgodnie z wymaganiami SMART.

### OpenID Connect (`openid fhirUser`)
Poproś o `openid fhirUser` obok zakresów pacjenta, a odpowiedź tokenu zawiera również `id_token`: JWT podpisany RS256, z `iss` (podstawowy adres URL platformy), `sub` (Twój identyfikator parami dla osoby), `aud` (Twój `client_id`), `exp`, `iat` i `fhirUser` — absolutny adres URL zasobu Pacjenta osoby, czytelny za pomocą właśnie otrzymanego tokenu dostępu. Discovery znajduje się pod adresem `GET /.well-known/openid-configuration`; klucze publiczne pod adresem `GET /oauth/jwks` (`kid` w nagłówku tokenu). Parametr `nonce` nie jest jeszcze obsługiwany (jest opcjonalny w przepływie authorization-code). `launch/patient` i `offline_access` są akceptowane; pole `patient` odpowiedzi tokenu to kontekst uruchomienia.

Inne typy grantów: `client_credentials` (klienci poufni; działa jak klucz API) i grant tożsamości pierwszej strony (tylko zaufani klienci).

### Twoja marka na stronie zgody

Aplikacja może wyświetlać swoje logo i kolor akcentu na hostowanej stronie zgody. Ustaw je w konsoli
(Applications → Brand) lub za pomocą API administratora:

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

- **Logo:** obraz PNG, JPEG lub WebP jako URI danych, do 64 KB. Sprawdzana jest zawartość, a nie zadeklarowany typ;
  SVG nie jest akceptowany. Obraz jest przechowywany wraz z aplikacją i osadzany na stronie, dzięki czemu strona zgody
  nie wysyła żadnych żądań do Twoich serwerów.
- **Kolor akcentu:** `#RRGGBB`, używany dla głównego przycisku. Biały tekst na nim musi zachować kontrast co najmniej
  4,5:1 (WCAG AA); jaśniejsze kolory są odrzucane.
- Pole, które pozostawisz puste, pozostaje bez zmian; `null` lub pusta wartość ciągu znaków usuwa je.

Reszta strony pozostaje niezmieniona: wiersz "Secured by Anpheros Platform", lista w języku potocznym
tego, o co prosi aplikacja, oraz baner TEST na projektach sandbox pozostają, dzięki czemu ludzie zawsze mogą stwierdzić, że zgoda jest zarządzana przez Anpheros. Połączenia AI (MCP) zawsze wyświetlają stronę Anpheros bez marki aplikacji.

### Zakresy
Zakresy pacjenta SMART v2: `patient/<Type>.<cruds>` z opcjonalnym filtrem `?category=<code>` (jedyny filtr egzekwowany przez serwer; każdy inny filtr jest odrzucany w momencie autoryzacji). `patient/*.rs` odczytuje wszystko; `offline_access` dodaje token odświeżania. Dane demograficzne pacjenta i katalog są zawsze czytelne w ramach grantu. Typ zasobu spoza grantu zwraca 403; pacjent spoza grantu zwraca 404.

### Cykl życia zgody
Zgody wygasają automatycznie, mogą zostać unieważnione przez pacjenta w dowolnym momencie (ekran Połączenia / `/me`), a każdy odczyt w ramach zgody jest rejestrowany z identyfikatorem aplikacji. Webhooki `consent.granted` / `consent.revoked` powiadamiają projekt.

## Błędy
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`). Zobacz [`errors.md`](https://developers.anpheros.com/pl/guides/errors).
