# Autentifikacija ir raktai

> Kaip siųsti raktą, koks jo formatas ir kaip veikia raktų gyvavimo ciklas.

Šaltinis: https://diko.app/api-docs/autentifikacija

## Bearer raktas

Kiekviena užklausa turi antraštę `Authorization` su `Bearer` schema. Rakto nereikia tik `GET /` ir `GET /openapi.json`:

```http
Authorization: Bearer dk_live_...
```

Taisyklės, kurios saugo jūsų raktą:

- **Priimama tik `Authorization: Bearer`.** Antraštė `X-API-Key` nepriimama, nes ji nutekėtų per peradresavimus.
- **Raktas negali būti URL.** Jei jis yra užklausos eilutėje (`api_key`, `key`, `token`, `access_token`), API grąžina 400 `api_key_in_query`. Tokį raktą laikykite nutekėjusiu ir jį [rotuokite](https://diko.app/api-docs/saugumas.md#rakto-rotacijos-receptas).
- **Raktas nenaudojamas naršyklėje.** API negrąžina `Access-Control-*` antraščių, o `OPTIONS` užklausa gauna 405. Raktą visada naudokite iš savo serverio.

## Rakto formatas

Raktas atrodo taip: `dk_live_` ir 49 simboliai `[0-9A-Za-z]`, iš viso 57 simboliai.

| Dalis | Ilgis | Paskirtis |
|---|---|---|
| `dk_live_` | 8 | priešdėlis, pagal kurį raktą atpažįsta žmonės ir paslaptų skeneriai |
| atsitiktinė dalis | 43 | 256 bitų atsitiktinumas |
| kontrolinė suma | 6 | Base62 CRC32 (big-endian, papildyta nuliais) |

Reguliarioji išraiška: `^dk_live_[0-9A-Za-z]{49}$`. Kontrolinė suma leidžia atmesti rašybos klaidą ir aptikti raktą kode be tinklo užklausos. Priešdėlis `dk_test_` rezervuotas ateičiai; smėlio dėžės v1 nėra.

Diko saugo tik rakto SHA-256 maišą ir užuominą (`dk_live_Ab12…9xYz`). Pats raktas niekada nerašomas į žurnalus, el. laiškus ar klaidų atsakymus.

## Raktų kūrimas

Raktus kuriate Diko programėlėje, skiltyje **Nustatymai → API**, adresu [`/settings/api`](https://studio.diko.app/settings/api). Senoji nuoroda `/kurejams` vis dar veikia ir nukreipia čia. Forma prašo:

| Laukas | Reikalavimai |
|---|---|
| Pavadinimas | 1–100 simbolių |
| Aprašas | neprivalomas, iki 500 simbolių |
| Leidimai | pasirinkite šabloną arba atskirus leidimus; žr. [Leidimai](https://diko.app/api-docs/leidimai.md). Po sukūrimo jų pakeisti negalima |
| Galiojimas | 7, 30, **90** (numatytasis), 180 arba 365 dienos, arba data. Daugiausia 365 dienos, „niekada“ nėra. Galiojimą galima tik sutrumpinti |
| IP apribojimas | neprivalomas, iki 20 CIDR įrašų; kur jis veikia, žr. [Saugumo gairės](https://diko.app/api-docs/saugumas.md#ip-apribojimas) |

Sukūrus raktas parodomas **vieną kartą**. Kol nepažymėsite langelio **Išsaugojau raktą saugioje vietoje**, programėlė neleis uždaryti lango. Kūrimui, rotacijai, įjungimui ir IP sąrašo keitimui programėlė gali paprašyti pakartotinio patvirtinimo (galioja 10 minučių). Atšaukimas, išjungimas ir pervadinimas patvirtinimo nereikalauja, kad saugūs veiksmai būtų greiti.

**Ribos:** daugiausia 25 raktai (aktyvūs ir išjungti kartu). Pasibaigę, atšaukti ir rotacijos persidengimo metu veikiantys seni raktai neskaičiuojami. Per valandą galima sukurti ar rotuoti daugiausia 10 raktų.

## Rakto objektas

`GET /me` grąžina raktą, kuriuo pateikta užklausa. Pats raktas, žinoma, neparodomas:

```json
{
  "id": "key_4Vf9771zpS8JcQdtUcR0u8",
  "object": "api_key",
  "name": "CRM sync",
  "description": "",
  "hint": "dk_live_Ab12…9xYz",
  "scopes": ["meetings:read", "library:read"],
  "status": "active",
  "allowed_cidrs": [],
  "created_at": "2026-10-11T09:00:00.000Z",
  "expires_at": "2027-01-09T09:00:00.000Z",
  "last_used_at": null,
  "last_used_ip": null,
  "first_used_at": null,
  "disabled_at": null,
  "revoked_at": null,
  "revoked_reason": null,
  "rotated_from": null,
  "grace_until": null
}
```

Likusi `GET /me` atsakymo dalis taip pat laikosi mažiausių privilegijų principo. Todėl trečiajai šaliai perduotas raktas neatskleidžia paskyros savininko duomenų. `user.email` visada paslėptas (`j***@example.com`). `credits` yra `null`, nebent raktas turi leidimą `library:write`, vienintelį, kuris naudoja kreditus.

## Būsenos

| Būsena | Reikšmė |
|---|---|
| `active` | raktas veikia |
| `disabled` | laikinai išjungtas; galima įjungti vėl (reikia pakartotinio patvirtinimo) |
| `revoked` | galutinai atšauktas; `revoked_reason` nurodo priežastį |
| `expired` | išvestinė būsena: `expires_at` jau praėjo |

`revoked_reason` reikšmės: `user` (atšaukėte jūs), `rotated` (pasibaigė rotacijos persidengimas), `admin` (atšaukė komandos administratorius), `owner` (atšaukė komandos savininkas), `user_disabled` (paskyra išjungta), `leaked` (aptiktas nutekėjimas), `dormant` (ilgai nenaudotas), `revoke_all` (veiksmas **Atšaukti visus raktus**).

## Galiojimas, priminimai ir nenaudojami raktai

- Likus 7 ir 1 dienai iki galiojimo pabaigos Diko išsiunčia el. laišką (tik jei galiojimas buvo bent 14 ir bent 2 dienų).
- Programėlė žymi raktą „Nenaudojamas“, jei jis nenaudotas 90 dienų. Raktas, nenaudotas 365 dienas, atšaukiamas automatiškai (`dormant`).
- Kiekvienas raktas turi `last_used_at` ir naudojimo statistiką programėlėje, todėl pamirštas integracijas lengva pastebėti ir atšaukti. `last_used_at` atnaujinamas ne dažniau kaip kas 5 minutes, todėl jis gali atsilikti nuo tikro paskutinio kreipinio.

## Rotacija

Rotacija sukuria naują raktą ir leidžia senam dar kurį laiką veikti, kad spėtumėte atnaujinti sistemas be prastovos.

- **Persidengimas:** iškart, 1 val., **24 val.** (numatytasis) arba 7 d.
- Naujas raktas paveldi pavadinimą, aprašą, leidimus ir IP sąrašą. Jis gauna tokią pat galiojimo trukmę kaip senasis (daugiausia 365 dienas), skaičiuojamą nuo rotacijos momento.
- Senas raktas gauna `grace_until` ir tampa `revoked` (`rotated`), kai laikas baigiasi.
- Vienu metu galima turėti tik vieną atvirą to paties rakto rotaciją.

Žingsnis po žingsnio receptas yra [Saugumo gairėse](https://diko.app/api-docs/saugumas.md#rakto-rotacijos-receptas).

## Importai, kai raktas nustoja veikti

Importas, sukurtas per `POST /library/imports`, gali trukti kelias minutes. Kai jį sukūręs raktas nustoja veikti, Diko sustabdo ir importą. Todėl nutekėjęs raktas negali toliau eikvoti kreditų per jau eilėje esančius darbus.

- **Šie veiksmai atšaukia rakto importus, kurie dar `queued` arba `processing`:** rakto atšaukimas (jūsų, komandos administratoriaus ar savininko, veiksmas **Atšaukti visus raktus** arba automatiškai po GitHub pranešimo apie nutekėjimą), išjungimas, ištrynimas, rotacija su persidengimu **iškart** ir paskyros išjungimas. Paskyros API prieigos sustabdymas atšaukia visų jos raktų importus.
- `queued` importas iškart tampa `canceled`. `processing` importas tampa `canceling`, o sustojus darbui baigiasi kaip `canceled`. Kiekvienas pabaigimas siunčia įvykį `library.import.canceled`.
- **Rotacija su persidengimu** (1 val., 24 val. arba 7 d.) importų nesustabdo. Senam raktui tapus `revoked` (`rotated`) pasibaigus persidengimui, importai taip pat neatšaukiami. Jei seną raktą atšaukiate patys persidengimo metu, jo importai atšaukiami kaip bet kurio atšaukto rakto.
- Jau atliktas darbas apmokestinamas kaip įprasta: transkriptas, kuris jau buvo gautas arba baigiamas, vis tiek patenka į jūsų biblioteką.

## Planas

API prieinamas **„Verslas“** plane. API atsakymuose planas žymimas reikšme `verslas`. Klaida `plan_required` nurodo jį lauke `required_plans`.

`GET /me` rodo dabartinę būseną lauke `access`:

- `access.plan` yra `asmeninis` (asmeninis planas, kuris API neapima), `verslas` arba `null`, kai paskyra plano neturi;
- `access.allowed` nurodo, ar API užklausos leidžiamos;
- `access.reason` nurodo priežastį. Prieigą suteikia `subscription` (prenumerata), `team` (komandos planas), `owner` ir `exempt` (paskyros, kurios nemoka) arba `paywall_off` (apmokėjimas išjungtas). Prieigą atmeta `subscription_required` arba `plan_required`.

Planas tikrinamas kiekvienos užklausos metu, todėl raktai nepašalinami keičiant planą: jie vėl veikia, kai planas leidžia. `GET /me` plano netikrina, todėl tinka diagnostikai.

## Autentifikacijos klaidos

| Situacija | HTTP | Kodas |
|---|---|---|
| Nėra antraštės `Authorization` | 401 | [`missing_api_key`](https://diko.app/api-docs/klaidos.md#missing_api_key) |
| Schema ne `Bearer`, tuščias raktas, kelios antraštės `Authorization`, blogas formatas ar kontrolinė suma arba nežinomas raktas | 401 | [`invalid_api_key`](https://diko.app/api-docs/klaidos.md#invalid_api_key) |
| Galiojimas pasibaigė | 401 | [`api_key_expired`](https://diko.app/api-docs/klaidos.md#api_key_expired) |
| Raktas atšauktas | 401 | [`api_key_revoked`](https://diko.app/api-docs/klaidos.md#api_key_revoked) |
| Raktas išjungtas | 401 | [`api_key_disabled`](https://diko.app/api-docs/klaidos.md#api_key_disabled) |
| IP nėra rakto sąraše | 403 | [`ip_not_allowed`](https://diko.app/api-docs/klaidos.md#ip_not_allowed) |
| Paskyra išjungta, el. paštas nepatvirtintas arba API prieiga sustabdyta | 403 | [`account_disabled`](https://diko.app/api-docs/klaidos.md#account_disabled), [`email_not_verified`](https://diko.app/api-docs/klaidos.md#email_not_verified), [`api_access_suspended`](https://diko.app/api-docs/klaidos.md#api_access_suspended) |
| Nėra apmokėtos prieigos | 402 | [`subscription_required`](https://diko.app/api-docs/klaidos.md#subscription_required) |
| Planas neapima API | 403 | [`plan_required`](https://diko.app/api-docs/klaidos.md#plan_required) |

401 atsakymai turi antraštę `WWW-Authenticate`: `Bearer realm="diko"`, kai antraštės `Authorization` nėra, ir `Bearer realm="diko", error="invalid_token"` kitais atvejais.

> **Pastaba:**
> Blogo formato raktas, nežinomas raktas ir netinkama antraštė gauna **tą patį** atsakymą, o IP apribojimas tikrinamas prieš rakto būsenos klaidas. Taip nutekėjęs raktas iš svetimo adreso nesužino, ar jis dar galioja.

Raktą atšaukus, išjungus ar rotavus, pakeitimas pasiekia API maždaug per **10 sekundžių**.
