wlls / sec / gateway-api-x-ingress-o-que-muda-na-segurana
sec

Gateway API x Ingress: o que muda na segurança

wander·30 de set.·6 min de leitura

Se você mantém Ingress controllers em produção há alguns anos, já sabe a dor: anotações específicas de cada implementação (nginx, Traefik, ALB) que não são portáveis, comportamento de roteamento que varia entre controllers e pouca separação de responsabilidades entre quem cuida da infraestrutura e quem cuida da aplicação. A Gateway API do Kubernetes existe para resolver isso — e traz junto um modelo de segurança por padrão diferente do que o Ingress oferece.

Este post explica o que muda estruturalmente e, principalmente, o que muda no comportamento padrão de exposição de tráfego entre namespaces — o ponto mais relevante do ponto de vista de segurança.

Premissas e limitações desta análise

Antes de entrar no conteúdo, uma declaração de escopo importante: a pesquisa que baseia este texto usou como fonte exclusiva a documentação oficial do Kubernetes sobre Gateway API. Essa fonte não traz uma comparação estruturada com o Ingress, nem detalhes sobre a spec do Ingress (anotações, comportamento de controllers, limitações). A única menção a Ingress no material original é lateral, citando anotações customizadas como contraste histórico para roteamento avançado.

Por isso, os pontos sobre a Gateway API neste post são tratados como fato documentado, com link para a fonte. Os pontos sobre o Ingress "clássico" refletem conhecimento geral e amplamente estabelecido do ecossistema Kubernetes (é o modelo de API estável desde a v1.19), não citações diretas de uma fonte fornecida — trate-os como contexto, não como afirmação com referência primária anexada aqui. Também não foram testados neste ambiente nenhum dos manifestos YAML reproduzidos abaixo; eles vêm da documentação oficial e servem para ilustrar estrutura, não como cópia pronta para produção sem revisão.

O problema estrutural que a Gateway API ataca

O Ingress define um único kind (Ingress) que precisa cobrir provisionamento de load balancer, regras de roteamento HTTP e configuração específica de cada controller — tudo isso na mesma spec, ou espalhado em anotações não padronizadas. Isso gera dois efeitos conhecidos: portabilidade baixa entre implementações e nenhuma separação de papéis entre quem opera a borda da rede e quem só quer expor uma aplicação.

A Gateway API resolve isso dividindo responsabilidades em quatro kinds estáveis, descritos assim pela documentação:

  • GatewayClass: define um conjunto de gateways com configuração comum, gerenciado por um controller que implementa a classe.
  • Gateway: define uma instância de infraestrutura de tratamento de tráfego (por exemplo, um load balancer de nuvem).
  • HTTPRoute: mapeia regras HTTP de um listener do Gateway para endpoints de backend, geralmente um Service.
  • GRPCRoute: equivalente ao HTTPRoute, mas para tráfego gRPC.

O design é explicitamente role-oriented: a documentação descreve três papéis organizacionais — Infrastructure Provider (gerencia a infra que serve múltiplos clusters/tenants), Cluster Operator (políticas, acesso de rede, permissões) e Application Developer (configuração de nível de aplicação). Cada kind é pensado para ser gerenciado pelo papel correspondente, com RBAC do Kubernetes aplicado normalmente sobre objetos diferentes — algo que o Ingress, como recurso único, não separa da mesma forma.

O ponto central para segurança: isolamento por namespace é o padrão

Este é o fato mais relevante do ponto de vista de exposição de tráfego: por padrão, um Gateway só aceita Routes do mesmo namespace em que ele está definido. Rotas cross-namespace exigem configuração explícita via allowedRoutes.

Isso muda o modelo mental de segurança: no Ingress, qualquer objeto Ingress no cluster que aponte para um IngressClass compartilhado normalmente entra na configuração do controller, sem uma barreira de namespace embutida na spec — o isolamento, quando existe, costuma vir de política externa (RBAC sobre o objeto Ingress, admission webhook, ou convenção de time). Na Gateway API, o isolamento por namespace já vem como comportamento padrão da API, não como algo que você precisa impor por fora.

Veja o exemplo de Gateway da própria documentação:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: example-gateway
  namespace: example-namespace
spec:
  gatewayClassName: example-class
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    hostname: "www.example.com"
    allowedRoutes:
      namespaces:
        from: Same

O valor Same em allowedRoutes.namespaces.from é o comportamento padrão demonstrado na documentação: só HTTPRoutes do namespace example-namespace podem se anexar a este listener. O campo aceita outros valores que ampliam ou restringem esse escopo, mas a fonte consultada aqui não detalha essa enumeração — antes de configurar algo diferente de Same em produção, vale checar a referência oficial do Gateway e a página de reference do kind.

O HTTPRoute correspondente referencia o Gateway explicitamente via parentRefs:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: example-httproute
spec:
  parentRefs:
  - name: example-gateway
  hostnames:
  - "www.example.com"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /login
    backendRefs:
    - name: example-svc
      port: 8080

A documentação chama isso de modelo de confiança bidirecional: o Gateway decide quais rotas aceita (via allowedRoutes), e a rota decide a qual Gateway quer se anexar (via parentRefs). Nenhum dos dois lados sozinho consegue forçar a associação. Do ponto de vista de DevSecOps, isso é relevante porque reduz um vetor comum de erro: um time de aplicação criar uma rota que, sem querer, herda exposição pública de um Gateway compartilhado gerenciado por outro time.

Diferenças práticas: o que muda no dia a dia

Com base no que a fonte confirma, três diferenças práticas se destacam:

  1. Portabilidade da configuração de roteamento. Matching por header e weighting de tráfego (canary, blue/green) fazem parte da spec padrão do HTTPRoute. No Ingress, esse tipo de caso só era viável via anotações específicas de cada controller — a própria documentação da Gateway API cita isso como motivação histórica.
  2. Separação de RBAC por kind. Como GatewayClass, Gateway e HTTPRoute são objetos distintos, dá para conceder permissão de criar HTTPRoute a um time de aplicação sem dar acesso a Gateway ou GatewayClass — sem depender de convenção informal.
  3. Extensibilidade via custom resources em camadas. A documentação descreve a Gateway API como "extensible" justamente por permitir vincular custom resources em pontos específicos da estrutura, em vez de sobrecarregar anotações de um único objeto.

O que a fonte não cobre, e que fica como lacuna explícita: comportamento de TLS/HTTPS nos listeners (há apenas a menção ao "Gateway API TLS Guide", sem conteúdo extraído), mTLS, políticas de rede complementares (NetworkPolicy), e detalhes de RBAC granular aplicado na prática a cada kind. Se sua decisão de migração depende desses pontos — e para a maioria dos ambientes depende —, trate-os como pesquisa adicional necessária antes de qualquer corte de produção.

Recomendação condicionada

Se seu cluster já roda com múltiplos times compartilhando um Ingress controller e você resolve isolamento de exposição hoje via convenção, RBAC externo ou admission webhook customizado, a Gateway API tende a formalizar esse isolamento em vez de depender de disciplina de time. Isso reduz superfície de erro humano em ambientes multi-tenant.

Se seu cenário é um cluster único, poucos times, e o Ingress controller atual já resolve os casos de roteamento que você precisa sem acúmulo de anotações mágicas, a migração pode esperar — trocar um modelo estável por outro tem custo de aprendizado e de reescrita de manifests que precisa ser justificado por um ganho real de segurança ou expressividade, não por tendência.

Vale reforçar: como a Gateway API tem controllers específicos por implementação (assim como o Ingress tinha), o comportamento exato de TLS, health check e integração com load balancer de nuvem ainda depende de qual controller você escolhe. A portabilidade é da spec, não necessariamente de todo comportamento operacional.

Próximo passo

Antes de migrar qualquer ambiente de Ingress para Gateway API, valide três coisas no seu controller específico: suporte a GRPCRoute (se você usa gRPC), o comportamento real de allowedRoutes em cenário multi-tenant, e a cobertura de TLS pelo guia oficial da Gateway API — nenhuma dessas três é opcional para um rollout com segurança sob controle.

#gateway-api#ingress#httproute#allowedroutes#multi-tenant-kubernetes#rbac-kubernetes