Сигурност17 мин

Сигурност на API за CTO: идентичност, gateway и токени, без сляпо доверие

От Dorian Chávez · основател на Hábil и архитект по интеграция ·

Кога да валидирате повторно токена зад gateway, как API се извикват едно друго, интроспекция или локална валидация, logout и колко дълго да живее един токен.

Често срещана днес архитектура за сигурност на API има три части: доставчик на идентичност, който издава токените —Keycloak, Microsoft Entra ID, Okta или друг—, gateway, който приема целия трафик —APISIX, Kong, Apigee, Azure API Management или друг— и OAuth 2.0 като език, на който се искат и се представят права. Това е добра архитектура. Проблемът се появява при въпросите, които никой не е записал при проектирането ѝ: услугата зад gateway-а проверява ли токена отново? Какво става, когато едно API извиква друго? Ако потребителят излезе от сесията, токенът му спира ли да върши работа? Колко дълго трябва да живее един токен?

Тази статия отговаря на тези въпроси за онзи, който трябва да подпише архитектурата: CTO на банка, финтех, застрахователна компания, търговска верига или всяка друга регулирана компания. Всеки отговор идва със своето условие, защото в сигурността почти никога няма «винаги».

Три вида маршрут, три нива на доверие

Преди да се заговори за токени, е добре да се класифицира всеки маршрут на API:

Три вида маршрут, три нива на доверие
Вид маршрутЗа какво служиКакво доказваКакво не доказва
ПубличенКаталози, обща информация, състояние на услугатаНищоКой извиква
С API ключИдентифициране на потребител на API, измерване и ограничаване на ползванетоЧе извикващият притежава ключаКой е човекът, какво е одобрил и дали ключът не е откраднат
С OAuth токенДостъп с права, от името на система или на човекПри access токен на OAuth, конфигуриран за това API: позволява да се проверят атрибутите, които профилът и доставчикът издават —например издател, аудитория, валидност и права— чрез JWT валидация или интроспекцияЧе човекът все още е упълномощен в този момент, ако токенът е дълъг

API ключът идентифицира, но не упълномощава добре: не носи фини права, нито към кого е адресиран, нито стандартен срок на валидност, нито делегиране [1][2]. Служи за просто ползване, измерване и квоти. За интеграция между компании (B2B) с чувствителни данни е подходящ OAuth 2.0 с идентификационни данни на клиента (client credentials): системата на партньора получава по API токен с кратък живот, с ограничени права и адресиран до Вашето API [3][4]. Този път е подходящ, когато системата действа от свое име или по предварително споразумение; той не замества съгласието на човек. Ако запазите API ключове: по един на потребител и на среда, съхранявани като тайна, ротирани и никога в URL адреса, защото URL адресите остават записани в дневниците на gateway-а, на прокситата и на инструментите за мониторинг, където всеки с достъп може да ги прочете [2].

Трябва ли услугата зад gateway-а да проверява токена?

Това е въпросът, който предизвиква най-много спорове, и краткият отговор е: това, че е зад gateway-а, само по себе си не дава доверие. Така гласи рамката за нулево доверие на NIST: местоположението в мрежата не предполага доверие, а зоната на имплицитно доверие трябва да е възможно най-малка [5].

Пълният отговор разделя две неща, които често се бъркат:

  • Валидиране на токена (автентичен ли е, издаден ли е от моя доставчик, за мен ли е, още ли е валиден?).
  • Упълномощаване на операцията (може ли този човек или тази система да чете тази сметка, тази полица, тази поръчка?).

Второто, фината авторизация върху обекта, трябва да се оценява там, където са налични бизнес правилото и връзката с обекта: обикновено в услугата или в компонент за политики, вграден в нея. Gateway-ът може да допълни с груби контроли, но не замества това правило. Общо право като «четене на плащания» не решава дали някой може да прочете плащането на друг клиент. Тази грешка си има име и е първата в списъка на OWASP с рискове за API [6][7].

Първото може да се делегира на gateway-а, но само ако са изпълнени всички тези условия [5][8][9]:

  1. Услугата не е достижима по никакъв друг път освен през gateway-а: нито от друга мрежа, нито от друга съседна услуга, нито по административен маршрут.
  2. Каналът между gateway-а и услугата е автентикиран, например с взаимен TLS.
  3. Gateway-ът изтрива всеки HTTP хедър за идентичност, дошъл отвън, и поставя свой, подписан (например вътрешен токен) или по автентикиран канал, така че услугата да може да провери, че идва от gateway-а.
  4. Конфигурацията на маршрутите е инвентаризирана, тества се и при грешка затваря: маршрут без правило не остава отворен.

Ако някое условие не е изпълнено, документирайте друга точка за прилагане на политиката, която проверимо валидира идентичността на извикващия и контекста; ако няма такава, услугата трябва да го направи. И има случаи, в които е добре да го валидира, дори да са изпълнени и четирите: когато работи с пари или лични данни, когато решава въз основа на данни от токена или когато обслужва няколко клиенти или домейна.

Един конфигурационен детайл, който струва злато: при някои gateway-и плъгините, които валидират API ключове или JWT, препращат оригиналните идентификационни данни към услугата отзад, освен ако не се конфигурира иначе, а плъгинът за OpenID Connect при bearer_only със стойност false не изисква строго bearer токен [10][11]. Това са стойностите, документирани в APISIX 3.19 [доставчик]; потвърдете инсталираната версия и действителната конфигурация. Прегледът на тези стойности по подразбиране е част от архитектурата, а не дреболия.

Когато едно API извиква друго

Вътре в архитектурата една услуга трябва да извика друга. Има пет често срещани модела и всеки служи за нещо различно [12][13][14]:

Когато едно API извиква друго
Има ли потребител отзад?МоделПолзвайте го, когатоРиск при неправилна употреба
ДаПрепращане на токена на потребителяЦелевата услуга е декларирана като получател на токенаПосредникът държи в ръцете си токен, който върши работа и за други услуги
ДаОбмен на токена (token exchange, RFC 8693)Целта трябва да знае кой е потребителят, но със собствен токен, намален и адресиран до неяОбменът да позволява искането на всякакви права за всякаква цел
НеСобствени идентификационни данни на услугатаТехническа работа, пакетна обработка, събития, съгласуване: няма потребител отзадПриписване на потребител на действие, извършено от системата
ДаВътрешен токен с кратък животGateway-ът сменя външния токен с вътрешен, валиден само вътреНеволно създаване на втори доставчик на идентичност без управление
НеСамо взаимен TLS между услугитеДостатъчно е да се знае коя услуга извикваСертификатът доказва услугата, а не правото на потребителя

Правило, което намалява риска от неправомерно повторно използване: всяка услуга проверява, че токенът е бил адресиран до нея. Полето, което го казва, се нарича аудитория (aud), и ако услугата не е в него, токенът се отхвърля [15][16]; за да се ограничи целта при поискването му, има индикатори на ресурса (RFC 8707) [30]. Така се избягва грешката «сляпо препращане» (token passthrough) и най-известната ѝ последица, confused deputy: услуга, която с чужд токен прави нещо, което потребителят никога не е упълномощавал. Например услуга за отчети, която получава токен, издаден за услугата за плащания, и с него успява да изпълнява плащания.

За веригата «A извиква B от името на потребителя» препоръчваният модел е обменът на токени: A сменя получения токен с нов, адресиран до B и с по-малко права [12]. В Keycloak стандартната функция V2 е включена по подразбиране, но клиентът, който я иска, трябва да е конфиденциален и да има включен Standard token exchange; стандартният обмен действа между клиенти от същия realm [17]. А NIST предлага нещо подобно за микроуслуги: смяна на външния токен на входа с вътрешен с кратък живот и проверка на всеки хоп [8].

Да се доверим на токена или да попитаме доставчика?

Има два начина да се разбере дали един токен е добър:

Да се доверим на токена или да попитаме доставчика?
МетодПодходящ, когатоПредимствоГраница
Локална валидация на JWT (подпис с публичните ключове на доставчика, издател, аудитория, срок на валидност)Голям обем, ниска латентностНе зависи от наличността на доставчика при всяка заявкаНе научава, ако токенът е отменен след издаването
Интроспекция (RFC 7662): въпрос към доставчикаНепрозрачни токени или действия, при които текущото състояние има значениеОтговаря дали токенът е активен в моментаДобавя латентност и зависимост от доставчика
СмесенРегулирани API с голям обемЛокална валидация за обичайното, интроспекция за критичнотоТрябва да се реши и документира кое е «критично»

Локалната валидация не е само «подписът мина»: трябва да се фиксира очакваният издател, да се приемат само предвидените алгоритми, да се проверяват аудитория, срок на валидност и права и да се вземат ключовете от надеждно място, защото доставчикът ги ротира: услугата държи публичните ключове в кеш и, когато пристигне токен, подписан с непознат ключ, ги иска отново, вместо да го отхвърли или да го приеме на сляпо [18][19]. И една цена, която CTO подписва: при интроспекция на всяка заявка доставчикът на идентичност попада в критичния път на всички операции; ако падне или се забави, пада или се забавя всичко. А ако резултатът от интроспекцията се държи в кеш, времето на кеша не може да бъде по-голямо от прозореца за отмяна, който бизнесът приема: кеш от пет минути противоречи на обещание за «незабавна» отмяна.

Излизането от сесията не изключва вече издадените токени

Оперативен ефект със съществено значение, който често изненадва един комитет по сигурност: когато потребителят излезе от сесията, access токенът, който вече има, остава валиден до изтичането си, за всяка услуга, която го валидира локално. Механизмите за излизане от сесия на OpenID Connect прекратяват сесията и уведомяват приложенията, но не обезсилват access токените, които вече циркулират [20][21]; документацията на Keycloak предупреждава за това изрично [17].

Затова валидността се проектира на слоеве:

  1. Кратки access токени, за да е малък прозорецът на експозиция.
  2. Refresh токени с възможност за отмяна, свързани с клиента и, при публични приложения, с ротация [3].
  3. Интроспекция при операциите, при които текущото състояние има значение: преводи, промени на бенефициент, масови изтегляния, административни действия.
  4. Отмяна (RFC 7009), когато доставчикът я поддържа [22].
  5. Събития за отмяна между системите (OpenID CAEP), които вече са окончателен стандарт; поддръжката им при доставчиците все още е неравномерна [23].

Колко дълго трябва да живее един токен?

В никоя норма не съществува «стандартна» продължителност. OAuth оставя живота на токена на доставчика [4]; стандартът за bearer токени препоръчва един час или по-малко [24]; а профилът за сигурност на отворното банкиране (FAPI 2.0) изисква кратки токени, без да фиксира цифра [25]. Има обаче начални диапазони за проектиране —редакционен критерий, а не норма—; нагласете ги според експозицията, прозореца за отмяна, повторната автентикация и наличността на доставчика:

Колко дълго трябва да живее един токен?
ТокенИзходна точкаКоментар
Access токен на човек5 минути; от 1 до 5 при плащания и администрацияСамо ако refresh токенът е ротиран и свързан с клиента; иначе е добре малко по-дълъг живот, компенсиран с интроспекция при критичното
Access токен между компании (client credentials)От 5 до 15 минутиПодновява се чрез повторна автентикация на системата
Refresh токенКолкото продължи сесията: неактивност и максимумДа не се подновява тихомълком неактивна сесия
«Offline» токен (с дълъг живот)Само като одобрено изключениеС изричен максимум и отмяна

Фабричните стойности на Keycloak [доставчик] са в тази посока. Проверихме ги директно в изходния му код (основният клон, консултиран на 6 октомври 2026 г.), защото документацията не ги публикува пълно [26]. Това са числа на доставчика и могат да се променят между версиите:

Колко дълго трябва да живее един токен?
Настройка на KeycloakСтойност по подразбиране
Живот на access токена5 минути (1 минута в административния домейн «master»)
Сесия: неактивност30 минути
Сесия: максимум10 часа
Offline сесия: неактивност30 дни (максимумът ѝ е изключен)

В Keycloak refresh токенът на нормална сесия живее колкото сесията позволява. Преди да се доверите на тези числа, прегледайте тези на Вашата инсталация: настройките по клиент и импортираните конфигурации ги променят.

Кога е нужен OpenID Connect?

  • OAuth 2.0 е достатъчен, когато това, което се защитава, е достъпът на приложение или система до API: интеграции между компании, вътрешни процеси, права по обхват [4].
  • OpenID Connect е подходящ, когато приложението се нуждае от автентикирана оперативно съвместима идентичност, claims за автентикация или единен вход (също ниво на автентикация, излизане от сесия и повторна автентикация за чувствителни действия) [27]. OAuth сам по себе си не стандартизира тази идентичност: OpenID Connect е слоят на идентичността върху OAuth.
  • Честа грешка: ползването на ID токена на OpenID Connect за извикване на API. ID токенът е за приложението, което е започнало сесията; към API се изпраща access токенът [27].

При отвореното банкиране летвата се вдига

Ако Вашето API попада в света на отвореното банкиране или на финансовите данни, профилът FAPI 2.0 (окончателен стандарт) вдига летвата: токени, свързани с онзи, който ги ползва —с взаимен TLS или DPoP—, силна автентикация на клиента и защитени параметри на заявката [25][28][29]. Не е задължителен за всички API, нито сам по себе си е мексиканско задължение: може да бъде полезна техническа референция за API с висока стойност, когато приложимата рамка, договор или политиката за риска го възприемат, и не замества оценката на приложимите регулаторни задължения.

От къде да започнете

  1. Класифицирайте маршрутите си в публични, с API ключ и с токен и проверете дали всеки е там, където трябва.
  2. Решете, услуга по услуга, кой валидира токена, с четирите условия по-горе, записани на хартия.
  3. Проверявайте аудиторията във всяка услуга и премахнете сляпото препращане на токени.
  4. Прегледайте стойностите по подразбиране на Вашия доставчик на идентичност и на Вашия gateway.
  5. Определете прозореца си за отмяна по вид операция и нагласете продължителностите и интроспекцията според него.

Колко от Вашите маршрути биха издържали днес такава проверка? Първият разговор за диагностика е безплатен: излизате с картата на маршрутите си по ниво на доверие и със слабите места, които да се адресират първи. Пишете ни в WhatsApp.

Referencias

  1. OWASP, REST Security Cheat Sheet (API ключове). https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
  2. OWASP, OAuth2 Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/OAuth2_Cheat_Sheet.html
  3. IETF, RFC 9700, Best Current Practice for OAuth 2.0 Security (2025). https://www.rfc-editor.org/rfc/rfc9700.html
  4. IETF, RFC 6749, The OAuth 2.0 Authorization Framework, §4.4 client credentials. https://www.rfc-editor.org/rfc/rfc6749.html
  5. NIST, SP 800-207, Zero Trust Architecture. https://csrc.nist.gov/pubs/sp/800/207/final
  6. OWASP, API Security Top 10 2023 (API1: Broken Object Level Authorization). https://api-security.owasp.org/editions/2023/en/0xa1-broken-object-level-authorization/
  7. OWASP, Authorization Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html
  8. NIST, SP 800-207A, A Zero Trust Architecture Model for Access Control in Cloud-Native Applications. https://csrc.nist.gov/pubs/sp/800/207/a/final
  9. NIST, SP 800-204, Security Strategies for Microservices-based Application Systems. https://csrc.nist.gov/pubs/sp/800/204/final
  10. Apache APISIX, плъгини key-auth и jwt-auth (hide_credentials). https://apisix.apache.org/docs/apisix/plugins/key-auth/ · https://apisix.apache.org/docs/apisix/plugins/jwt-auth/
  11. Apache APISIX, плъгин openid-connect (bearer_only, интроспекция, JWKS). https://apisix.apache.org/docs/apisix/plugins/openid-connect/
  12. IETF, RFC 8693, OAuth 2.0 Token Exchange. https://www.rfc-editor.org/rfc/rfc8693.html
  13. OWASP, Identity Propagation Patterns Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Identity_Propagation_Patterns_Cheat_Sheet.html
  14. IETF, RFC 8705, OAuth 2.0 Mutual-TLS Client Authentication. https://www.rfc-editor.org/rfc/rfc8705.html
  15. IETF, RFC 7519, JSON Web Token, §4.1.3 (aud). https://www.rfc-editor.org/rfc/rfc7519.html
  16. IETF, RFC 9068, JWT Profile for OAuth 2.0 Access Tokens. https://www.rfc-editor.org/rfc/rfc9068.html
  17. Keycloak, Server Administration Guide и Securing Applications Guide (аудитория, обмен на токени, сесии). https://www.keycloak.org/securing-apps/token-exchange · https://www.keycloak.org/documentation
  18. OWASP, JSON Web Token Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_Cheat_Sheet.html
  19. IETF, RFC 7662, OAuth 2.0 Token Introspection. https://www.rfc-editor.org/rfc/rfc7662.html
  20. OpenID, Back-Channel Logout 1.0. https://openid.net/specs/openid-connect-backchannel-1_0.html
  21. OpenID, RP-Initiated Logout 1.0. https://openid.net/specs/openid-connect-rpinitiated-1_0.html
  22. IETF, RFC 7009, OAuth 2.0 Token Revocation. https://www.rfc-editor.org/rfc/rfc7009.html
  23. OpenID, CAEP 1.0 (Continuous Access Evaluation Profile). https://openid.net/specs/openid-caep-1_0-final.html
  24. IETF, RFC 6750, Bearer Token Usage, §5.3. https://www.rfc-editor.org/rfc/rfc6750.html
  25. OpenID, FAPI 2.0 Security Profile (окончателен). https://openid.net/specs/fapi-security-profile-2_0-final.html
  26. Keycloak [доставчик], изходен код: Constants.java и ApplianceBootstrap.java (стойности по подразбиране), основният клон, консултиран на 6 октомври 2026 г.; връзки към последния комит на всеки файл към тази дата. https://github.com/keycloak/keycloak/blob/55e0a796c7d397027c766efcad1ba47706ba8f72/server-spi-private/src/main/java/org/keycloak/models/Constants.java · https://github.com/keycloak/keycloak/blob/3575af2b5bc19fa16d3f6caf39ad1fc869c3fdda/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
  27. OpenID, OpenID Connect Core 1.0. https://openid.net/specs/openid-connect-core-1_0.html
  28. IETF, RFC 9449, OAuth 2.0 Demonstrating Proof of Possession (DPoP). https://www.rfc-editor.org/rfc/rfc9449.html
  29. OpenID, FAPI 2.0 Message Signing (окончателен). https://openid.net/specs/fapi-message-signing-2_0-final.html
  30. IETF, RFC 8707, Resource Indicators for OAuth 2.0. https://www.rfc-editor.org/rfc/rfc8707.html