/projects/airia-cloud-connector

Todos os projetos

Airia Cloud Connector

Um túnel reverso que alcança uma rede privada sem precisar abri-la.

Engenheiro de P&D — segurança, roteamento e superfície de comandos · Jun 2025 – Out 2025

.NET 9SignalRRedisJWTMCPxUnitTestcontainersHelm
Privado
Captura de tela de Airia Cloud Connector

Visão geral

Um executável único e trimado que roda dentro da rede do cliente e mantém um canal de saída aberto até a plataforma na nuvem. Tudo que a plataforma precisa do outro lado do firewall — uma chamada HTTP, uma consulta a banco, a execução de uma ferramenta MCP — volta por esse mesmo canal como um comando tipado.

O que eu fiz

Fui responsável por como o conector se autentica, como uma requisição encontra o conector certo e o que ele consegue fazer depois que chega lá.

  • TLS mútuo entre conector e hub — construído, e desligado uma semana depois.
  • Roteamento — resolver qual conector, em qual grupo de cliente, responde a uma dada requisição.
  • O tipo de comando de banco de dados, tanto para engines relacionais quanto para bancos de documentos.
  • Suporte a MCP: listar as ferramentas de um servidor interno e executá-las pelo túnel.
  • Empacotamento de release por ambiente e instalação como serviço nativo do Windows.

O repositório é três meses mais velho que minha entrada e vários engenheiros dividiam ele; a superfície de browser agent do hub é trabalho de outra pessoa.

O problema

Uma empresa contrata uma plataforma de IA na nuvem, e aí os agentes que ela constrói lá precisam dos sistemas que de fato guardam seus dados — um banco, uma API interna, um servidor MCP — todos atrás do firewall dela. As respostas padrão são VPN, túnel site-to-site ou uma regra de entrada para a faixa de endereços do fornecedor, e cada uma pede que o time de segurança abra o perímetro para um software que não é dele. O conector inverte o sentido: nada disca para dentro, então não há o que abrir.

Arquitetura

O conector abre uma conexão SignalR para fora e se registra sob um grupo de cliente. O hub guarda esse registro no Redis em vez de em memória, então qualquer instância do hub encontra qualquer conector e correlaciona a resposta — que é o que permite escalar o hub horizontalmente atrás de um balanceador. Uma requisição da plataforma vira um envelope de comando tipado, é empurrada pelo canal do conector, executada contra o que existe do lado privado, e a resposta é rastreada de volta até a instância que ainda segura quem chamou.

  1. Airia platformEmite uma requisição HTTP comum, endereçada a um grupo de cliente e não a um host.
  2. Cloud HubEmpacota como comando tipado e descobre qual conector deve responder.
  3. Redis registryGuarda o mapa conector-instância e as respostas pendentes, então o hub pode rodar com mais de uma réplica.
  4. ConnectorRecebe o comando no canal que ele mesmo já abriu, de dentro da rede do cliente.
  5. Internal serviceA API, o banco ou o servidor MCP que nunca se tornou alcançável de fora.

O que trafega pelo canal

ComandoO que a plataforma pede
HttpCall an internal API and return the response
DatabaseRun a query, or read the schema first
McpServerInfoList the tools an internal MCP server exposes
McpToolExecutionInvoke one of those tools by name
SystemInfoReport the connector’s own health and version
Somar uma capacidade é somar um tipo de comando, não outro proxy.

O que faz

  • Só saída: o conector disca para a nuvem, nunca o contrário.
  • Os testes de integração rodam contra um Redis real via Testcontainers, não contra um fake.
  • Consulta engines relacionais e bancos de documentos do lado privado, schema incluído.
  • Expõe as ferramentas de um servidor MCP interno para a plataforma pelo mesmo túnel.
  • Distribuído como um executável único, trimado e autocontido, instalável como serviço do Windows.

Decisões de engenharia

  • Inverter o sentido em vez de abrir o perímetro

    Uma conexão de saída persistente faz tudo o que uma regra de entrada faria, e não pede ao cliente nada que a política de egresso dele já não permita. A revisão de segurança que isso evita não é pequena: é a diferença entre um deploy que o time de rede aprova numa tarde e um que passa um trimestre em comitê.

  • TLS mútuo, construído e depois desligado

    Um bearer token prova o conector para o hub e não prova nada do hub para o conector, então certificados de cliente entraram nas duas pontas, com uma tolerância explícita de desvio de relógio e um erro legível no lugar de uma falha crua de handshake. Durou uma semana. Fui eu mesmo que mergeei a mudança que desligou isso, a exigência de certificado caiu no dia seguinte, e o wiring segue comentado dos dois lados — o motivo não está registrado em lugar nenhum que eu possa apontar, e não vou reconstruir um. O que vai para produção é bearer token sobre TLS. A lição honesta não é sobre criptografia: um controle de segurança que depende do time de operações do cliente segurar a outra ponta só é tão real quanto a distribuição de certificados que ninguém tinha construído ainda.

  • O registro de conectores vive no Redis, não na memória do hub

    Um conector está preso a exatamente uma instância do hub, mas uma requisição da plataforma pode cair em qualquer uma. Manter o registro e as respostas pendentes no Redis faz com que a instância que recebe a requisição consiga roteá-la até a instância que segura a conexão, e a resposta encontra o caminho de volta. Sem isso, o hub fica preso a uma réplica só — coisa estranha de aceitar no único componente por onde passa o tráfego de todo cliente.

  • Um envelope de comando único em vez de um proxy por capacidade

    HTTP veio primeiro, e banco e MCP poderiam cada um ter virado um segundo túnel com ciclo de vida próprio. Torná-los tipos de comando no canal já existente fez com que autenticação, roteamento, reconexão e correlação de resposta fossem resolvidos uma vez só. Quando o suporte a MCP entrou, nada disso precisou ser refeito — foi um novo tipo de comando e um handler.

  • Um arquivo único trimado, e o serializador que isso exige

    O conector é instalado pelo time de operações de outra empresa, numa máquina em que ninguém do lado do fornecedor consegue entrar, então ele é distribuído autocontido: sem runtime para instalar, um arquivo para copiar e, depois, um serviço nativo do Windows para sobreviver a um reboot sem humano. Trimar esse binário quebra JSON baseado em reflexão, e é por isso que o envelope de comando é serializado por um contexto gerado em tempo de compilação — uma restrição sem glamour que decorre direto de escolher um deploy que o cliente consiga de fato operar.