Proteção Robusta de APIs: Kong Gateway e Keycloak no Linux
A segurança de APIs é uma camada crítica na arquitetura de microsserviços e aplicações distribuídas. O cenário atual exige mecanismos de autenticação e autorização robustos, escaláveis e de fácil gerenciamento. A combinação do Kong Gateway, atuando como um poderoso proxy de API e orquestrador de tráfego, com o Keycloak, uma solução de Gerenciamento de Identidade e Acesso (IAM) de código aberto, oferece uma arquitetura resiliente e flexível para proteger endpoints de API em ambientes Linux. Este artigo detalha a implementação e configuração dessa sinergia, focando em práticas de DevOps, automação e infraestrutura como código.
Fundamentos de Arquitetura para Segurança de APIs
A estratégia aqui consiste em delegar a autenticação de usuários e clientes de API ao Keycloak, utilizando padrões como OAuth 2.0 e OpenID Connect (OIDC). O Kong Gateway, posicionado na borda da rede, intercepta todas as requisições destinadas às APIs. Sua função primária é validar tokens de acesso emitidos pelo Keycloak antes que qualquer requisição atinja o serviço de backend, garantindo que apenas tráfego autorizado e autenticado prossiga. Essa abordagem centraliza a lógica de segurança, reduzindo a complexidade nos serviços de backend e promovendo a reutilização de código.
Componentes Essenciais
- Keycloak: Servidor de autenticação e autorização que gerencia identidades, emite e valida tokens JWT (JSON Web Token), e suporta fluxos OAuth 2.0 e OIDC.
- Kong Gateway: API Gateway de alto desempenho que atua como proxy reverso, balanceador de carga, e, crucialmente, como ponto de imposição de políticas de segurança (via plugins).
- Serviços de Backend: As APIs que precisam ser protegidas. O Kong as expõe e as protege, enquanto o Keycloak garante que apenas entidades autorizadas possam interagir com elas.
- PostgreSQL: Banco de dados relacional robusto, utilizado tanto pelo Keycloak quanto pelo Kong para persistir suas configurações e dados de runtime.
Preparando o Ambiente Linux para Implantação
Para uma implantação eficiente e replicável, utilizaremos Docker e Docker Compose. Isso facilita o empacotamento das dependências e a orquestração dos contêineres. Certifique-se de que o sistema operacional Linux (por exemplo, Ubuntu Server, CentOS, Debian) esteja atualizado e com Docker e Docker Compose instalados.
Instalação do Docker e Docker Compose (Exemplo no Ubuntu)
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER # Adicione seu usuário ao grupo docker
newgrp docker # Ative as novas permissões (ou reinicie a sessão)
sudo curl -L "https://github.com/docker/compose/releases/download/v2.19.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker --version
docker-compose --version
Implantação do Keycloak via Docker Compose
Vamos configurar o Keycloak junto a um banco de dados PostgreSQL persistente. Crie um diretório de projeto e, dentro dele, um arquivo docker-compose.yml.
docker-compose.yml para Keycloak e PostgreSQL
# keycloak-compose.yml
version: '3.8'
services:
keycloak-db:
image: postgres:13
restart: always
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: ${DB_PASSWORD_KEYCLOAK:-admin}
volumes:
- ./data/keycloak-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 10s
timeout: 5s
retries: 5
keycloak:
image: quay.io/keycloak/keycloak:21.1.2
restart: always
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: ${DB_PASSWORD_KEYCLOAK:-admin}
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin}
KC_HOSTNAME: localhost
KC_HTTP_PORT: 8080
KC_PROXY: edge # Importante para integrar com gateways/proxies
KC_LOG_LEVEL: INFO
ports:
- "8080:8080"
command: start --optimized --hostname-strict=false # Desabilita hostname strict para desenvolvimento
depends_on:
keycloak-db:
condition: service_healthy
volumes:
- ./data/keycloak-config:/opt/keycloak/conf
volumes:
keycloak-db:
keycloak-config:
Este arquivo configura um serviço de banco de dados PostgreSQL e o Keycloak. As variáveis de ambiente DB_PASSWORD_KEYCLOAK e KEYCLOAK_ADMIN_PASSWORD devem ser definidas no ambiente ou substituídas por valores seguros no arquivo. O parâmetro KC_PROXY: edge é crucial para que o Keycloak funcione corretamente atrás de um proxy reverso como o Kong.
Para iniciar o Keycloak:
mkdir -p data/keycloak-db data/keycloak-config
docker-compose -f keycloak-compose.yml up -d
Aguarde alguns minutos para que o Keycloak inicie completamente. O painel de administração estará acessível em http://localhost:8080 com as credenciais admin/admin (ou as que você definiu).
Configuração Inicial do Keycloak
Após iniciar, configure o Keycloak. É uma boa prática automatizar isso com a CLI do Keycloak ou scripts de importação de realm JSON, mas para fins de demonstração, podemos fazer manualmente:
- Crie um novo Realm (ex:
minha-api-realm). - Dentro do Realm, crie um Cliente (ex:
kong-client) com as seguintes configurações:- Client type:
OpenID Connect - Access type:
confidential - Standard flow enabled:
ON(para testes) - Service accounts enabled:
ON(para o Kong obter tokens) - Valid redirect URIs:
*(para testes, em produção seja específico) - Web origins:
*(para testes, em produção seja específico)
- Client type:
- Na aba ‘Credentials’ do cliente, copie o ‘Secret’ gerado. Ele será usado pelo Kong.
- Crie um Usuário (ex:
apiuser) com uma senha.
Configuração do Kong Gateway via Docker Compose
Agora, implante o Kong Gateway. Ele também usará o PostgreSQL para persistência. Crie um novo arquivo kong-compose.yml no mesmo diretório.
kong-compose.yml para Kong e PostgreSQL
# kong-compose.yml
version: '3.8'
services:
kong-db:
image: postgres:13
restart: always
environment:
POSTGRES_DB: kong
POSTGRES_USER: kong
POSTGRES_PASSWORD: ${DB_PASSWORD_KONG:-kongpass}
volumes:
- ./data/kong-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U kong"]
interval: 10s
timeout: 5s
retries: 5
kong-migrations:
image: kong:3.3.0-alpine
command: kong migrations bootstrap
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-db
KONG_PG_PORT: 5432
KONG_PG_USER: kong
KONG_PG_PASSWORD: ${DB_PASSWORD_KONG:-kongpass}
KONG_PG_DATABASE: kong
depends_on:
kong-db:
condition: service_healthy
restart: on-failure
kong:
image: kong:3.3.0-alpine
restart: always
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-db
KONG_PG_PORT: 5432
KONG_PG_USER: kong
KONG_PG_PASSWORD: ${DB_PASSWORD_KONG:-kongpass}
KONG_PG_DATABASE: kong
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
KONG_PROXY_LISTEN: 0.0.0.0:8000, 0.0.0.0:8443 ssl
KONG_ANONYMOUS_REPORTS: "off"
ports:
- "80:8000" # HTTP para o proxy
- "443:8443" # HTTPS para o proxy
- "8001:8001" # HTTP para a API Admin
- "8444:8444" # HTTPS para a API Admin
depends_on:
kong-migrations:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8001/status || exit 1"]
interval: 10s
timeout: 5s
retries: 5
volumes:
kong-db:
Inicie o Kong Gateway:
mkdir -p data/kong-db
docker-compose -f kong-compose.yml up -d
Verifique o status do Kong em http://localhost:8001. Ele deve retornar uma resposta JSON com as informações do Gateway.
Integrando Kong com Keycloak para Autenticação OIDC
Com Keycloak e Kong em execução, o próximo passo é configurar o Kong para usar o Keycloak como provedor de identidade via OIDC. Para isso, criaremos um serviço e uma rota no Kong, e aplicaremos o plugin OpenID Connect a essa rota.
Exemplo de Serviço de API (Mock Server)
Para testar, podemos usar um simples mock server ou qualquer serviço de backend que responda a requisições HTTP.
# mock-api-compose.yml
version: '3.8'
services:
mock-api:
image: mendhak/http-https-server
environment:
HTTP_PORT: 80
CORS: "true"
ports:
- "8081:80"
restart: always
docker-compose -f mock-api-compose.yml up -d
Este mock API estará disponível em http://localhost:8081.
Configurando Serviço e Rota no Kong via CLI
Crie um Serviço no Kong que aponte para o nosso mock-api e uma Rota que exponha este serviço através do Kong.
# Criar Serviço para a API de backend
curl -X POST http://localhost:8001/services
--data name='minha-api-backend'
--data url='http://mock-api:80'
# Criar Rota para o Serviço (o tráfego para /minha-api será roteado para o serviço)
curl -X POST http://localhost:8001/services/minha-api-backend/routes
--data paths[]='/minha-api'
Agora, você pode acessar a API via Kong (sem autenticação ainda): http://localhost/minha-api (isso deve mostrar a resposta do mock-api).
Aplicando o Plugin OpenID Connect do Kong
O plugin openid-connect do Kong fará a integração com o Keycloak. Ele intercepta as requisições, redireciona o usuário para o Keycloak para autenticação e, após o sucesso, valida o JWT recebido. Configure o plugin na rota minha-api.
# Plugin OpenID Connect configurado na rota
KEYCLOAK_CLIENT_SECRET='<O SECRET GERADO PELO KEYCLOAK PARA O CLIENTE KONG-CLIENT>'
curl -X POST http://localhost:8001/routes/minha-api/plugins
--data name='openid-connect'
--data config.client_id='kong-client'
--data config.client_secret="$KEYCLOAK_CLIENT_SECRET"
--data config.issuer='http://localhost:8080/realms/minha-api-realm'
--data config.realm='minha-api-realm'
--data config.introspection_endpoint='http://keycloak:8080/realms/minha-api-realm/protocol/openid-connect/token/introspect'
--data config.auth_methods='bearer,authorization_code'
--data config.cookie_secret='super-secret-cookie-key-with-32-chars!'
--data config.upstream_headers_claim_names='preferred_username,email,sub'
--data config.public_key_cache_ttl=3600
--data config.access_token_param_names='access_token'
Substitua <O SECRET GERADO PELO KEYCLOAK PARA O CLIENTE KONG-CLIENT> pelo valor real do secret do seu cliente Keycloak. Note que o cookie_secret deve ter 32 caracteres (ou 64/128 para maior segurança).
Testando o Fluxo de Autenticação
Ao tentar acessar http://localhost/minha-api agora, o Kong deve redirecionar você para a página de login do Keycloak. Após o login bem-sucedido com apiuser, você será redirecionado de volta para http://localhost/minha-api, e a resposta do mock-api será exibida. O Kong adicionará cabeçalhos na requisição upstream com informações do JWT, como X-Consumer-Username e outros claims configurados em upstream_headers_claim_names.
Automação e Infraestrutura como Código (IaC)
Gerenciar configurações do Kong e Keycloak manualmente é inviável em ambientes de produção. A adoção de IaC é fundamental.
Kong Declarative Configuration (DEC)
O Kong suporta configuração declarativa via um arquivo YAML (kong.yml). Isso permite versionar todas as suas configurações de serviços, rotas e plugins em um repositório Git e aplicá-las ao Kong.
Exemplo de kong.yml
_format_version: "3.0"
services:
- name: minha-api-backend
url: http://mock-api:80
routes:
- name: minha-api-route
paths:
- /minha-api
plugins:
- name: openid-connect
config:
client_id: kong-client
client_secret: <O SECRET GERADO PELO KEYCLOAK PARA O CLIENTE KONG-CLIENT>
issuer: http://localhost:8080/realms/minha-api-realm
realm: minha-api-realm
introspection_endpoint: http://keycloak:8080/realms/minha-api-realm/protocol/openid-connect/token/introspect
auth_methods: bearer,authorization_code
cookie_secret: super-secret-cookie-key-with-32-chars!
upstream_headers_claim_names: preferred_username,email,sub
public_key_cache_ttl: 3600
access_token_param_names: access_token
Para aplicar este arquivo ao Kong:
docker cp kong.yml kong:/kong.yml
docker exec kong kong config reload -c /kong.yml # Ou usar `kong config push` se a API Admin estiver acessível externamente
Automação do Keycloak
O Keycloak permite exportar realms como arquivos JSON, que podem ser versionados. Para automatizar a criação de realms, clientes e usuários, pode-se usar a CLI do Keycloak (kcadm.sh) ou ferramentas como Terraform com o provedor Keycloak.
Exemplo de criação de Realm com Terraform
# main.tf
resource "keycloak_realm" "minha_api_realm" {
realm = "minha-api-realm"
enabled = true
display_name = "Realm para Minhas APIs"
access_code_lifespan = "300s"
}
resource "keycloak_openid_client" "kong_client" {
realm_id = keycloak_realm.minha_api_realm.id
client_id = "kong-client"
name = "Kong Gateway Client"
enabled = true
access_type = "CONFIDENTIAL"
service_accounts_enabled = true
standard_flow_enabled = true
valid_redirect_uris = ["*"] # Ajustar em produção
web_origins = ["*"] # Ajustar em produção
client_secret = "${var.keycloak_kong_client_secret}"
}
variable "keycloak_kong_client_secret" {
description = "O segredo do cliente para o Kong Gateway no Keycloak."
type = string
sensitive = true
}
Considerações de Produção e Boas Práticas
- Segurança de Credenciais: Nunca armazene secrets diretamente em arquivos de configuração ou repositórios Git. Utilize ferramentas de gerenciamento de segredos como HashiCorp Vault, AWS Secrets Manager, ou variáveis de ambiente seguras.
- HTTPS/TLS: Sempre configure HTTPS para o Kong Gateway e para o Keycloak. Utilize certificados TLS válidos (Let’s Encrypt, certificados corporativos). O Kong suporta a terminação TLS e o plugin
acmepara Let’s Encrypt. - Alta Disponibilidade: Em produção, o Kong e o Keycloak devem ser implantados em clusters para alta disponibilidade, com balanceadores de carga adequados e múltiplos nós para os bancos de dados.
- Observabilidade: Implemente monitoramento (Prometheus, Grafana), logging centralizado (ELK Stack, Splunk) e tracing distribuído (Jaeger, Zipkin) para diagnosticar problemas e garantir o desempenho.
- Políticas de Autorização: Além da autenticação OIDC, o Kong pode aplicar políticas de autorização mais granulares usando plugins como o
opa(Open Policy Agent) ouacl, baseando-se em grupos, roles ou claims presentes no JWT. - Limite de Taxa e Proteção contra DoS: Configure plugins como
rate-limitingeip-restrictionno Kong para proteger suas APIs contra abusos e ataques DoS.
Refinamento da Segurança com Roles e Scopes
A simples validação de um token JWT garante que a requisição é autenticada. Para autorização, é essencial verificar se o usuário ou cliente tem permissão para acessar um recurso específico ou executar uma ação. Keycloak facilita isso com roles e scopes.
- Roles (Papéis): Podem ser atribuídas a usuários ou grupos no Keycloak. Quando um token é emitido, os papéis do usuário são incluídos como claims (geralmente no campo
realm_access.rolesouresource_access.<client_id>.roles). - Scopes: Definem o escopo de acesso que um cliente está solicitando. Por exemplo, um cliente pode solicitar o scope
readouwrite. Estes scopes também são incluídos no JWT.
O Kong Gateway pode ser configurado para inspecionar esses claims do JWT. O plugin openid-connect do Kong pode ser estendido com regras de autorização personalizadas, ou plugins adicionais como o jwt (para validação mais simples) ou o opa (Open Policy Agent) para lógica de autorização complexa. Para um controle mais refinado, pode-se desenvolver um plugin customizado para o Kong que interaja com um serviço de autorização externo.
Por exemplo, para um cenário onde apenas usuários com o role admin podem acessar uma rota:
# Exemplo (conceitual, exigiria um plugin customizado ou OPA para lógica complexa)
# Adicionar o role 'admin' a um usuário no Keycloak
# ...
# Plugin hipotético para verificar roles (ou usar OPA)
curl -X POST http://localhost:8001/routes/minha-api/plugins
--data name='role-based-authorization'
--data config.required_roles='admin'
A arquitetura com Kong e Keycloak fornece uma base sólida para construir camadas de segurança avançadas, desde a autenticação básica até políticas de autorização complexas baseadas em atributos e contexto. A flexibilidade do Kong em termos de plugins e a robustez do Keycloak tornam essa combinação ideal para ambientes Linux exigentes.
Sou um profissional na área de Tecnologia da informação, especializado em monitoramento de ambientes, Sysadmin e na cultura DevOps. Possuo certificações de Segurança, AWS e Zabbix.


