Voltar para o blog

LLMJacking: como credenciais comprometidas geram custos inesperados com LLMs

Uma aplicação pode continuar saudável enquanto outra pessoa utiliza suas credenciais para consumir modelos de linguagem diretamente no provedor. O tráfego indevido não precisa atravessar seu Ingress, sua API ou seu gateway: a identidade comprometida pode ser suficiente para autorizar inferências faturadas na sua conta. Esse é o problema central do LLMJacking documentado pela equipe de pesquisa da Sysdig. (sysdig.com)

Para equipes de plataforma, a pergunta operacional deixa de ser apenas quanto custa cada resposta. Também é necessário perguntar quem pode autorizar esse gasto, de onde essa identidade pode ser utilizada e quanto tempo leva para interromper seu consumo.

Este artigo propõe uma arquitetura defensiva com Amazon Bedrock e Amazon Elastic Kubernetes Service, o Amazon EKS. O recorte é comprometimento de identidade, detecção de consumo fora do caminho autorizado e contenção financeira. Para políticas de conteúdo e remoção de dados sensíveis, consulte o artigo complementar sobre proxy de IA e redação de dados sensíveis.

O que é LLMJacking

LLMJacking é o uso não autorizado de serviços de grandes modelos de linguagem, ou Large Language Models (LLMs), por meio de acesso comprometido. Na pesquisa publicada em 6 de maio de 2024, a Sysdig descreveu credenciais cloud roubadas, descoberta de serviços utilizáveis e indícios de revenda de acesso. A vítima arcava com o consumo. (sysdig.com)

O mecanismo é diferente de manipular instruções de um modelo: neste recorte, o atacante utiliza uma identidade válida para obter capacidade de inferência. Não é necessário que ele altere o modelo ou comprometa o provedor. (sysdig.com)

Uma sequência de ameaça útil para análise é:

Aplicação vulnerável → credencial exposta → descoberta de permissões → inferência não autorizada → cobrança

Esse fluxo sintetiza o incidente descrito pela Sysdig; não significa que toda ocorrência seguirá exatamente as mesmas etapas. (sysdig.com)

Para o threat model da sua organização, considere também chaves em pipelines de integração e entrega contínuas, CI/CD, estações de desenvolvimento e workloads comprometidos. Trate essas possibilidades como hipóteses a validar no inventário, não como evidência automática de invasão.

Os controles que não devem ser confundidos

ControlePergunta que deve responder
IdentidadeQuem está fazendo a chamada?
AutorizaçãoQuais operações, modelos e recursos essa identidade pode utilizar?
Quota técnicaQual volume o serviço permite processar?
Limite financeiro de admissãoQuanto a plataforma aceita comprometer antes de bloquear novas chamadas?
AuditoriaQuem utilizou o serviço, quando e por qual caminho?
ContençãoComo impedir novas autorizações após detectar comprometimento?

Use essa separação como modelo de projeto. Não atribua a uma camada uma garantia que pertence a outra.

No Bedrock, quotas podem ser específicas por modelo e endpoint; elas não devem ser interpretadas automaticamente como um orçamento monetário global. Consulte as quotas efetivas da conta e inventarie todos os caminhos de inferência habilitados. (docs.aws.amazon.com)

Da mesma forma, uma notificação do AWS Budgets não é um bloqueio síncrono por requisição. A AWS documenta atrasos entre consumo, contabilização e notificação, durante os quais novos custos podem ocorrer. (docs.aws.amazon.com)

Como estimar a exposição financeira

Para um exercício simplificado de inferência textual, use:

custo estimado = tokens de entrada / 1.000.000 × preço de entrada + tokens de saída / 1.000.000 × preço de saída

Considere valores exclusivamente hipotéticos, sem associação a uma tabela comercial:

  • 10.000 chamadas por hora;
  • 8.000 tokens de entrada por chamada;
  • 2.000 tokens de saída por chamada;
  • US$ 2 por milhão de tokens de entrada;
  • US$ 8 por milhão de tokens de saída.

Nesse exercício, a entrada custa US$ 160/h e a saída US$ 160/h. O total é US$ 320/h, ou US$ 7.680 em 24 horas de consumo constante.

Não se trata de preço atual, benchmark ou previsão de incidente. O objetivo é dimensionar o efeito do tempo de resposta. Para planejamento, use também:

exposição aproximada = taxa de gasto × tempo até contenção efetiva + consumo já admitido

Essa expressão não é um teto garantido: a taxa pode variar. No seu cálculo, inclua os componentes faturáveis efetivos do contrato e uma margem para requisições em andamento, processamento assíncrono e incerteza de medição.

Arquitetura: impedir o desvio do caminho autorizado

Proponho o seguinte caminho para chamadas legítimas:

Cliente autenticado → aplicação → admissão financeira → executor de inferência → Bedrock

Em paralelo:

Auditoria cloud + métricas do provedor + registros da plataforma → correlação → resposta a incidentes

A regra arquitetural é manter a permissão de inferência apenas no executor autorizado. Frontends e serviços que apenas encaminham solicitações não devem receber a mesma identidade cloud.

Centralizar chamadas não resolve sozinho o roubo da identidade do executor. O próprio executor precisa de permissões restritas e controles adicionais de origem. Para conectividade privada, o Bedrock oferece endpoints de interface com AWS PrivateLink e políticas de endpoint. (docs.aws.amazon.com)

Entretanto, disponibilizar um endpoint privado não obriga uma credencial roubada a utilizá-lo. Para impor esse requisito, avalie controles de perímetro com condições como aws:SourceVpce, considerando exceções de serviços e integrações legítimas. Teste chamadas pelo caminho aprovado e por um caminho não autorizado antes de promover a política. (docs.aws.amazon.com)

Para isolamento de rede entre workloads, mantenha a política de rede como uma camada separada; o desenho de egress está no artigo sobre rede para sandboxes de agentes em Kubernetes.

Implementação: identidade dedicada no EKS

1. Criar Namespace e ServiceAccount

O manifesto abaixo é completo para os objetos declarados. Ele não instala um gateway nem configura a associação IAM:

apiVersion: v1
kind: Namespace
metadata:
  name: llm-runtime
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: llm-inference
  namespace: llm-runtime
automountServiceAccountToken: false

O Namespace separa os objetos da aplicação. O ServiceAccount identifica o workload. automountServiceAccountToken: false desabilita a montagem automática do token padrão de acesso à API Kubernetes; o campo pode ser sobrescrito no Pod. (kubernetes.io)

Configure serviceAccountName: llm-inference no template do workload autorizado. Adapte os nomes à sua convenção e não crie um RoleBinding apenas para permitir chamadas AWS: autorização Kubernetes e autorização cloud são controles distintos.

Restrinja, por controle de acesso baseado em papéis, ou RBAC, quem pode criar Pods nesse Namespace, alterar workloads ou acessar Secrets. A capacidade de criar workloads pode permitir utilizar identidades e credenciais disponíveis no Namespace. (kubernetes.io)

2. Associar uma role com EKS Pod Identity

Com o EKS Pod Identity Agent instalado nos nós compatíveis, uma role IAM preparada e um SDK AWS compatível, crie a associação:

aws eks create-pod-identity-association \
  --cluster-name production-eks \
  --namespace llm-runtime \
  --service-account llm-inference \
  --role-arn arn:aws:iam::111122223333:role/llm-inference-runtime

Substitua cluster, conta e role. A relação é administrada pelo EKS, sem annotation no ServiceAccount. A trust policy da role deve autorizar pods.eks.amazonaws.com com sts:AssumeRole e sts:TagSession; restrinja também o contexto de confiança conforme seu ambiente. (docs.aws.amazon.com)

O Pod Identity utiliza seu próprio token projetado e disponibiliza credenciais temporárias para SDKs compatíveis. Desabilitar o token padrão Kubernetes não significa eliminar esse mecanismo. Valide a identidade efetiva e remova credenciais estáticas que possam ser selecionadas pela cadeia de credenciais da aplicação. (docs.aws.amazon.com)

Credenciais temporárias ainda exigem proteção: se forem expostas, podem precisar de revogação antes da expiração. (docs.aws.amazon.com)

3. Autorizar somente os recursos necessários

Este Terraform cria uma política inline em uma role existente. O exemplo se limita a inferência direta em um foundation model:

variable "runtime_role_name" {
  type = string
}

variable "approved_model_arn" {
  type = string
}

resource "aws_iam_role_policy" "llm_inference" {
  name = "approved-llm-inference"
  role = var.runtime_role_name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid    = "InvokeApprovedModel"
      Effect = "Allow"
      Action = [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ]
      Resource = var.approved_model_arn
    }]
  })
}

Forneça o Amazon Resource Name, ARN, real do modelo aprovado. Valide suporte a inferência direta na região escolhida. A API Converse exige bedrock:InvokeModel; ConverseStream exige bedrock:InvokeModelWithResponseStream. (docs.aws.amazon.com)

Esse exemplo não é uma política universal para inference profiles, inferência cross-region ou outros endpoints. Revise os recursos exigidos pelo caminho escolhido. Além disso, um Allow restrito não remove permissões concedidas por outras políticas: revise a identidade completa e os controles organizacionais. (docs.aws.amazon.com)

Admissão financeira: antes de enviar, reservar

Para produção, recomendo implementar um controle explícito de admissão:

  1. Autenticar o chamador e derivar seu tenant no servidor.
  2. Validar modelo, tamanho da entrada, saída máxima e concorrência.
  3. Calcular uma reserva conservadora para a chamada.
  4. Reservar saldo atomicamente antes de encaminhar a inferência.
  5. Reconciliar a reserva com o consumo observado.
  6. Manter reserva pendente quando o resultado financeiro for desconhecido.

Não implemente o saldo como um contador independente em cada réplica. Projete um ledger compartilhado, operações idempotentes e recuperação após falha. PostgreSQL transacional é uma opção de projeto; Redis pode ajudar em limites de taxa, mas um contador volátil isolado não deve ser a única evidência financeira.

Para evitar confusão entre custo e capacidade, lembre que o Bedrock pode reservar quota considerando entrada e saída máxima, enquanto a cobrança considera o uso efetivo. Ajustar o máximo de saída influencia também a concorrência disponível. (docs.aws.amazon.com)

Defina limites por tenant, workload, modelo e ambiente. Dimensione também o teto global: a soma de vários limites locais pode ultrapassar a exposição aceita pela organização.

Esse desenho controla o tráfego admitido pela plataforma. Ele não limita chamadas que utilizem credenciais roubadas diretamente no provedor; por isso IAM, perímetro e reconciliação externa continuam obrigatórios.

Cenário próximo de produção

Problema: uma empresa hipotética executa workers de resumo documental no EKS. O desenho inicial compartilha uma chave entre desenvolvimento e produção e permite chamadas diretas ao provedor.

Solução: separar ambientes, substituir a chave por identidade dedicada e implantar admissão financeira com reconciliação.

Implementação proposta:

  • Executor com múltiplas réplicas distribuídas entre zonas.
  • Requests e limits definidos por testes de carga, sem confundi-los com limites de gasto.
  • Readiness para retirar réplicas indisponíveis e liveness restrita à saúde local.
  • Ledger com alta disponibilidade, backup e teste de restauração.
  • Limites globais preservados durante autoscaling.
  • Concorrência e retries limitados, com backoff e orçamento de tentativas.
  • Bloqueio de novas inferências quando não for possível reservar saldo com segurança.
  • Degradação funcional, como adiar resumos, em vez de desviar silenciosamente para uma credencial alternativa.

Resultado esperado: reduzir o alcance de uma credencial comprometida e tornar a contenção testável. Não se atribuem métricas a esse cenário fictício.

O trade-off é deliberado: falhar fechado protege o orçamento, mas pode indisponibilizar funcionalidades. Defina esse comportamento com o negócio e estabeleça um objetivo de nível de serviço, ou SLO, específico para a função assistida por LLM.

Observabilidade: detectar consumo fora da aplicação

Organize a investigação em três planos:

Auditoria de identidade

No Bedrock, operações como InvokeModel, InvokeModelWithResponseStream, Converse e ConverseStream são registradas pelo CloudTrail como eventos de gerenciamento. Outras operações exigem cobertura de eventos de dados. Não presuma que uma única configuração cobre todo o inventário. Em streaming, eventos adicionais de conclusão também exigem cuidado para não contar uma chamada duas vezes. (docs.aws.amazon.com)

Consumo do provedor

Para bedrock-runtime, acompanhe Invocations, InputTokenCount, OutputTokenCount, InvocationLatency e InvocationThrottles no CloudWatch. Observe as dimensões para não somar séries sobrepostas. Essas métricas não substituem a atribuição por tenant feita pela plataforma. (docs.aws.amazon.com)

Registros da plataforma

Proponho registrar identidade interna, modelo, identificador da requisição, reserva, consumo reconciliado e decisão de admissão. Correlacione isso com logs e traces, sem inserir prompts ou credenciais em atributos por padrão.

O model invocation logging do Bedrock é uma configuração separada e pode registrar entradas e saídas. Antes de habilitá-lo, defina retenção, criptografia, acesso e tratamento de dados sensíveis. (docs.aws.amazon.com)

Como regra de detecção, procure consumo no provedor sem chamadas correspondentes na plataforma, considerando atraso, retries, chamadas administrativas e diferenças de cobertura. Essa divergência é um sinal para investigação, não prova isolada de LLMJacking.

Defina alertas para gasto estimado por minuto, identidades inesperadas, modelos fora do inventário, backlog, falhas de reconciliação e perda de telemetria. Use orçamento faturado como confirmação posterior, não como único sensor operacional.

Resposta a incidentes: conter sem perder o controle

Prepare um runbook aprovado antes do incidente:

  1. Preservar evidências em paralelo à contenção: identidades, horários, eventos e alterações recentes.
  2. Bloquear a identidade comprometida: desativar chaves e aplicar o procedimento apropriado para sessões temporárias.
  3. Impedir a renovação do acesso: corrigir o ponto de entrada e revisar confiança, pipelines e permissões.
  4. Inventariar trabalho já iniciado: não presumir que novas negativas cancelam inferências ou jobs em andamento.
  5. Restaurar com identidade limpa: validar permissões e reintroduzir tráfego gradualmente.
  6. Reconciliar consumo e impacto: registrar a cronologia e acionar o suporte do provedor quando necessário, sem pressupor ressarcimento.

Para uma role exclusiva do executor comprometido, uma política emergencial deliberadamente abrangente é:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "IncidentContainment",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

Essa política bloqueia todas as ações AWS autorizadas por aquela role, não apenas inferência. É uma medida disruptiva, não uma configuração permanente. A AWS utiliza políticas de negação também no mecanismo de revogação de sessões; o procedimento oficial pode restringir sessões pelo horário de emissão. (docs.aws.amazon.com)

Não prometa bloqueio instantâneo nem cancelamento retroativo. Valide a eficácia por testes e telemetria. Um rollback seguro remove a contenção somente após a correção da causa, sem reintroduzir a credencial exposta.

Troubleshooting

SintomaPossível causaInvestigaçãoCorreção proposta
Cobrança aumenta, aplicação está estávelConsumo direto ou workload não inventariadoComparar identidade cloud, região e chamadas internasConter a identidade e completar o inventário
AccessDenied após migraçãoRole, associação ou recurso incorretoConferir identidade efetiva, trust policy e ARNCorrigir o escopo exato; não liberar bedrock:* indiscriminadamente
429 após aumentar réplicasConcorrência acima da quotaComparar throttling, saída máxima e tentativasReduzir concorrência e reavaliar limites
Consumo permanece após excluir PodsOutra origem ou sessões ainda utilizáveisInvestigar atividade cloud fora do clusterConter a identidade, não apenas o workload
Plataforma bloqueia chamadas legítimasLedger indisponível ou reservas pendentesExaminar disponibilidade e reconciliaçãoRecuperar o ledger e liberar reservas somente com evidência

Comandos de inspeção para o Namespace do exemplo:

kubectl get pods -n llm-runtime
kubectl get serviceaccount llm-inference -n llm-runtime -o yaml
kubectl get events -n llm-runtime --sort-by=.metadata.creationTimestamp
aws eks list-pod-identity-associations --cluster-name production-eks

A listagem das associações permite conferir cluster, Namespace e ServiceAccount; ela não comprova que a aplicação está utilizando a credencial esperada. (docs.aws.amazon.com)

Evite coletar tokens, variáveis sensíveis e dumps completos de Secrets em tickets de troubleshooting. Secrets Kubernetes precisam de controle de acesso e proteção em repouso; codificação base64 não é criptografia. (kubernetes.io)

Desenvolvimento, produção e manutenção

Em desenvolvimento, recomendo uma conta isolada, modelos aprovados, baixo teto financeiro e menor redundância. Nunca reutilize a identidade de produção para simplificar testes.

Em produção, exija responsáveis por identidade e orçamento, alta disponibilidade, TLS, backups testados, alertas acionáveis e exercícios periódicos de contenção. Versione IAM e políticas de admissão com GitOps. Antes de upgrades de SDK, modelo ou endpoint, teste autenticação, contagem de consumo, limites, negativas esperadas e recuperação.

No planejamento de capacidade, inclua requests, memória, concorrência, filas e quotas do provedor. No custo total, orce também endpoints privados, rede, armazenamento do ledger, load balancers e observabilidade. Trate a adoção de Spot no executor como uma decisão de tolerância a interrupções; não como uma redução do preço da inferência gerenciada.

Evite credenciais hardcoded, identidades compartilhadas, contadores apenas em memória, retries ilimitados, ausência de probes e mecanismos de emergência nunca testados. Não permita que o workload de inferência altere suas próprias permissões ou os controles responsáveis por detectá-lo.

Quando adotar uma plataforma central e quando simplificar

Uma camada central é indicada, como decisão arquitetural, quando vários times compartilham provedores, há múltiplos tenants ou a exposição financeira exige limites coordenados.

Para uma única aplicação de baixo volume, uma identidade restrita, isolamento de conta, limites no backend e alertas podem ser mais proporcionais. Não é necessário operar Kubernetes apenas para resolver LLMJacking.

AlternativaBenefício esperadoTrade-off
Backend direto com identidade dedicadaMenor complexidadeGovernança distribuída entre aplicações
Executor central com ledgerAdmissão financeira consistenteNovo serviço crítico para operar
Contas separadas por ambiente ou equipeFronteiras administrativas clarasMais gestão e consolidação financeira
Gateway gerenciadoMenor esforço em parte da operaçãoValidar limites, auditoria, portabilidade e bypass

Resumo prático

  • Identifique quem pode transformar uma requisição em despesa.
  • Reduza permissões e elimine credenciais compartilhadas.
  • Reserve orçamento antes de admitir novas chamadas.
  • Compare consumo cloud com o tráfego conhecido da plataforma.
  • Teste revogação, recuperação e rollback antes do incidente.

Conclusão

A defesa contra LLMJacking deve ser tratada como uma responsabilidade conjunta de DevSecOps, FinOps e engenharia de confiabilidade, ou SRE. A plataforma precisa transformar autorização de consumo em um contrato explícito: identidade, escopo, limite, evidência e procedimento de interrupção.

O objetivo não é apenas descobrir uma conta alta. É conseguir demonstrar quais chamadas eram autorizadas, limitar a exposição durante uma falha e restaurar o serviço sem restaurar a vulnerabilidade.

Quer aplicar isso no seu ambiente?

Agende uma conversa de 30 minutos sem compromisso. Eu olho o seu cenário e digo por onde começar.

Agendar uma conversa

Receba os novos artigos por e-mail

Um e-mail quando sair artigo novo sobre infraestrutura, backend e IA. Sem spam, cancele quando quiser.