Public API and rate limits for reading registry data

🌐 This document is available in both English and Ukrainian. Use the language toggle in the top right corner to switch between versions.

1. General description

In order to ensure public access to registry data that is considered public and to ensure the possibility for third-party systems to receive such data in an up-to-date state, process and visualize them, it is possible to mark individual search criteria (`search conditions') as public, which will allow their further use without need to authenticate.

2. Functional scripts

  • Publication of search requests

  • Configuration of public API resources

  • Creation of integration points for the public API by the registry technical administrator.

  • Getting documentation and using the public API.

  • Status monitoring and use of public search criteria.

  • Changing `rate-limits' for existing integration points.

3. User roles

  • Unauthorized user or third-party system

  • Developer of regulations

  • Technical registry administrator

4. General principles and provisions

  • An API that does not require client authentication is considered public.

  • Requests to the Data Factory are made on behalf of the system user

  • Only search queries (`search conditions') can be presented as a public API

  • Restriction of access to the public API (ip blacklist, geoip, protection against ddos attacks) outside the scope of this design

  • The integration points are set up in two stages - through the configuration of the regulation by the registry modeler and through changing the registry settings by adding the corresponding integration points to the ``Public access'' list by the technical administrator of the registry

  • Wildecard links are prohibited

5. High-level solution design

context
In the first iteration, it was decided not to allocate a separate instance of API Gateway for the public API.

6. Simulation of the registry regulation

6.1. Structure of the regulation

Access control is carried out at the data model configuration level using the exposeSearchCondition tag

6.2. Simulation extension

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

When exposing an API as public and modeling searchCondition for them, the modeler should take into account the following recommendations:

  • Each searchCondition that should be published as public should be created separately for this scenario, it is not necessary to expose to public access searchCondition that are used for offices, business processes and integrations with SHO Trembita.

  • Recommended pagination type page as it allows you to see the total number of records without displaying them.

  • limit for such searchCondition should be selected depending on the data type and should be the smallest sufficient.

7. Deployment of services

To ensure fault tolerance and separate public requests from others, a separate instance of the rest-api service is deployed to improve security.

7.1. NetworkPolicy configuration

A public `REST API' instance can only be accessed:

  • User public-user from realm to external-system

  • Only using the GET method

  • Only to `urls' that have been exposed publicly and links to the OpenAPI specification

  • Technical links for the actuator and health-check should be available only in the middle of the cluster

8. Low-level design of services

8.1. Components and their purpose

Component Appointment

infrastructure/monitoring

Installation and configuration of platform monitoring

data-architecture/libraries/ddm-starter-swagger

A library for generating an OpenAPI specification based on internal rules

general/registry-configuration

Configuration and creation of registry resources

general/kong-admin-tools

Configuration of global plugins for API Gateway

8.2. Health and load monitoring for public APIs

To monitor the current state of the API, metrics are downloaded from API Gateway (Kong) using the plugin:

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
This configuration will be applied to absolutely all integration points that are exposed through API Gateway. According to the documentation, these settings can lead to a deterioration in the performance of ``API Gateway'', therefore, in the case of significant performance degradation, the list of metrics can be revised downwards, and their configuration can be brought to the level of individual integration points.

Creating a service for collecting metrics

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

and 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

It is suggested to use official as a basis for the Grafana Dashboard. Creation of ConfigMap with dashboard for monitoring

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

Key metrics:

  • The number of requests for each integration point

  • The number of successful 2xx codes, 5xx server errors, and 4xx client errors, all other codes can be assigned to a separate group

  • Performance statistics (longest request, average, fastest)

8.3. Get documentation for the public API

Getting the specification (OpenAPI) for an API that has been marked as public. (example)

`Rate-limits' are not applied to the documentation link, however, to reduce the load on the service, the response is additionally cached on the `API Gateway' (`Kong') using the `proxy-cache' plugin.

TTL-based caching is used. The configuration of which is carried out at the plug-in configuration level through Gerrit

General caching configuration requirements:

  • Caching is set only by the reference to the documentation and only by the GET method

  • ``TTL'' is 15 minutes by default

  • The cache is stored in memory by API Gateway

8.4. Create a service account to perform public requests.

Although formally the integration points are public, in order to maintain uniformity of auditing and logging in the middle of the platform, such requests will be made on behalf of the official user from realm' to `external-system'. Creation of service user `public-user for authorization at platform-gateway level.

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. Providing access and setting rate limits at the configuration level.

Authentication header checking must be disabled for all `urls' listed.

The service settings should be such that `GET'' request to https://{domin}/api/public/data-factory/search-laboratories-by-city made a request to `registry-rest-api-public.{registry-namespace}.svc.cluster.local:8080/search-laboratories-by-city

An example of a simplified configuration
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

General requirements for the configuration of rate-limits:

  • The request counter is stored in ``Redis'' memory

  • Set at the level of integration points (`routes')

  • Maintained for each `IP' address of the user

An example of the configuration of the main aspects
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. Administrative access

In order to prevent the API from being mistakenly presented as public, it is assumed that such integration points need to be configured not only by the modeler of the regulation, but also by the technical administrator of the registry. Also, the technical administrator of the registry should set rate limits.

10. Registry configuration management

Management is carried out by adding the path registry to the Public access list by the technical administrator,

In case of deleting existing integration points or temporarily disabling them when accessing them, the user receives HTTP 404 that such integration points do not exist.

10.1. Registry configuration

In Helm chart registry-configurations section public API which provides configuration of technical name for public API, relative path to integration point in public-rest-api and limits.

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

The current values are used to create the kong service and configure the rate-limit plugin for it.

When the limit is reached, a response from API Gateway with code 429 and a body is generated

{ "message": "API rate limit exceeded" }
Attribute name Functional value

name

The technical name of the rule, serves as the unique identifier of the rule and cannot be changed

enabled

Displays the state of the integration point, if false the route is not removed API Gateway generates a response with code 503

url

The relative path to the search entry can be changed

limits

List of limits applied to the integration point

11. High-level development plan

11.2. Development plan

  • Public API

    • Extension of ``Liquibase'' scheme and library.

    • Changed deployment template for registry-rest-api.

    • Adding plugin for collecting metrics from API Gateway.

    • Grafana dashboard adaptation and deployment.

    • Adding section to configure public API in registry-configuration.

    • Adding validation of the uniqueness of the name and `url' to the pipeline of making changes to the registry.

    • Adding "Public access" integration type at Admin Technical Console level and configuration registry-configuration from registry configuration.

  • Rate limits

    • Change of deployment template and creation of `rate limit' plugins in `registry-configuration'

    • Extension of the configuration section of the public API with rate limits.

    • Adding a check for the presence of rate limits on the pipeline of making changes to the register.

    • Documentation caching settings

    • Transferring settings to the registry configuration level.

    • Adding the ability to configure through the administrative console.