# Saugumo gairės

> Kaip laikyti raktus, rotuoti juos, ką daryti nutekėjus ir ką realiai gina IP apribojimas.

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

## Rakto laikymas

API raktas suteikia prieigą prie jūsų susitikimų ir bibliotekos, todėl su juo elkitės kaip su slaptažodžiu.

- **Laikykite paslapčių saugykloje** arba aplinkos kintamajame: debesies paslapčių tarnyboje, CI paslapčių nustatymuose arba `.env` faile, įtrauktame į `.gitignore`.
- **Niekada nedėkite rakto į kodą ar repozitoriją**, net į privatų. Istorija išlieka.
- **Niekada nenaudokite rakto naršyklėje, mobiliojoje programoje ar kitame kode, kurį gauna vartotojai.** API neleidžia naršyklės užklausų (nėra CORS), o raktas klientiniame kode nebėra paslaptis. Kvieskite API iš savo serverio.
- **Nedėkite rakto į URL, žurnalus, klaidų sekiklius, užklausų kopijas ir ekrano nuotraukas.** URL raktas ir taip atmetamas (400 [`api_key_in_query`](https://diko.app/api-docs/klaidos.md#api_key_in_query)). Komandų eilutėje raktą perduokite per aplinkos kintamąjį. Nenaudokite argumento, nes jį mato procesų sąrašas.
- **Vienas raktas vienai integracijai ir aplinkai.** Taip atšaukimas paliečia tik vieną sistemą.
- **Mažiausi reikalingi leidimai** (mažiausių privilegijų principas) ir trumpas galiojimas (žr. [Leidimai](https://diko.app/api-docs/leidimai.md)).

Diko laikosi to paties principo: saugo tik jūsų rakto SHA-256 maišą, o pats raktas niekada nerašomas į žurnalus, el. laiškus ar klaidų atsakymus. Webhook paslaptys saugomos užšifruotos.

## Rakto rotacijos receptas

Rotuokite raktus reguliariai ir kiekvieną kartą, kai kas nors, turėjęs prieigą, palieka komandą. Rotacija leidžia pakeisti raktą be prastovos, nes senas dar kurį laiką veikia.

1. **Sukurkite naują raktą.** Skiltyje **Nustatymai → API** ([`/settings/api`](https://studio.diko.app/settings/api)) rakto meniu pasirinkite **Rotuoti raktą**. Nurodykite persidengimą (numatyta 24 val.) ir patvirtinkite pakartotiniu prisijungimu. Naujas raktas paveldi pavadinimą, leidimus ir IP sąrašą ir parodomas vieną kartą. Senas raktas gauna žymą „Galioja iki …“.
2. **Įdiekite naują raktą.** Įrašykite jį į paslapčių saugyklą ir perdiekite savo sistemas.
3. **Patikrinkite.** Iškvieskite `GET /me`: `api_key.id` turi būti naujo rakto, o `api_key.rotated_from` – senojo. Programėlėje senojo rakto „paskutinis panaudojimas“ nebeturėtų atsinaujinti.
4. **Atšaukite seną raktą.** Atšaukite jį iškart, kai įsitikinote, kad niekas jo nebenaudoja, arba palaukite, kol pasibaigs persidengimas: tada jis automatiškai tampa `revoked` (`rotated`).

> **Patarimas:**
> Įtariate, kad raktas atsidūrė svetimose rankose? Rotuodami pasirinkite persidengimą **iškart** arba tiesiog atšaukite raktą ir sukurkite naują. Abu būdai iškart atšaukia seno rakto importus, kurie eilėje ar vykdomi. Rotacija su persidengimu jų nesustabdo.

Raktų galiojimas ribotas (daugiausia 365 dienos). Diko primena el. laišku likus 7 ir 1 dienai. Todėl rotacija tampa įprasta rutina, o ne skubiu gesinimu.

## Nutekėjęs raktas

Jei raktas galėjo nutekėti (patekęs į repozitoriją, žurnalą, ekrano nuotrauką ar išvykusio kolegos kompiuterį), veikite iškart:

1. **Atšaukite raktą** skiltyje **Nustatymai → API** (`/settings/api`). Atšaukimui pakartotinis patvirtinimas nereikalingas, kad tai būtų greita. Atšaukimas pradeda galioti maždaug per 10 sekundžių ir yra galutinis. Jis taip pat atšaukia rakto importus, kurie dar eilėje ar vykdomi, todėl nieko, ką raktas paleido, neeikvoja kreditų (žr. [Importai, kai raktas nustoja veikti](https://diko.app/api-docs/autentifikacija.md#importai-kai-raktas-nustoja-veikti)). Jei neaišku, kuris raktas nutekėjo, naudokite **Atšaukti visus raktus** puslapio apačioje.
2. **Sukurkite naują raktą** su mažiausiais reikalingais leidimais ir įdiekite jį.
3. **Peržiūrėkite naudojimą.** Rakto „paskutinis panaudojimas“, užklausų statistika ir skirtukas **Žurnalas** ([`/settings/api/zurnalas`](https://studio.diko.app/settings/api/zurnalas)) rodo, kada ir iš kur raktas buvo naudotas. IP rodomas tik kai Diko galėjo jį nustatyti patikimai.
4. **Peržiūrėkite webhooks** ir, jei abejojate, rotuokite jų paslaptis. Raktas negali pakeisti webhook endpointų, todėl adresai lieka tokie, kokius nustatėte.
5. **Pašalinkite priežastį.** Net ištrynus raktą iš kodo, jis lieka repozitorijos istorijoje, todėl laikykite jį nebetinkamu ir pasirūpinkite, kad tokia klaida nepasikartotų.

### GitHub secret scanning

Diko raktai turi atpažįstamą priešdėlį `dk_live_` ir kontrolinę sumą, todėl paslapčių skeneriai juos randa be klaidingų signalų. Diko turi GitHub secret scanning pranešimų priėmimo adresą. Kai GitHub aptinka Diko raktą viešoje repozitorijoje ir apie tai praneša, raktas **automatiškai atšaukiamas** (priežastis `leaked`), jo importai, kurie eilėje ar vykdomi, atšaukiami, o savininkui išsiunčiamas el. laiškas. Tai veikia tik užbaigus Diko registraciją GitHub secret scanning programoje ir tik viešose repozitorijose, kurias skenuoja GitHub. Tai papildoma apsauga, o ne atsargumo pakaitalas: jei žinote, kad raktas nutekėjo, atšaukite jį patys iškart.

## IP apribojimas

Raktui galima nurodyti IP adresų (CIDR) sąrašą, iš kurių jis priimamas. Tai papildomas sluoksnis tuo atveju, jei raktas nutekėtų.

**Kaip tai veikia:**

- Diko tiki kliento IP **tik užklausoms, siunčiamoms į `https://api.diko.app/api/v1`**. Ten prieglobos kraštinis serveris pakeičia kliento atsiųstą antraštę `X-Forwarded-For` dviem adresais: `<klientas>, <kraštinis serveris>`. Todėl suklastota antraštė nepraeina, o pirmas adresas yra jūsų. Bet kokios kitos antraštės formos Diko netiki.
- Per programėlės domeną (`https://studio.diko.app/api/v1`, aptarnaujamą per Vercel) pirmas adresas yra Vercel, o ne jūsų. Ten Diko kliento IP netiki niekada, todėl raktas su IP apribojimu tame domene visada gauna `ip_not_allowed`.
- Raktas su sąrašu priimamas **tik** iš patikimai nustatyto IP, kuris yra sąraše. Kitaip API grąžina 403 [`ip_not_allowed`](https://diko.app/api-docs/klaidos.md#ip_not_allowed). Tai „fail closed“ elgsena: abejojant užklausa atmetama.
- IP tikrinamas **prieš** bet kokias rakto būsenos klaidas, todėl nutekėjęs raktas iš svetimo adreso nesužino, ar jis dar galioja.
- Sąraše gali būti iki 20 įrašų. IP sąrašo keitimas reikalauja pakartotinio patvirtinimo.

> **Įspėjimas:**
> **Ką IP apribojimas gina ir ko negina.** Su IP apribojimu naudokite bazinį adresą `https://api.diko.app/api/v1`: tik ten Diko mato tikrąjį kliento IP. Raktas su IP apribojimu atmetamas adresu `https://studio.diko.app/api/v1` su `ip_not_allowed`. Net ir tinkamame domene IP apribojimas yra **papildoma apsauga, o ne garantija**: derinkite jį su mažais leidimais, trumpu galiojimu ir rotacija.

**Praktiniai patarimai:**

- Debesų ir serverless platformų išeinantys adresai dažnai keičiasi. Tokiai aplinkai IP apribojimas netinka, nebent turite fiksuotą išeinantį adresą.
- Atsižvelkite į IPv4 ir IPv6: jūsų serveris gali kreiptis kitu protokolu, nei tikitės.
- Diko saugo `last_used_ip`, auditą ir el. laiškų IP tik tada, kai jis nustatytas patikimai, kitaip rodoma `null`. Šiuos adresus laikykite užuominomis, o ne įrodymu, iš kur atėjo užklausa.
- **Derinimas.** Jei kiekviena užklausa grąžina `ip_not_allowed`, iškvieskite `GET /me` su raktu be IP apribojimo ir pažiūrėkite į lauką `request`. `request.ip` yra adresas, kurį matė Diko, o `request.ip_trusted` nurodo, ar Diko juo tiki. Jei `ip_trusted` yra `false`, patikrinkite, ar kreipiatės į `api.diko.app`.

## Komandos priežiūra

Komandos savininkas ir administratorius mato **dabartinių narių** raktų metaduomenis (pavadinimą, užuominą, leidimus, būseną, paskutinį panaudojimą) ir gali juos atšaukti. Jie **niekada nemato rakto paslapties**, taip pat kito asmens IP adreso ar IP apribojimo. Taisyklės:

- administratorius negali veikti savininko ar kitų administratorių raktų;
- savo raktus kiekvienas valdo per savo sąrašą, o ne per komandos skiltį;
- raktą atšaukus, narys gauna el. laišką, o veiksmas įrašomas į auditą.

## Narystės ir plano pokyčiai

Raktai priklauso **asmeniškai jums**, nes API duomenys yra jūsų susitikimai ir jūsų biblioteka.

- **Paliekate komandą arba esate pašalinti.** Raktai nepašalinami, bet kiekviena užklausa iš naujo tikrina planą. Jei po to nebeturite „Verslas“ plano, užklausos grąžina 403 [`plan_required`](https://diko.app/api-docs/klaidos.md#plan_required). Pakeitimas veikia iškart.
- **Pažeminate planą arba baigiasi prenumerata.** Raktai lieka, bet API neveikia, kol planas neleidžia. Atnaujinus planą raktai vėl veikia. `GET /me` visada parodo `access.allowed` ir priežastį.
- **Paskyra išjungta arba suarchyvuota.** Visi jos raktai atšaukiami (`user_disabled`), o webhook endpointai išjungiami.
- **Keičiate ar atstatote slaptažodį.** Gaunate el. laišką su aktyvių raktų ir webhooks sąrašu bei nuoroda **Atšaukti visus**. Endpointas įvardijamas tik domenu ir ID, o ne visu adresu, nes webhook adreso kelyje dažnai yra paslaptis. Skiltis **Nustatymai → API** 7 dienas rodo įspėjimą.
- **API prieigos sustabdymas.** Diko administratorius gali sustabdyti paskyros API prieigą: tada užklausos gauna 403 [`api_access_suspended`](https://diko.app/api-docs/klaidos.md#api_access_suspended).

## Saugumo kontrolinis sąrašas

- Raktas laikomas paslapčių saugykloje, ne kode.
- Raktas naudojamas tik iš serverio.
- Kiekviena integracija turi savo raktą su mažiausiais leidimais.
- Galiojimas trumpas, o rotacija suplanuota.
- Jūsų webhook gavėjas tikrina parašą ir laiko žymą.
- Žinote, kaip per minutę atšaukti raktą.
