27 de maio de 202611 min de leitura

Estou Criando uma Nova Aplicação no Cosmos DB: De Qual Segurança Eu Preciso, de Fato?

Sudhanshu Khera e Iria Osara

Azure

Banner - Estou Criando uma Nova Aplicação no Cosmos DB: De Qual Segurança Eu Preciso, de Fato?

TL;DR: Este artigo analisa as escolhas críticas de segurança ao iniciar uma aplicação no Azure Cosmos DB. A conclusão principal é que adotar Entra ID (em vez de chaves), restringir rede, usar consultas parametrizadas e habilitar logging desde o início evita retrabalhos e vulnerabilidades comuns. Para empresas brasileiras, isso reduz riscos de vazamento de dados e simplifica auditoria de conformidade.

Você acabou de criar uma conta Cosmos DB. O portal te entregou duas chaves e uma connection string, funcionou, e você seguiu em frente. Isso é o que a maioria dos desenvolvedores faz — e é o que causa problemas mais tarde.

Este post é um guia para desenvolvedores que estão lançando uma nova aplicação Cosmos DB e querem uma configuração segura padrão, sem complexidade enterprise. Ele foca nas decisões que importam no primeiro dia.

O modelo de ameaça honesto de dois minutos

Antes de mergulhar na configuração, vale entender o que realmente dá errado em aplicações reais.

A maioria dos problemas de segurança em qualquer workload não são ataques avançados. São erros simples que criam riscos desnecessários:

  • Vazar acidentalmente sua connection string em um arquivo .env, logs, screenshots ou pull requests.
  • Dar à sua aplicação mais acesso do que ela precisa, aumentando o blast radius quando algo dá errado.
  • Deixar sua conta aberta para a internet: um endpoint Cosmos DB sem restrições de rede é acessível de qualquer lugar. Se uma credencial vazar, nada impede um atacante de chegar aos seus dados.
  • Confiar em dados vindos de clientes sem validá-los: Cosmos DB NoSQL aceita qualquer JSON. Sua aplicação é a única barreira entre a entrada do usuário e seu banco. Queries não sanitizadas, documentos com tamanho ilimitado e concatenação de strings com risco de injection são perigos que você precisa tratar.
  • Voar cego após uma violação: se audit logs não estiverem habilitados antes de algo dar errado, você não consegue determinar o que foi acessado, quando ou por quem. Sem logs, a investigação vira adivinhação.
  • Levar para produção configurações que eram “vou arrumar antes do lançamento”.

Duas coisas para entender primeiro

Antes de configurar qualquer coisa, há dois conceitos que moldam como seu modelo de segurança do Cosmos DB funciona.

Chaves ou Entra ID?

Quando você cria uma conta Cosmos DB, ganha dois pares de chaves primária e secundária. Elas funcionam imediatamente, são simples e quase todo tutorial as usa. Essa simplicidade é também o problema.

Chaves são bearer tokens. Quem tem uma pode ler, modificar ou deletar seus dados. Com diagnostic logging habilitado, você vê o que aconteceu, quando e detalhes como IP e user agent, mas chaves compartilhadas não dão atribuição de identidade confiável para saber quem usou a chave. Se uma chave vazar, a única opção é regenerá-la e atualizar todos os sistemas que dependem dela — o que é doloroso, propenso a erros e muitas vezes incompleto.

Entra ID (antigo Azure AD) é a alternativa. Em vez de uma chave, sua aplicação ganha uma identidade (managed identity ou service principal), e você concede permissões específicas a essa identidade. O acesso pode ser escopado, auditado e revogado sem precisar rotacionar secrets em vários sistemas.

Recomendação: comece com Entra ID desde o primeiro dia, mesmo em desenvolvimento. A configuração inicial é mínima e elimina uma classe inteira de risco.

O que minha aplicação deveria realmente poder fazer?

O Cosmos DB tem dois tipos de acesso:

Camada O que controla Gerenciado por
Control plane Criar/deletar contas, databases, containers; alterar configurações Azure RBAC (via IAM)
Data plane Ler, escrever, consultar, deletar documentos Cosmos DB RBAC (built-in data roles)

A maioria dos desenvolvedores só pensa no acesso ao data plane: minha aplicação pode ler e escrever dados? Mas você também precisa pensar se sua aplicação (ou seu pipeline de CI/CD, ou seus colegas de equipe) deve poder alterar a própria conta.

Para uma aplicação típica:

  • Sua aplicação deve ter apenas acesso ao data plane, com a role mínima necessária (reader vs. contributor), escopada ao database ou container correto.
  • Desenvolvedores devem ter acesso ao data plane para desenvolvimento local, idealmente de forma restrita.
  • Pipeline de CI/CD deve ter apenas as permissões necessárias para deploy, geralmente só acesso de escrita no data plane, às vezes control plane para gerenciamento de schema/container.

Cada identidade deve ter seu próprio acesso. Evite compartilhar uma única connection string ou credencial entre usuários, ambientes ou sistemas.

A configuração mínima viável de segurança

Aqui está o que configurar antes de escrever uma única linha de lógica de negócio.

Passo 1: Desabilite a autenticação local (chaves)

Sim, faça isso mesmo em desenvolvimento. Isso força o modo de autenticação correto desde o início.

No Azure CLI:

az cosmosdb update --name <sua-conta> --resource-group <seu-rg> --disable-local-auth true

Uma vez desabilitado, as chaves não funcionam mais e todo acesso exige uma identidade Entra ID. Isso impede que alguém, incluindo você, use acidentalmente uma chave.

Se você não estiver pronto para isso, pelo menos não armazene suas connection strings em source control. Use environment variables ou um cofre seguro como Azure Key Vault. Use ferramentas que escaneiam repositórios em busca de secrets vazados.

Passo 2: Crie uma managed identity para sua aplicação

Se sua aplicação roda no Azure (App Service, Functions, Container Apps, AKS ou similar), atribua a ela uma system-assigned managed identity. Isso evita gerenciar credenciais diretamente, e o Azure faz a rotação automaticamente.

Para App Service:

az webapp identity assign --name <sua-app> --resource-group <seu-rg>

Isso retorna um principalId. Copie-o; você usará no próximo passo.

Para desenvolvimento local, use sua identidade de desenvolvedor via az login ou uma user-assigned managed identity. A classe DefaultAzureCredential no SDK do Azure lida com ambos os cenários.

Passo 3: Atribua a role RBAC correta do Cosmos DB

Conceda à sua aplicação apenas as permissões necessárias usando data plane roles.

Role ID Pode fazer
Cosmos DB Built-in Data Reader 00000000-0000-0000-0000-000000000001 Ler documentos e metadados
Cosmos DB Built-in Data Contributor 00000000-0000-0000-0000-000000000002 Ler + escrever + deletar documentos

Atribua à managed identity da sua aplicação a role apropriada:

az cosmosdb sql role assignment create \
--account-name <sua-conta> \
--resource-group <seu-rg> \
--role-definition-id "00000000-0000-0000-0000-000000000002" \
--principal-id <principal-id-da-sua-app> \
--scope "/"

--scope "/" concede acesso à conta inteira. Para escopar mais restritivamente, use "/dbs/<database>" ou "/dbs/<database>/colls/<container>". Escope tão restritivamente quanto sua aplicação realmente precisa.

Passo 4: Conecte sua aplicação usando identidade, não chaves

Atualize o código da sua aplicação para autenticar usando managed identity. O padrão é o mesmo em C#, Python, JavaScript ou Java:

C# (.NET):

using Azure.Identity;
using Microsoft.Azure.Cosmos;

var client = new CosmosClient(
    accountEndpoint: "https://<sua-conta>.documents.azure.com:443/",
    tokenCredential: new DefaultAzureCredential()
);

DefaultAzureCredential funciona em todo lugar: desenvolvimento local usa sua sessão az login, Azure usa a managed identity, CI/CD usa service principal ou federated identity. Mesmo código e, na melhor configuração, nenhum secret.

Passo 5: Ative o diagnostic logging

Habilite logging antes de precisar dele. Sem logs, investigar incidentes se torna difícil. Ative diagnostic settings e direcione os logs para um Log Analytics workspace.

Categorias recomendadas:

  • DataPlaneRequests: toda requisição aos seus dados (caro em alto volume; considere sampling)
  • QueryRuntimeStatistics: telemetria nível de query
  • PartitionKeyStatistics: útil para performance
  • ControlPlaneRequests: mudanças de configuração, importante para compliance

Passo 6: Restrinja o acesso à rede

Por padrão, seu endpoint Cosmos DB é publicamente acessível. Restrinja o acesso a faixas de IP conhecidas para reduzir a superfície de ataque.

No portal: Conta Cosmos DB → Networking → Selected networks → adicione suas faixas de IP conhecidas (seu escritório, IPs de egress do CI/CD, IPs dos desenvolvedores).

Pelo CLI:

az cosmosdb update \
--name <sua-conta> \
--resource-group <seu-rg> \
--ip-range-filter "<seu-ip>,<ip-egress-ci-cd>"

Isso reduz a superfície de ataque e deve ser tratado como baseline até você migrar para Private Endpoints.

Passo 7: Use consultas parametrizadas, sempre

Cosmos DB NoSQL aceita qualquer JSON que você enviar. Ele não protege contra queries malformadas ou injection. A única proteção é sua aplicação.

O SDK suporta consultas parametrizadas em todas as linguagens. Use-as:

// Evite concatenação de strings:
var query = $"SELECT * FROM c WHERE c.userId = '{userInput}'";

// Use consultas parametrizadas:
var query = new QueryDefinition("SELECT * FROM c WHERE c.userId = @userId")
    .WithParameter("@userId", userInput);

O mesmo princípio se aplica em todas as linguagens do SDK. Use o objeto de parâmetro, nunca concatenação de strings. Isso vale para qualquer valor que venha de entrada do usuário, parâmetros de query ou sistemas externos.

Passo 8: Ative o backup contínuo (point-in-time restore)

Perda de dados geralmente é causada por erros, não por atacantes. O backup contínuo oferece uma opção confiável de recuperação.

Ative o backup contínuo (7 ou 30 dias) para permitir restauração pontual. Ative na criação da conta se possível. A migração de periódico para contínuo é suportada em contas existentes e é uma mudança unidirecional.

No portal: Conta Cosmos DB → Backup & Restore → Backup policy → Continuous (7 days) ou Continuous (30 days).

Pelo CLI:

az cosmosdb update \
--name <sua-conta> \
--resource-group <seu-rg> \
--backup-policy-type Continuous \
--continuous-tier Continuous7Days

O que não estou pedindo para você fazer (ainda)

Este post é sobre o primeiro dia. Há coisas que importam mas não precisam acontecer no primeiro dia:

  • VNet e Private Endpoints: o Passo 6 cobre allowlist de IPs como ponto de partida. Private endpoints e integração com VNet são o próximo passo.
  • Customer-Managed Keys (CMK): relevante para cenários de compliance, mas adiciona overhead operacional. A maioria das aplicações não precisa disso inicialmente.
  • Microsoft Defender para Cosmos DB: fortemente recomendado, mas pode ser ativado quando você tiver dados que valem a pena proteger.

O objetivo é acertar a base para que você não precise redesenhar seu modelo de segurança depois.

A única coisa que pode ser difícil de desfazer

Migrar de chaves para managed identity depois significa tocar em cada deployment, cada ambiente e potencialmente cada chamada de SDK. Vira um projeto de vários dias com risco real de breaking changes.

Começar com DefaultAzureCredential desde o primeiro dia evita o problema completamente.

Checklist de referência rápida

Use isso antes de commitar seu primeiro código de verdade:

  • Autenticação local desabilitada; nenhuma chave ou connection string em source control
  • Managed identity atribuída ao compute; role RBAC escopada e atribuída; aplicação usando DefaultAzureCredential
  • Cada desenvolvedor autentica com sua própria identidade Entra ID em uma conta de dev
  • Diagnostic logging ativado e roteado para Log Analytics Workspace
  • Acesso público restrito a endereços IP conhecidos
  • Todas as queries usam valores parametrizados, nunca concatenação de strings
  • Backup contínuo ativado (7 ou 30 dias)

Recursos

Perguntas Frequentes

  • É realmente necessário desabilitar a autenticação por chaves já no desenvolvimento?
    Sim, desabilitar local authentication no início força o uso de identidade gerenciada, evitando o risco de vazamento de connection strings e facilitando a rotação de credenciais depois.

  • Qual a diferença prática entre as roles 'Data Reader' e 'Data Contributor'?
    Data Reader permite apenas leitura de documentos e metadados. Data Contributor permite leitura, escrita e exclusão. Escolha a mais restritiva que sua aplicação precisa.

  • Posso usar o Cosmos DB sem configurar firewalls de rede?
    Tecnicamente sim, mas é arriscado. Restringir a endpoints a IPs conhecidos ou usar Private Endpoints reduz a superfície de ataque e é uma prática recomendada mesmo em cenários de baixo risco.

  • O que fazer se eu já tenho uma aplicação rodando com chaves e quero migrar para Entra ID?
    A migração exige alterações em deployments, SDKs e ambientes. O artigo sugere começar com DefaultAzureCredential desde o início para evitar esse retrabalho. Se já estiver em produção, planeje a migração por etapas, mantendo as chaves temporariamente.

  • O backup contínuo (point-in-time restore) é obrigatório?
    Não obrigatório, mas fortemente recomendado. Erros humanos ou alterações acidentais podem ser corrigidos com restauração pontual. Ative de 7 ou 30 dias conforme necessidade.


Artigo originalmente publicado por Sudhanshu Khera e Iria Osara em Azure Updates - Latest from Azure Charts.

Gostou? Compartilhe:
Precisa de ajuda?Fale com nossos especialistas 👋
Avatar Walcew - Headset