Публічний API та рейт-ліміти на читання даних реєстру

🌐 Цей документ доступний українською та англійською мовами. Використовуйте перемикач у правому верхньому куті, щоб змінити версію.

1. Загальний опис

Для забезпечення доступу широкого загалу до даних реєстру які вважаються публічними та забезпечення можливості для сторонніх систем отримувати такі дані в актуальному стані, обробляти та візуалізувати їх, надається можливість позначати окремі пошукові критерії (search conditions) як публічні, що дозволить надалі використовувати їх без необхідності автентифікуватись.

2. Функціональні сценарії

  • Публікація пошукових запитів

  • Конфігурація ресурсів публічного API

  • Створення точок інтеграції для публічного API технічним адміністратором реєстру.

  • Отримання документації та використання публічного API.

  • Моніторинг стану та використання публічних пошукових критеріїв.

  • Зміна rate-limit-ів для існуючих точок інтеграції.

3. Ролі користувачів

  • Не авторизований користувач або стороння система

  • Розробник регламенту

  • Технічний адміністратор реєстру

4. Загальні принципи та положення

  • Публічним вважаються той API який не потребує автентифікації з боку клієнта.

  • Запити до Дата Фабрики здійснюються від імені системного користувача

  • В якості публічного API може бути представлені тільки пошукові запити (search conditions)

  • Обмеження доступу до публічного API (ip blacklist, geoip, захист від ddos-атак) поза межами даного дизайну

  • Виставлення точок інтеграції здійснюється в два етапи - через конфігурацію регламенту моделювальником реєстру і через зміну налаштувань реєстру шляхом додавання відповідних точок інтеграції в перелік Публічний доступ технічним адміністратором реєстру

  • Виставлення wildecard посилань є забороненим

5. Високорівневий дизайн рішення

context
В першій ітерації вирішено не виділяти окремий екземпляр API Gateway для публічного API.

6. Моделювання регламенту реєстру

6.1. Структура регламенту

Управління доступом здійснюється на рівні конфігурації дата моделі за допомогою тегу exposeSearchCondition

6.2. Розширення для моделювання

<exposeSearchCondition public="true" name="search-laboratories-by-city"/>

При виставленні API як публічне, та моделюванні searchCondition для них моделювальнику слід взяти до уваги наступні рекомендації:

  • Кожен searchCondition який має бути опублікований як публічний, має бути створений окремо для цього сценарію, не варто виставляти до публічного доступу searchCondition яки використовуються для кабінетів, бізнес процесів та інтеграцій з ШБО Трембіта.

  • Рекомендований тип пагінації page, оскільки він дає змогу бачити загальну кількість записів не відображаючи їх.

  • limit для таких searchCondition має бути підібраний в залежності від типу даних і має бути найменшим достатнім.

7. Розгортання сервісів

Для забезпечення відмовостійкості та відокремлення публічних запитів від інших задля підвищення безпеки розгортається окремий екземпляр сервісу rest-api.

7.1. Конфігурація NetworkPolicy

Публічний екземпляр REST API можу бути доступний лише:

  • Користувач public-user з realmexternal-system

  • Тільки за допомогою метода GET

  • Тільки до url які були виставлені публічно та посилання до OpenAPI специфікації

  • Технічні лінки для актуатора та health-check мають бути доступні тільки в середині кластеру

8. Низькорівневий дизайн сервісів

8.1. Компоненти та їх призначення

Компонент Призначення

infrastructure/monitoring

Встановлення та конфігурація моніторингу платформи

data-architecture/libraries/ddm-starter-swagger

Бібліотека для генерації OpenAPI-специфікації на основі внутрішніх правил

general/registry-configuration

Конфігурація та створення ресурсів реєстру

general/kong-admin-tools

Конфігурація глабальних плагінів для API Gateway

8.2. Моніторинг стану та навантаження для публічних API

Для моніторингу актуального стану API метрики знімаються з API Gateway (Kong) за допомогою плагіну:

apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
  name: kong-prometheus-plugin
  annotations:
    kubernetes.io/ingress.class: kong
  labels:
    global: "true"
config:
  status_code_metrics: true
  latency_metrics: true
  bandwidth_metrics: true
  per_consumer: true
plugin: prometheus
Дана конфігурація буде застосована до всіх абсолютно точок інтеграції, які виставлені через API Gateway. Згідно з документацією дані налаштування можуть призводити до погіршення швидкодії API Gateway-ю, тому при суттєвій деградації швидкодії перелік метрик можна переглянути в бік зменшення, і винести їх конфігурацію на рівень окремих точок інтеграції.

Створення сервісу для збирання метрик

apiVersion: v1
kind: Service
metadata:
  name: kong-prometheus-monitoring
  labels:
    app: kong-prometheus-monitoring
spec:
  selector:
    app.kubernetes.io/name: kong
  type: ClusterIP
  ports:
  - name: metrics
    protocol: TCP
    port: 8100
    targetPort: 8100

та ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: kong-service-monitor
spec:
  namespaceSelector:
    any: true
  endpoints:
  - port: metrics
  selector:
    matchLabels:
      app: kong-prometheus-monitoring

За основу Grafana Dashboard пропонується взяти офіційну. Створення ConfigMap з дашбордом для моніторингу

monitoring/deploy-templates/dashboard/public-api.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-public-api
data:
  public-api-statistic.json: |-
  ...
monitoring/deploy-templates/values.yaml
dashboardsConfigMaps:
  - configMapName: grafana-public-api
    fileName: public-api-statistic.json

Ключові метрики:

  • Кількість запитів по кожній точці інтеграції

  • Кількість успішних 2хх кодів, помилок сервера 5хх, та помилок клієнту 4хх, всі інші коди можуть бути винесені в окрему групу

  • Статистика швидкодії (найдовший запит, середні, найшвидший )

8.3. Отримання документації до публічного API

Отримання специфікації (OpenAPI) для API який був позначений як публічний. (приклад)

Rate-limit-и не застосовуються до посилання документації, проте для зменшення навантаження на сервіс, відповідь додатково кешується на API Gateway (Kong) за допомогою proxy-cache плагіна.

Застосовується TTL-based кешування. Конфігурація якого здійснюється на рівні конфігурації плагіну через Gerrit

Загальні вимоги до конфігурації кешування:

  • Кешування встановлюється тільки посилання до документації та тільки GET методу

  • TTL за замовчанням 15 хвилин

  • Кеш зберігається в пам`яті API Gateway

8.4. Створення сервісного облікового запису для виконання публічних запитів.

Попри те що формально точки інтеграції є публічними, для підтримання однорідності аудиту та логування в середині платформи, такі запити будуть здійснюватись від імені службового користувача з realmexternal-system. Створення службового користувача public-user для авторизації на рівні platform-gateway.

general/registry-configuration/values.yaml
    publicUser:
      name: public-user
      clientId: public-user
      public: false
      secretName: keycloak-public-user-client-secret
      targetRealm:
        name: external-system
    ...

8.5. Надання доступу та встановлення rate limit-ів на рівні конфігурації.

Для всіх url з переліку має бути вимкнена перевірка заголовків автентифікації.

Налаштування сервіса мають бути такими щоб GET запит до https://{domin}/api/public/data-factory/search-laboratories-by-city здійснював запит до registry-rest-api-public.{registry-namespace}.svc.cluster.local:8080/search-laboratories-by-city

Приклад спрощеної конфігурації
apiVersion: v1
kind: Service
metadata:
  name: public-city-lab-route
  labels:
    app: registry-rest-api-public
  annotations:
    konghq.com/plugins: post-transformer, city-lab-rate-limiting
    konghq.com/override: registry-rest-api-public:/search-laboratories-by-city
    konghq.com/path: /search-laboratories-by-city
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: registry-rest-api-public
  selector:
    app: registry-rest-api-public

Загальні вимоги до конфігурації rate-limit-ів:

  • Лічильник запитів зберігається в пам`яті Redis

  • Встановлюється на рівні точок інтеграції (роутів)

  • Ведеться для кожної IP-адреси користувача

Приклад конфігурації основних аспектів
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: city-lab-rate-limiting
plugin: rate-limiting
config:
  second: 5
  hour: 100
  limit_by: ip
  policy: redis
  ...

9. Адміністративний доступ

Задля запобігання помилкового виставлення API в якості публічного, передбачається необхідність конфігурації таких точок інтеграції не тільки моделювальником регламенту, але і технічним адміністратором реєстру. Також технічний адміністратор реєстру має виставити rate limit-и.

10. Управління конфігурацією реєстру

Управління здійснюється шляхом додавання технічним адміністратором реєстру шляхів до списку Публічний доступ,

У випадку видалення існуючих точок інтеграції або тимчасове вимкнення їх при зверненні до них користувач отримує, що таких точок інтеграції не існує HTTP 404.

10.1. Конфігурація реєстру

В Helm чарті registry-configurations секція публічне API яка передбачає конфігурацію технічної назви для публічного API, відносного шляху до точки інтеграції в public-rest-api та лімітів.

publicApi:
  - name: city-lab
    enabled: true
    url: /search-laboratories-by-city
    limits:
        second: 5
        hour: 100
  - ...

Поточні значення використовуються для створення kong сервісу та конфігурації rate-limit плагіна до нього.

При досягнені ліміту, формується відповідь від API Gateway з кодом 429 та тілом

{ "message": "API rate limit exceeded" }
Назва атрибута Функціональне значення

name

Технічна назва правила, служить унікальним ідентифікатором правила і не може бути змінена

enabled

Відображає стан точки інтеграції, у випадку false роут не видаляється API Gateway формує відповідь з кодом 503

url

Відносний шлях до пошукового запису, може бути змінений

limits

Перелік лімітів які застосовуються до точки інтеграції

11. Високорівневий план розробки

11.2. План розробки

  • Публічне API

    • Розширення схеми та бібліотеки Liquibase.

    • Зміна шаблону розгортання для registry-rest-api.

    • Додавання плагіну для збирання метрик з API Gateway.

    • Адаптація та розгортання дашборд Grafana.

    • Додавання секції для конфігурації публічного API в registry-configuration.

    • Додавання валідація унікальності імені та url на пайплайні внесення змін в реєстр.

    • Додавання типу інтеграції "Публічний доступ" на рівні Технічної консолі адміністратора та конфігурації registry-configuration з конфігурації реєстру.

  • Rate limits

    • Зміна шаблону розгортання та створення плагінів rate limit-ів в registry-configuration

    • Розширення секції конфігурації публічне API rate limit-ами.

    • Додавання перевірки наявності рейт лімітів на пайплайні внесення змін в реєстр.

    • Налаштування кешування документації

    • Винесення налаштувань на рівень конфігурації реєстру.

    • Додавання можливості конфігурації через адміністративну консоль.