Конг Гейт웨й – это open-source API-шлюз, который обеспечивает, чтобы входящие запросы были правильными, а также управляет безопасностью, ограничением скорости, логированием и другими аспектами. OPA (Open Policy Agent) – это open-source политичный движок, который контролирует ваши решения по безопасности и доступу. Представьте его как ум, который декоуплирует применение политики в вашем приложении, чтобы ваши услуги не вынуждены были обеспокоены применением правил. вместо этого OPA делает вычисления с помощью языка Rego, оценивая политику посредством API, микросервисов или даже Kubernetes. Он гибкий, безопасный и делает обновление политик легко. OPA работает, оценивая три ключевых элемента: входные данные (например, реально-временные данные, такие как запросы), данные (внешние сведения, такие как роли пользователей) и политику (логика в Rego, решающая, должен ли быть “разрешен” или “запрещен”). Вместе эти компоненты позволяют OPA поддерживать сильную игру вашей безопасности с сохранением простоты и последовательности.
Что мы стремимся достичь или решить?
Часто данные в OPA подобны старому другу — статическим или медленно изменяющимся. Они используются вместе с постоянно изменяющимися входными данными для принятия умных решений. Но imagine систему с разросшейся сетью микросервисов, массой пользователей и огромной базой данных, как PostgreSQL. Эта система обеспечивает высокий объем транзакций в секунду и должна справиться с своей скоростью и пропускной способностью без особых усилий.
Затратный контроль доступа в такой системе сложен, но с OPA вы можете возложить тяжелую работу на микросервисах и выполнять ее на уровнеゲート웨イ. Благодаря сотрудничеству с Kong API Gateway и OPA вы получаете и высокий пропуск и точный контроль доступа.
Как вы удерживаете точность данных пользователей без того, чтобы замедлять работу? Константно стучать в базу данных PostgreSQL, чтобы извлечь миллионы записей, дорого и медленно. Achieving both accuracy and speed usually requires compromises between the two. Let’s aim to strike a practical balance by developing a custom plugin (at the gateway level) that frequently loads and locally caches data for OPA to use in evaluating its policies.
Демо
Для демонстрации я установил набор примерных данных в PostgreSQL, содержащих информацию о пользователях, такую как имя, электронная почта и роль. Когда пользователь пытается получить доступ к сервису через определенный URL, OPA оценивает, разрешен ли запрос. политики Rego проверяет URL запроса (ресурс), метод и роль пользователя, затем возвращает true или false в соответствии с правилами. Если true, запрос допускается; если false, доступ запрещен. До этого момента все было простым установкой. Теперь погрузимся в нашу собственную плагин. Чтобы более ясно понять его реализацию, пожалуйста, обратите внимание наdiagramму ниже.
Когда запрос идет через Kong Proxy, вызывается наш customsplugin для Kong.Pluginполучает необходимые данные и передает их в OPA вместе с входными данными/запросом. Этот процесс получения данных состоит из двух частей: одна из них – это поиск в Redis, чтобы найти необходимые значения, и если их найдено, передается OPA; если нет, будет дополнительный запрос к Postgres и получение данных и кэширование их в Redis, прежде чем передать их в OPA. Мы можем вернуться к этому, когда мы запустим команды в следующем разделе и проверить логи. OPA принимает решение (на основе политики, входных данных и данных) и если это разрешено, Kong продолжит отправить запрос на API. Utilizingthis approach, the number of queries to Postgres is significantly reduced, while the data available to OPA is quite accurate and preserves low latency.
Для начала создания пользовательского плагина нам нужен handler.lua
, в котором реализована базовая логика плагина, и schema.lua
, который, как следует из имени, определяет схему конфигурации плагина. Если вы начинаете учиться, как писать пользовательские плагины для Kong, смотрите на этот ссылку для более подробной информации. Документация также объясняет, как упаковывать и устанавливать плагин. Продолжим и посмотрим на логику этого плагина.
Первый шаг демонстрации состоит в установке OPA, Kong, Postgres и Redis на вашем локальном настройке или любом облачном настройке. Пожалуйста, клонируйте в этот репозиторий.
Просмотрите docker-compose yaml, в котором определены настройки для развертывания четырех указанных выше служб. Observe the Kong Env variables to see how the custom plugin is loaded.
Вот команды, которые нам нужно выполнить для развертывания служб:
docker-compose build
docker-compose up
После проверки того, что контейнеры запущены и работают, Kong manager и OPA доступны на соответствующих endpoint https://localhost:8002 и https://localhost:8181, как показано ниже:
Создайте тестовую службу, маршрут и добавьте наш пользовательский плагин Kong к этому маршруту следующей командой:
curl -X POST http://localhost:8001/config -F config=@config.yaml
Политика OPA, определенная в authopa.rego файле, публикуется и обновляется для службы OPA следующей командой:
curl -X PUT http://localhost:8181/v1/policies/mypolicyId -H "Content-Type: application/json" --data-binary @authopa.rego
Этот примерной политикой предоставляется доступ к пользовательским запросам только если пользователь обращается к пути /demo с методом GET
и имеет роль "Moderator"
. Дополнительные правила могут быть добавлены по мере необходимости, чтобы настраивать контроль доступа на основе различных критериев.
opa_policy = [
{
"path": "/demo",
"method": "GET",
"allowed_roles": ["Moderator"]
}
]
Теперь установка готова, но перед тестированием нам нужно добавить некоторые тестовые данные в Postgres. Я добавил несколько примерных данных (имя, электронный адрес и роль) для нескольких сотрудников, как показано ниже (см. PostgresReadme).
Вот пример неверного и успешного запроса:
Теперь, чтобы протестировать основную функциональность этого пользовательского плагина, давайте сделаем два последовательных запроса и проверим логи, чтобы посмотреть, как происходит извлечение данных.
Вот логи:
2024/09/13 14:05:05 [error] 2535#0: *10309 [kong] redis.lua:19 [authopa] No data found in Redis for key: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:25 [authopa] Fetching roles from PostgreSQL for email: [email protected], client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] postgres.lua:43 [authopa] Fetched roles: Moderator, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:29 [authopa] Caching user roles in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] redis.lua:46 [authopa] Data successfully cached in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"
2024/09/13 14:05:05 [info] 2535#0: *10309 client 192.168.96.1 closed keepalive connection
------------------------------------------------------------------------------------------------------------------------
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] redis.lua:23 [authopa] Redis result: {"roles":["Moderator"],"email":"[email protected]"}, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"
Данные логи показывают, что для первого запроса, когда данных в Redis нет, данные вытягиваются из Postgres и кэшируются в Redis, прежде чем отправиться в OPA для оценки. В следующем запросе, так как данные доступны в Redis, ответ будет гораздо быстрее.
Заключение
В заключение, сочетая Kong Gateway с OPA и реализуяカスタム плагин с кэшированием Redis, мы эффективно балансируем точность и скорость для контроля доступа в средах высокой пропускности. Плагин минимизирует количество дорогих запросов к Postgres, кэшируя роли пользователей в Redis после первичного запроса. На следующих запросах данные из Redis are retrieved, значительно уменьшая латенцию, сохраняя при этом точные и актуальные сведения о пользователях для оценки политик OPA. Этот подход обеспечивает, что качественный доступ контроля решается эффективно на уровне шлюза без потерь в производительности или безопасности, делая его идеальным решением для масштабирования микросервисов при обеспечении точных доступных политик.
Source:
https://dzone.com/articles/enhanced-api-security-fine-grained-access-control