SpyBara
Go Premium

claude-apps-gateway-deploy.md 2026-09-27 23:59 UTC to 2026-09-28 22:01 UTC

This page contains 3 additions and 3 deletions.

2026
Wed 9 22:58 Sat 12 03:02 Fri 18 23:58 Sat 19 23:57 Fri 25 23:58 Mon 28 22:59

Implantação e operação do gateway de aplicativos Claude

Registre o gateway com seu IdP, crie o contêiner, implante no Kubernetes ou Cloud Run e o opere: verificações de integridade, rotação de segredos, atualizações e segurança.

Esta página cobre o lado operacional da execução do gateway de aplicativos Claude: registrar um cliente OAuth em seu provedor de identidade (IdP), implantar o gateway como um contêiner e executá-lo no dia a dia. Para cada opção no arquivo gateway.yaml que o gateway lê na inicialização, consulte a Referência de configuração.

Uma implantação em produção segue quatro etapas em ordem, e as seções abaixo as correspondem. As duas primeiras são onde você faz escolhas; as duas últimas são material de referência para consultar quando estiver em execução.

  1. Configure seu provedor de identidade: registre o cliente OAuth e verifique as notas específicas do IdP para Okta, Entra e Google
  2. Implante o gateway: crie uma imagem de contêiner fixada e execute-a no Kubernetes, Cloud Run ou sua própria plataforma. Esta seção também cobre decisões de custo, bypass, múltiplos gateways e serverless
  3. Configure operações: logs, sondas de integridade, comportamento de interrupção, rotação de segredos e atualizações. Referência para quando você estiver conectando monitoramento e runbooks
  4. Revise a postura de segurança: para onde os dados fluem, o modelo de ameaça e respostas de conformidade. Referência para uma revisão de segurança

Se uma entrada ou inicialização falhar no caminho, vá direto para Solução de problemas, que é indexada no erro que você vê.

Configuração do provedor de identidade

Registre um aplicativo web OAuth/OpenID Connect (OIDC) confidencial com um único URI de redirecionamento, https://<gateway>/oauth/callback, e atribua-o aos usuários ou grupos que devem ter acesso ao gateway.

Qualquer IdP compatível com OIDC funciona: Okta, Microsoft Entra ID, Google Workspace, Keycloak, Dex, PingFederate e outros. O IdP deve atender a três requisitos:

  • Serve /.well-known/openid-configuration, sobre HTTPS em produção; o gateway aceita um emissor http://, e um emissor de loopback adicionalmente requer CLAUDE_GATEWAY_ALLOW_LOOPBACK=1
  • Suporta o fluxo de código de autorização. PKCE (Proof Key for Code Exchange) está ativado por padrão; desative-o com oidc.use_pkce: false para IdPs que não o suportam
  • Retorna email e opcionalmente groups no id_token, ou os serve do endpoint userinfo com oidc.userinfo_fallback: true

Para PKI privada, defina oidc.ca_cert_pem.

Alguns provedores lidam com email e reivindicações de grupo de forma diferente:

  • Okta: o servidor de autorização da organização em https://example.okta.com retorna um id_token fino que omite email e groups, então defina oidc.userinfo_fallback: true sempre que o usar como issuer. Um servidor de autorização personalizado como https://example.okta.com/oauth2/default que inclui email e opcionalmente groups no id_token os emite diretamente e não precisa de fallback. Okta emite groups apenas quando o escopo groups é solicitado em oidc.scopes e o filtro de reivindicação de grupos do aplicativo o permite; userinfo_fallback não pode preencher uma reivindicação que o IdP não foi solicitado.
  • Microsoft Entra ID: issuer = https://login.microsoftonline.com/<tenant-id>/v2.0. Entra emite Object IDs de grupo em vez de nomes, então use os GUIDs em managed.policies.match.groups, ou use App Roles para nomes legíveis por humanos. Se seu locatário emite funções sob roles em vez de groups, defina oidc.groups_claim: roles.
  • Google Workspace: issuer = https://accounts.google.com. O id_token do Google não carrega grupos. Para usar allowed_groups baseado em grupo ou managed.policies com Google como IdP, configure oidc.google_groups, que procura os grupos de cada usuário através da API do Directory do Admin SDK usando uma conta de serviço com delegação em todo o domínio. Sem isso, use oidc.allowed_email_domains para gating de associação e managed.policies.match.email_domain para atribuição de política. Google também ignora o escopo padrão offline_access. Para tokens de atualização, defina oidc.scopes: [openid, profile, email] e oidc.extra_auth_params: { access_type: offline, prompt: consent }.

Implantação

O gateway é um único binário Linux sem estado que se coordena através do Postgres, então implante-o da forma como você implanta qualquer outro serviço sem estado em seu ambiente. Mantenha-o dentro de sua rede, onde seus desenvolvedores e IdP possam alcançá-lo via HTTPS, e trate-o como qualquer serviço que mantém uma credencial de produção.

Algumas decisões moldam a implantação além de onde ela é executada:

  • Custo: sem licença separada ou taxa por assento. O gateway é parte do binário claude, então você paga pela inferência através de seu compromisso existente, mais a computação em que ele é executado.
  • Bypass: o gateway não impõe que a única rota para um modelo passe por ele. Um desenvolvedor com sua própria credencial ainda pode chamar o provedor diretamente, então fechar esse caminho é uma decisão de política de rede, por exemplo, bloqueando a saída para api.anthropic.com exceto do gateway. Bloquear essa saída também quebra a verificação de segurança de domínio WebFetch, que chama api.anthropic.com de cada máquina do desenvolvedor. Defina skipWebFetchPreflight: true na política gerenciada para desativá-lo.
  • Múltiplos gateways: cada um é uma implantação separada com sua própria configuração, e o CLI armazena confiança e credenciais por nome de host do gateway, então equipes podem usar diferentes gateways sem conflito. Para servir múltiplos emissores OIDC, execute instâncias separadas.
  • Serverless: Cloud Run funciona se você definir min-instances: 1 para evitar descoberta OIDC fria. Lambda e Cloud Functions não funcionam, porque o gateway é um servidor HTTP de longa duração.

Cada topologia de produção aqui coloca um proxy L7, como um Ingress, o front-end do Cloud Run ou um ALB, na frente de réplicas HTTP simples. Defina listen.trusted_proxies para os intervalos de origem do proxy para que o gateway leia IPs de cliente de X-Forwarded-For. O gateway honra o cabeçalho apenas quando o par TCP é confiável. Os exemplos trabalhados do Google Cloud e AWS têm valores concretos por topologia. Sem proxies confiáveis, cada solicitação parece vir do IP do proxy, o que colapsa limites de taxa por IP em um balde compartilhado e registra o IP do proxy em eventos de auditoria.

Não redirecione solicitações para os endpoints de autorização de dispositivo e token do gateway, por exemplo com uma reescrita HTTP-para-HTTPS ou canonicalização de host no ingress. Claude Code não segue redirecionamentos nessas solicitações, então uma regra de ingress que os redireciona quebra o sign-in e a atualização de token.

Dê ao proxy qualquer tempo limite de inatividade mais longo que o intervalo de keepalive do gateway, que depende do upstream:

  • Em cada upstream exceto provider: anthropic, o gateway escreve um ping SSE uma vez que um stream tenha ficado silencioso por cerca de 15 segundos.
  • Em provider: anthropic, o gateway passa a resposta inalterada, incluindo os próprios pings da API Anthropic.

Um padrão como os 60 segundos do ALB é suficiente para manter um stream silencioso aberto. O exemplo trabalhado do AWS o aumenta para uma hora de qualquer forma, e sua linha de troubleshooting cobre gateways mais antigos que v2.1.229, que não enviavam nada durante períodos silenciosos nos upstreams que agora recebem pings.

Imagem de contêiner

Construa sua própria imagem em torno do binário nativo claude da versão padrão do Claude Code:

  1. Baixe a compilação Linux para a arquitetura de sua imagem de uma versão fixada; consulte Instalar uma versão específica para a URL de download.
  2. Verifique-a contra o manifest.json assinado por GPG da versão conforme descrito em Integridade binária e assinatura de código.
  3. Copie-a para o contexto de compilação.

Espelhe a versão em seu registro interno se suas compilações não conseguirem alcançar o host de versão, e fixe a versão que sua frota executa.

Além do binário, a imagem precisa:

  • Uma imagem baseada em glibc: a compilação glibc tem apenas dependências dinâmicas de bibliotecas glibc. Imagens baseadas em Musl precisam da compilação linux-x64-musl ou linux-arm64-musl mais pacotes adicionais; consulte Configuração do Alpine Linux.
  • Um diretório de estado gravável: o gateway é executado como qualquer usuário, mas imagens mínimas não têm home gravável. Defina CLAUDE_CONFIG_DIR para um caminho gravável como /tmp/.claude.
  • O comando do contêiner: claude gateway --config /etc/claude/gateway.yaml, com o arquivo de configuração montado como somente leitura e segredos fornecidos como variáveis de ambiente; o gateway escuta em listen.port, padrão 8080.

Kubernetes

Execute o gateway como uma Deployment, como qualquer serviço sem estado:

  • Monte a configuração de um ConfigMap e segredos de um Secret; referencie segredos no YAML via ${file:/path/to/secret} ou como variáveis de ambiente
  • Termine TLS no Ingress e defina listen.public_url para o nome de host do Ingress
  • Aponte a sonda de prontidão para GET /readyz e a sonda de vivacidade para GET /healthz

Para um exemplo trabalhado completo no AWS, cobrindo ECS Fargate ou EKS, Amazon RDS e AWS Secrets Manager, consulte Implantar no AWS.

Prefira a identidade de carga de trabalho da plataforma em relação a chaves estáticas; a referência upstreams tem detalhes de configuração por plataforma. Para um emparelhamento entre nuvens, como um upstream Bedrock do Amazon no GKE, defina credenciais explícitas no bloco auth do upstream.

Cloud Run

Configure o serviço da seguinte forma:

  • Deixe listen.port em seu padrão de 8080, que corresponde ao PORT padrão do Cloud Run, ou defina port: ${PORT}
  • Defina public_url para a origem externamente alcançável. Para produção, isso normalmente é o nome de host de um balanceador de carga interno, porque /login rejeita endereços públicos e a URL *.run.app se resolve para um, então a URL do Cloud Run sozinha funciona apenas para um teste de fumaça curl ou navegador. A exceção é uma rede onde *.run.app se resolve privadamente através do Private Service Connect e uma zona privada do Cloud DNS; nessa topologia a URL do Cloud Run é um public_url válido. O exemplo trabalhado do Google Cloud cobre ambos.
  • Monte a configuração como um volume secreto
  • Defina min-instances: 1 para evitar descoberta OIDC fria na primeira solicitação

Para um exemplo trabalhado completo no Google Cloud, cobrindo Cloud Run ou GKE, Cloud SQL e Secret Manager, consulte Implantar no Google Cloud.

Envie a URL do gateway para máquinas de desenvolvedores

Assim que o gateway estiver servindo, envie forceLoginMethod, forceLoginGatewayUrl e parentSettingsBehavior: "merge" para a máquina de cada desenvolvedor através de configurações gerenciadas, via MDM ou escrevendo o managed-settings.json por SO diretamente. Sem isso, /login mostra o seletor de conta padrão sem opção de gateway.

Uma vez que você implanta as chaves, Claude Code para de usar uma chave de API restante ou login claude.ai na máquina, então planeje o envio junto com suas instruções de sign-in. A política do administrador requer um sign-in de gateway Cloud descreve as mensagens que os desenvolvedores veem.

Consulte onde cada mecanismo armazena a política para os caminhos de arquivo, e Configurações gerenciadas do lado do cliente para o equivalente bootstrapUrl do Claude Desktop.

Grandes implantações

O sign-in é limitado por taxa por endereço IP do cliente, e os padrões se adequam a uma pequena equipe. Cada endereço recebe 30 inícios de sign-in e 10 envios de código a cada 10 minutos. Uma implantação para milhares de desenvolvedores pode atingir esses limites na primeira manhã, por uma de duas razões:

  • O gateway não consegue ver além do seu balanceador de carga. Sem listen.trusted_proxies, cada desenvolvedor parece vir do endereço do balanceador de carga e compartilha um limite. Defina-o antes de qualquer outra coisa. O gateway registra um aviso na primeira vez que ignora um cabeçalho X-Forwarded-For.
  • Muitos desenvolvedores compartilham alguns endereços de saída NAT ou VPN. Eles compartilham os limites desses endereços mesmo quando trusted_proxies está correto. Aumente rate_limits para se adequar.

Para dimensionar max, divida os desenvolvedores pelos endereços de saída que eles compartilham. Estime quantos desses fazem sign-in dentro de um período window_seconds, que é 10 minutos por padrão. Depois dobre para cobrir tentativas novamente e desenvolvedores que fazem sign-in tanto para Claude Code quanto para Claude Desktop.

Por exemplo, 10.000 desenvolvedores atrás de 4 endereços de saída fazem sign-in uniformemente ao longo de uma hora. Isso é 2.500 desenvolvedores por endereço e cerca de 420 deles em cada 10 minutos, que você dobra e arredonda para 1.000. O exemplo abaixo define ambos os limites para 1.000:

rate_limits:
  device_authorization: { max: 1000, window_seconds: 600 }
  device_verify: { max: 1000, window_seconds: 600 }

device_verify é o que impede alguém de adivinhar o código de sign-in de outro desenvolvedor, então aumente-o apenas o quanto sua estimativa precisa. Mesmo nestes limites, um código tem 8 caracteres de um alfabeto de 20 caracteres e expira após 10 minutos, então adivinhar permanece impraticável; consulte Resistência de força bruta de código de usuário.

Quando seu IdP emite tokens de atualização, Claude Code renova sessões silenciosamente, então você pode colocar o limite de volta após a implantação. Sem tokens de atualização, desenvolvedores fazem sign-in novamente a cada session.ttl_hours. Dimensione ambos os limites para essa taxa constante também e deixe-os elevados.

Quando um limite é atingido, Claude Code v2.1.274 ou posterior mostra The gateway is limiting sign-in attempts right now. Um gateway na v2.1.274 ou posterior mostra Too many attempts came from your network address na página de verificação, com as configurações a verificar. Também escreve uma linha de log sign-in refused que nomeia a configuração a alterar.

Operações

Assim que o gateway estiver servindo tráfego, a operação do dia a dia é ler seus logs, sondar sua saúde e girar seus segredos em seu cronograma. As subseções cobrem cada uma, mais o que o Postgres mantém e como atualizações e reversões se comportam.

Logs

O gateway escreve dois fluxos para stderr, ambos amigáveis a JSON:

  • Eventos de auditoria: JSON de linha única por evento relevante para segurança. Canalize stderr para seu agregador de logs.

    Os eventos emitidos incluem config.load, session.mint, session.refresh, device.authorize, device.verify, device.callback, auth.denied, access.denied, access.public_client, inference, managed.serve, desktop_bootstrap.serve, desktop_bootstrap.denied, spend.blocked, admin.denied, admin.limit.upsert e admin.limit.delete. Os campos variam por evento:

    • Eventos de mint e refresh bem-sucedidos carregam sub, email, client_ip e o resultado
    • auth.denied e access.denied carregam o motivo e IP do cliente, mais o caminho da solicitação para auth.denied, já que nenhuma identidade de usuário existe nessas negações. Dois motivos de access.denied mudam o que o evento carrega:
      • xff_unparseable: o evento também carrega a entrada X-Forwarded-For que não pôde ser lida
      • client_ip_unknown: o evento não carrega IP do cliente, porque a conexão não tinha endereço de peer enquanto uma lista de access_control estava definida
    • access.public_client carrega o IP do cliente da primeira solicitação por processo a chegar de um endereço público enquanto access_control.allow_cidrs está vazio. O gateway serve a solicitação como de costume; o evento sinaliza que o gateway pode ser alcançável a partir da internet pública. Veja a referência de access_control para o que conta como público e para a lista de permissões recomendada.
    • inference registra qual upstream serviu a solicitação e o status da resposta
    • desktop_bootstrap.denied registra uma busca de bootstrap do Claude Desktop rejeitada com o motivo (not_configured, policy_not_opted_in ou no_policy_matched) e a identidade do usuário
    • admin.denied registra uma tentativa de autenticação de API de administrador rejeitada com o IP do cliente, método, caminho e um motivo, sem o material de chave apresentado: invalid_key quando um x-api-key foi apresentado mas não correspondeu a nenhuma chave configurada, bearer_rejected quando apenas um cabeçalho Authorization foi apresentado e não verificou como uma sessão de gateway em admin.admin_groups, ou no_credentials quando nenhum cabeçalho foi apresentado
  • Logs operacionais: linhas legíveis por humanos com prefixo [gateway] para inicialização, avisos e erros upstream. A variável de ambiente CLAUDE_GATEWAY_LOG_LEVEL controla a verbosidade e aceita debug, info, warn ou error, com info como padrão. Em debug, cada entrada e atualização também registra os nomes, não os valores, das reivindicações no id_token, mais os nomes das reivindicações de userinfo quando userinfo_fallback forneceu alguma, para que você possa diagnosticar configurações de email_claim e groups_claim sem registrar PII. Não afeta eventos de auditoria, que são sempre emitidos.

Saúde

O gateway serve GET /healthz como uma sonda de vivacidade e GET /readyz como uma sonda de prontidão; /readyz verifica se o armazenamento é alcançável. Ambos estão isentos de access_control.allow_cidrs, então as sondas continuam funcionando em um listener bloqueado.

O documento de descoberta OAuth em /.well-known/oauth-authorization-server também retorna 200 apenas após carregamento de configuração, descoberta OIDC, construção de cliente upstream e migração do Postgres, então funciona como uma verificação de inicialização de ponta a ponta.

Solicitações upstream simultâneas

Por padrão, cada réplica de gateway envia no máximo 256 solicitações upstream ao mesmo tempo. Uma resposta de streaming conta contra o limite até que o stream termine.

Uma solicitação que chega enquanto uma réplica está no limite aguarda dentro do gateway por um slot livre. O desenvolvedor vê uma resposta que é lenta para começar ou parece travar. Em um upstream provider: anthropic, uma solicitação que aguarda mais tempo que timeouts.upstream_ttfb_ms desiste desse upstream e falha com um 502 quando nenhum upstream posterior o serve.

A linha de log de inicialização que contém upstream requests: mostra o limite em vigor. Enquanto uma réplica tem mais solicitações abertas que o limite, ela também registra um aviso que contém client requests are open, no máximo uma vez por minuto.

Para servir mais solicitações ao mesmo tempo, você tem duas opções:

  • Adicione réplicas.
  • Aumente o limite em cada réplica. Defina a variável de ambiente BUN_CONFIG_MAX_HTTP_REQUESTS no contêiner do gateway para um número inteiro de 1 a 65535, depois reinicie o contêiner.

Uma réplica preenche seu limite a uma taxa de solicitação de aproximadamente o limite dividido pelo número médio de segundos que uma solicitação permanece aberta. Por exemplo, se as solicitações permanecerem abertas por 10 segundos em média, uma réplica no limite padrão de 256 a preenche a cerca de 26 solicitações por segundo.

Se você fizer autoscaling em CPU, uma réplica no limite enfileira solicitações sem disparar uma expansão, então defina o alvo abaixo do nível de CPU que suas réplicas mostram quando registram o aviso client requests are open.

Comportamento de interrupção

Se o Postgres cair, o gateway em si continua servindo desenvolvedores conectados e novas entradas falham. Se os desenvolvedores realmente continuam funcionando depende de como seu orquestrador lida com prontidão:

  • Sessões existentes: tokens portadores validam localmente com o segredo JWT, atualizações de sessão não tocam o armazenamento e o processo do gateway ainda pode servir inferência
  • Novas entradas: falham até que o Postgres se recupere, porque o fluxo de dispositivo e seus contadores de limite de taxa vivem no Postgres
  • Aplicação de limite de gastos: falha aberta por padrão durante a interrupção, então a inferência ainda flui; inverta para falha fechada se preferir bloquear do que executar sem medição
  • Prontidão: /readyz relata não-pronto durante a interrupção, então orquestradores que controlam tráfego na prontidão removem cada réplica da rotação de uma vez. Nessa topologia todo tráfego, incluindo inferência que o gateway ainda poderia servir, falha no balanceador de carga até que o Postgres se recupere. A sonda de vivacidade em /healthz continua passando, então as réplicas não são reiniciadas. Aponte a sonda de prontidão para /healthz em vez disso se preferir que desenvolvedores conectados continuem funcionando através de uma interrupção de armazenamento; o custo é que novas entradas falham contra uma réplica que ainda relata pronto.

Se seu IdP cair, as sessões existentes funcionam até ttl_hours, novas entradas falham e uma atualização de sessão recebe uma resposta de tentar novamente e passa uma vez que o IdP está de volta. Defina um ttl_hours mais longo se seu IdP tiver janelas de manutenção frequentes.

Rotação de segredo JWT

Gire o segredo de assinatura em etapas para que as sessões existentes permaneçam válidas:

  1. Gere um novo segredo. Coloque-o no início da matriz session.jwt_secret.
  2. Implante a implantação. Novos tokens assinam com o novo segredo; tokens antigos ainda verificam.
  3. Após ttl_hours mais uma margem, remova o segredo antigo e implante novamente.

A rotação também é a única maneira de forçar sessões para fora antes de expirarem: tokens portadores validam localmente contra o segredo JWT, então não há revogação por sessão. Substituir o segredo completamente, sem manter o antigo na matriz, invalida cada sessão pendente de uma vez. Para offboarding individual, desprovision o usuário em seu IdP; sua sessão termina dentro de ttl_hours.

Postgres

O gateway mantém cinco tabelas de dados mais uma tabela _migrations, todas criadas por suas migrações de tempo de inicialização:

Tabela Conteúdo Retenção
kv Concessões de dispositivo (TTL de 10 minutos) e contadores de limite de taxa TTL por linha
spend Contadores de gastos período-até-data por principal, em centavos admin.spend_retention_months, padrão 13
spend_limits Limites de gastos configurados Até deletado via API
admin_audit Trilha de mutação de API de administrador admin.audit_retention_days, padrão 365
principal_emails Email, nome de exibição e grupos de IdP de cada principal vistos pela última vez. Contém PII. admin.identity_retention_days desde última atividade, padrão 90

Um loop de 30 segundos expira linhas kv após seu TTL, e uma varredura horária impõe as janelas de retenção nas tabelas de gastos, então nada cresce sem limite. Sem limites de gastos configurados, apenas kv é escrito. O gateway aplica suas próprias migrações de esquema na inicialização e em cada atualização, então sua função de banco de dados precisa de direitos para criar e alterar tabelas. Aponte-a para um banco de dados ou esquema dedicado ao gateway para manter essa concessão estreita.

Com limites de gastos em uso, um banco de dados perdido significa rastreamento de gastos e limites perdidos, não apenas re-entradas de desenvolvedores, então execute backups regulares. Para apagar um desenvolvedor que partiu imediatamente em vez de esperar pela retenção, execute DELETE FROM principal_emails WHERE principal = '<sub>' diretamente; isso remove a única tabela que mantém seu email, nome e grupos. Linhas spend e admin_audit referenciam apenas o sub OIDC pseudônimo.

Atualizações

As réplicas são sem estado, então uma reinicialização contínua não perde nenhum estado do gateway. O gateway executa migrações de esquema na inicialização, o que significa que implantar o novo binário auto-migra o banco de dados. Réplicas concorrentes serializam em um bloqueio consultivo do Postgres, então apenas uma aplica cada migração.

Quando seu orquestrador para uma réplica com SIGTERM, como em uma reinicialização contínua ou uma redução de escala, o gateway para de aceitar novas conexões e deixa as solicitações e streams já em voo terminarem antes de sair. Ele aguarda até 25 segundos, chamado de janela de drenagem, depois fecha o que ainda está aberto. Um SIGINT, como Ctrl+C em um terminal, inicia a mesma drenagem, e um segundo sinal durante a drenagem fecha as solicitações abertas e sai imediatamente. A drenagem requer gateway v2.1.274 ou posterior.

Gerações longas podem fazer streaming por minutos. No Kubernetes e Amazon ECS, aumente ambas juntas para dar a esses streams mais tempo:

  • A janela de drenagem: defina a variável de ambiente CLAUDE_GATEWAY_DRAIN_TIMEOUT_MS no contêiner do gateway para um número inteiro positivo de milissegundos, como 120000. O gateway ignora um valor em qualquer outra forma, como 120s, e mantém o padrão de 25 segundos
  • O período de carência do seu orquestrador: terminationGracePeriodSeconds no Kubernetes, ou stopTimeout no Amazon ECS

O período de carência padrão é 30 segundos em ambas as plataformas. Mantenha-o pelo menos 5 segundos mais longo que a janela de drenagem, ou o orquestrador matará o gateway antes da drenagem terminar. No Kubernetes, adicione também a duração de qualquer hook preStop, porque o período de carência começa a contar antes do hook ser executado em vez de quando o gateway recebe SIGTERM.

Sua plataforma também pode limitar quanto tempo a drenagem pode executar:

  • Amazon ECS no Fargate: stopTimeout permite no máximo 120 segundos
  • Cloud Run: para uma instância 10 segundos após SIGTERM, então streams abertos recebem no máximo 10 segundos lá, qualquer que seja a janela de drenagem

Quando a janela de drenagem termina com solicitações ainda abertas, o gateway registra um aviso que contém drain window over after, conta as solicitações que cortou e nomeia ambas as configurações para aumentar.

As migrações são apenas anexadas, então reverter para um binário anterior que conhece menos migrações é seguro; ele ignora as linhas extras. A reversão também re-valida o YAML contra o esquema do binário mais antigo, então uma configuração que adotou uma chave introduzida pela versão mais nova falha na inicialização no mais antigo. Remova a nova chave antes de reverter.

Como você fixa a versão do gateway em sua própria imagem, correções em novas versões do Claude Code, incluindo correções de segurança, chegam à sua implantação apenas quando você atualiza o pino e reimplanta. Inclua o gateway no mesmo ciclo de patch que você usa para outros serviços que mantêm credenciais de produção.

Segurança

Esta seção responde às perguntas que uma revisão de segurança faz: quais dados fluem através do gateway e para onde vão, quais ataques o design se defende e quais respostas pertencem a um questionário de conformidade.

Fluxo de dados

Dados Caminho Enviado para Anthropic pelo gateway
Inferência (prompts, conclusões) CLI → gateway → seu upstream Apenas se a API Anthropic for um upstream configurado
Telemetria (métricas OTLP, mais logs e rastreamentos opcionais) CLI → gateway → seu coletor Nunca
Identidade (email, grupos, sub) IdP → gateway → JWT → CLI; o CLI o carimba em exportações OTLP. Se você ativar forward_user_identity, o gateway também envia o email do desenvolvedor e o assunto do IdP como cabeçalhos para seu proxy Nunca
Configurações gerenciadas Seu YAML de gateway → CLI Nunca
Log de auditoria Gateway stderr → seu agregador Nunca

Resumo do modelo de ameaça

O gateway fica dentro do perímetro de rede, mas laptops de desenvolvedores individuais não são tratados como confiáveis. O design leva isso em conta de três maneiras:

  • Os desenvolvedores mantêm JWTs de curta duração em vez de chaves upstream brutas. A perna CLI-para-gateway usa a concessão de dispositivo RFC 8628, e a troca de código de autorização do gateway com o IdP executa PKCE na configuração padrão, então um código de autorização IdP interceptado é inútil.

  • A página de verificação de dispositivo impõe POST de mesma origem e um limite de taxa por IP por RFC 8628 §5.1. Consulte Resistência de força bruta de código de usuário.

  • As solicitações do gateway para seu IdP, seus coletores OTLP e upstreams provider: anthropic passam por uma proteção de falsificação de solicitação do lado do servidor (SSRF) que resolve DNS, bloqueia endereços link-local e metadados de nuvem mais loopback por padrão e fixa a conexão ao IP resolvido, então URLs influenciadas pelo operador não podem ser redirecionadas para endpoints de metadados de nuvem. Intervalos privados RFC 1918 são deliberadamente permitidos, porque IdPs e coletores OTLP comumente vivem em IPs privados. Para os outros provedores, o gateway recusa um base_url que nomeie um desses endereços ou um nome de host de metadados quando carrega a configuração, e o SDK do provedor então se conecta sem a verificação de DNS.

    Se você ativar egresso somente proxy, essa verificação de endereço se move para seu proxy direto: o gateway entrega nomes de host e a lista de permissões do proxy deve recusar esses destinos.

    Defina CLAUDE_GATEWAY_ALLOW_LOOPBACK=1 no ambiente do gateway apenas quando algo que o gateway deve alcançar legitimamente vive em loopback, como um IdP de desenvolvimento local ou um coletor OTLP sidecar em localhost. A variável relaxa o bloqueio de loopback para cada URL configurada pelo operador e também pula o aviso de tempo de inicialização que verifica se o pod pode alcançar o endpoint de metadados de nuvem, então prefira dar ao coletor seu próprio endereço interno.

Se você adicionar seus próprios controles de saída, o gateway deve alcançar o servidor de metadados sempre que usar credenciais de metadados de instância como identidade de carga de trabalho.

Duas ameaças estão fora do escopo porque são sua infraestrutura para proteger:

  • Um host de gateway comprometido: o host mantém a credencial upstream e distribui configurações gerenciadas para cada desenvolvedor conectado, então o controle sobre a configuração do gateway é comparável ao controle sobre seu MDM. O diálogo de aprovação do CLI para configurações capazes de shell limita mudanças silenciosas, mas não substitui a segurança do host.
  • Um provedor OIDC malicioso: o provedor assina os id_tokens que o gateway confia, então pode afirmar qualquer identidade. Verificar e proteger seu IdP é sua responsabilidade.

Resistência de força bruta de código de usuário

O user_code que um desenvolvedor digita na página de verificação /device tem 8 caracteres extraídos de um alfabeto de 20 caracteres, o que produz 20⁸ ou cerca de 2,56×10¹⁰ combinações, e expira após 10 minutos.

O gateway aplica limites de taxa por IP nos endpoints de concessão de dispositivo, configuráveis via rate_limits. Aumente os limites se muitos desenvolvedores entrarem de um único endereço NAT corporativo compartilhado. Grandes implantações mostra como dimensioná-los. Os limites se aplicam apenas ao fluxo de entrada, não à inferência.

Postura de conformidade

  • Residência de dados: o plano de dados do próprio gateway não envia nada para Anthropic a menos que a API Anthropic seja um upstream configurado; quando é, seu acordo de tratamento de dados existente se aplica ao caminho de inferência. Telemetria, auditoria, identidade e configurações vão apenas para os destinos que você configura.
  • Tráfego de processo de host: o processo de host é o CLI do Claude Code. O claude gateway é executado sob as mesmas regras de terceiros que as implantações do Amazon Bedrock e da Agent Platform do Google Cloud e não envia nada para Anthropic. Antes da v2.1.227, o processo de host enviava telemetria de inicialização como versão do produto e plataforma, que a configuração de CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 no ambiente do contêiner desativava. Essas versões também enviavam uma solicitação HEAD na inicialização, sem corpo ou credenciais, para /api/hello em https://api.anthropic.com, ou em ANTHROPIC_BASE_URL quando o ambiente a definiu, a menos que o ambiente também definisse uma variável de proxy como HTTPS_PROXY ou um certificado de cliente mTLS. Eles ignoravam a resposta, então bloquear essa solicitação no firewall de saída não afetava o gateway.
  • Análises do cliente: o CLI desativa sua própria análise de uso e relatório de erros enquanto conectado a um gateway. Antes do primeiro login, o CLI ainda envia eventos de inicialização para Anthropic, incluindo em máquinas cujas configurações gerenciadas forçam o login do gateway. Para manter aqueles desativados também, entregue DISABLE_TELEMETRY nas mesmas configurações gerenciadas do lado do cliente que forçam o login do gateway.
  • Relatório de erros: o CLI desativa o relatório de erros sempre que suas solicitações de modelo vão para qualquer endpoint diferente da API de primeira parte da Anthropic, como Amazon Bedrock ou um ANTHROPIC_BASE_URL personalizado.
  • Máquinas do cliente: CLIs de desenvolvedores ainda enviam verificações de nome de host WebFetch e verificações de versão para Anthropic a menos que CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 e skipWebFetchPreflight: true sejam definidos. Consulte uso de dados.
  • Classificações de pesquisa: enquanto conectado a um gateway, o CLI desativa o upload de classificação vinculado a Anthropic junto com os fluxos de análise, então não envia classificações para Anthropic.
  • Compartilhamento de transcrição: escolher Sim em um prompt de compartilhamento de transcrição de pesquisa escreve um arquivo local em ~/.claude/feedback-bundles/ em vez de fazer upload para Anthropic.
  • Atualizações do cliente: verificações de atualização são separadas do tráfego do gateway. Fixe versões através de sua própria distribuição e defina DISABLE_UPDATES se laptops não devem buscar versões. DISABLE_AUTOUPDATER para apenas atualizações de fundo enquanto claude update ainda funciona.
  • TLS: sirva public_url sobre HTTPS em produção, seja do próprio listener do gateway via listen.tls ou de um ingress que termina TLS na frente de réplicas HTTP simples, com listen.public_url definido em ambos os casos. O gateway não recusa HTTP simples. O IdP deve servir HTTPS em produção, e o Postgres suporta ?sslmode=require. Defina Strict-Transport-Security em seu ingress.
  • Divulgação de vulnerabilidade: siga Relatando problemas de segurança

Troubleshooting

Para dúvidas e feedback, use Claude Code support, ou abra uma issue no repositório Claude Code GitHub. Ao relatar um problema, inclua:

  • Gateway issue: o stderr do gateway para a janela relevante, seu gateway.yaml com segredos removidos, a versão do gateway, mostrada na página inicial em / e no cabeçalho de resposta x-cc-gateway-version em /managed/settings, e o que mudou recentemente
  • Login issue: o desenvolvedor executa claude --debug-file ./claude-debug.txt, reproduz, e envia esse arquivo mais o log de auditoria do gateway para a mesma janela
  • Inference issue: o modelo solicitado, os upstreams configurados, e o log de auditoria do gateway para a solicitação, que registra qual upstream a serviu e o status da resposta

O stderr do gateway inclui o fluxo de eventos de auditoria, o log de auditoria registra identidades de desenvolvedores, e o arquivo de debug registra saída de hook e servidor MCP da máquina do desenvolvedor. Revise e remova essas informações antes de postar em uma issue pública.

Symptom Cause Fix
A /login de um desenvolvedor mostra o seletor de conta padrão em vez da tela Cloud gateway forceLoginMethod ou forceLoginGatewayUrl não está definido nas configurações gerenciadas nessa máquina Implante o arquivo de configurações gerenciadas no dispositivo; /login lê a URL do gateway de lá
As solicitações de um desenvolvedor falham com Not signed in to the Cloud gateway — run /login. As configurações gerenciadas da máquina definem forceLoginMethod: "gateway" ou forceLoginGatewayUrl, e a sessão não tem login no gateway. Um login claude.ai restante não satisfaz o requisito. Peça ao desenvolvedor para executar /login e completar o login no gateway. Veja também Administrator policy requires a Cloud gateway sign-in.
Claude Desktop relata que sua configuração de bootstrap não pôde ser buscada /user/bootstrap retornou 404: a política que corresponde ao usuário não carrega uma chave desktop, ou nenhuma política correspondeu. O log de auditoria do gateway registra cada rejeição como desktop_bootstrap.denied com o motivo. Adicione um bloco desktop à política que corresponde ao usuário, ou à camada base match: {}; um desktop: {} vazio é suficiente. Veja Claude Desktop overlay.
A inicialização mostra Gateway login is configured in managed settings, but this Claude Code build does not include Cloud gateway support. A compilação Claude Code instalada é anterior ao suporte de gateway Peça ao desenvolvedor para atualizar Claude Code para uma versão que inclua suporte de Cloud gateway
A inicialização sai com Administrator policy requires a Cloud gateway sign-in on this machine O ambiente do desenvolvedor define ANTHROPIC_API_KEY ou ANTHROPIC_AUTH_TOKEN, suas configurações configuram um apiKeyHelper, ou uma chave de API de um login anterior do Claude Console ainda está salva Peça ao desenvolvedor para limpar cada um que se aplica: desdefina a variável, remova a entrada apiKeyHelper, ou execute claude auth logout para remover a chave salva. Depois peça para iniciar claude e fazer login com /login. Veja também Administrator policy requires a Cloud gateway sign-in.
A inicialização ou /login relata Claude Code may not be enabled for your organization após um 403 no carregamento de configurações gerenciadas O gateway, ou algo na frente dele, respondeu à solicitação /managed/settings com 403. A rota de configurações do próprio gateway nunca responde com 403. O status vem das verificações de IP access_control ou de um proxy ou WAF na frente do gateway. O log de auditoria registra uma negação de verificação de IP como access.denied com o motivo. O desenvolvedor permanece conectado. Verifique o log de auditoria para access.denied no momento da falha e corrija as listas access_control ou o front end, depois peça ao desenvolvedor para iniciar claude novamente
CLI /login: The gateway is limiting sign-in attempts right now, ou Request failed with status code 429 em versões mais antigas. A página /device pode mostrar Too many attempts para desenvolvedores que não tentaram antes O limite de taxa de login por IP foi atingido. Ou listen.trusted_proxies não cobre o balanceador de carga, então cada desenvolvedor compartilha seu endereço, ou muitos desenvolvedores compartilham um endereço de saída NAT ou VPN. Eventos de auditoria com result: rate_limited mostram o mesmo um ou poucos valores client_ip. Defina listen.trusted_proxies para os intervalos de origem do balanceador de carga primeiro, depois aumente rate_limits se desenvolvedores ainda compartilharem endereços. Veja Large rollouts.
CLI /login: Gateway hosts must be on your organization's private network; <host> resolves to the public (or unrecognized) address <ip> O nome do host do gateway resolve para pelo menos um endereço IP público. Claude Code verifica cada endereço resolvido e requer que todos sejam privados. Uma causa comum é um nome dual-stack onde uma família resolve para um endereço público, incluindo balanceadores de carga dual-stack internos da AWS, que retornam endereços AAAA de intervalo público. Faça com que o nome do gateway resolva apenas para endereços privados nas máquinas dos desenvolvedores. Para um nome dual-stack, remova o registro de intervalo público ou sirva um nome DNS separado apenas para interno. Veja o pré-requisito de rede privada. Se o endereço é espaço público que sua organização possui e usa internamente, declare esse bloco em vez disso.
CLI /login: Gateway login would go through proxy <proxy>, which is not on a private network Um HTTPS_PROXY ou HTTP_PROXY se aplica ao host do gateway e o nome do host do proxy resolve para um endereço público. Um proxy cujo host resolve apenas para endereços privados é permitido e não dispara esse erro Adicione o host do gateway a NO_PROXY na máquina do desenvolvedor para que a conexão seja direta, ou use um proxy cujo nome do host resolve para endereços privados. A mensagem nomeia a entrada exata NO_PROXY a adicionar
CLI /login: Claude Code only signs in to <host> from inside its declared network <block> (managed settings), and this machine is connecting from <ip>, outside it O gateway está em um bloco declarado em gatewayInternalNetworks, e a máquina do desenvolvedor o alcançou de um endereço fora desse bloco: um pool de endereços VPN, um segmento NAT de container ou WSL2, ou uma rede que não é sua Peça ao desenvolvedor para executar /login do SO host em sua rede. Se o endereço mostrado também é espaço público da sua organização, substitua a entrada do gateway por um bloco que cubra ambos, até /8; uma segunda entrada sobreposta é recusada
CLI /login: Every address for gateway host <host> must be inside its declared network <block>, and it also resolves to <ip> O nome do gateway resolve para um endereço fora do bloco declarado em gatewayInternalNetworks: um segundo site, ou um registro IPv6 em um nome dual-stack. Sob um bloco declarado, cada registro deve estar dentro desse único bloco IPv4, endereços privados e IPv6 inclusos Publique apenas registros dentro do bloco para o nome do gateway nas máquinas dos desenvolvedores, ou sirva um nome separado apenas para interno
CLI /login: <host> is on the declared network <block>, which Claude Code checks over a direct connection, not through an HTTP proxy Um HTTPS_PROXY ou HTTP_PROXY se aplica a um gateway em um bloco declarado Na máquina do desenvolvedor, adicione a entrada NO_PROXY que a mensagem nomeia
CLI /login: uma mensagem começando gatewayInternalNetworks in managed settings O valor quebra uma das regras de validação, e a mensagem nomeia qual. Até você corrigir, Claude Code recusa cada novo /login de gateway na máquina, gateways em endereços privados inclusos; logins existentes continuam funcionando Na fonte de configurações gerenciadas que você implanta, corrija a entrada que a mensagem nomeia, depois execute /login novamente
CLI /login: Could not resolve the configured HTTP proxy O nome do host em HTTPS_PROXY ou HTTP_PROXY não resolve da máquina do desenvolvedor, tipicamente porque não está conectado à rede corporativa Peça ao desenvolvedor para conectar à sua rede ou VPN e tentar novamente, ou corrija a URL do proxy
CLI /login: Could not resolve gateway host <host> A máquina não consegue resolver o nome DNS interno do gateway, tipicamente porque não está na rede corporativa Peça ao desenvolvedor para conectar à sua rede ou VPN, depois execute /login novamente
Boot exits with a config validation error naming store.postgres_url Nenhum Postgres configurado; o gateway requer Postgres Defina store.postgres_url. Para desenvolvimento local, use um container descartável: docker run --rm -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres.
Boot exits: requires the native binary Executando sob Node em vez do binário nativo Instale Claude Code com um dos métodos de instalação autônomos
Boot exits with an OIDC discovery error after config.load oidc.issuer inacessível, ou cadeia TLS não confiável Verifique se o emissor é acessível do pod e serve /.well-known/openid-configuration. Defina ca_cert_pem para PKI privada. Se o pod alcança o IdP apenas através de um proxy direto, defina oidc.use_proxy: true; em versões anteriores a v2.1.227, dê ao pod uma rota direta para cada um dos endpoints do IdP em vez disso. Se o pod também não conseguir resolver o nome do host do IdP, ou o proxy recusar CONNECT para um endereço IP, veja Proxy-only egress, que requer v2.1.277 ou posterior.
Boot exits with a Postgres permission error O papel do banco de dados carece de direitos DDL em seu schema Conceda ao papel CREATE no schema do gateway para que possa criar e alterar suas tabelas na inicialização
Log: could not connect to Postgres at boot, attempt 1 of 3 O banco de dados não estava acessível quando o gateway iniciou, por exemplo em uma instância fria cuja rede ainda está se iniciando Se o gateway então terminar de inicializar, nenhuma ação é necessária. Quando o banco de dados não está acessível, o gateway tenta a conexão três vezes, dois segundos de intervalo, antes de sair. Se sair com could not connect to Postgres, verifique store.postgres_url e o caminho de rede para o banco de dados. Se as tentativas expirarem em vez de serem recusadas, aumente store.connect_timeout_seconds para dar a cada uma mais tempo.
/oauth/callback shows "Sign-in could not be completed" Domínio de email rejeitado, validação de id_token falhou, ou email_verified é explicitamente false, que o gateway sempre rejeita sem override Verifique allowed_email_domains e que o IdP retorna uma reivindicação email verificada. Para email_verified: false, corrija a verificação do lado do IdP. Se seu IdP emite email sob um nome de reivindicação diferente, defina oidc.email_claim.
Log: token exchange failed request_id=<id>: id_token missing email claim O IdP não está incluindo email no id_token por padrão. Essa rejeição dispara apenas quando allowed_email_domains está definido; sem ele, um email ausente cria uma sessão sem email Configure o IdP para emitir email no id_token. Okta: adicione email às reivindicações de token de ID de um servidor de autorização personalizado. Entra: adicione email como uma reivindicação opcional no registro do aplicativo. PingFederate: ative uma Política OpenID Connect que emita email. Se o IdP serve email do endpoint userinfo mas não incluirá no id_token, como o servidor de autorização da organização Okta, defina oidc.userinfo_fallback: true.
Log: refresh failed request_id=<id>: invalid_token (…) (at userinfo_no_id_token, …), e desenvolvedores veem Cloud gateway session expired a cada session.ttl_hours O IdP aceitou o token de atualização mas não retornou id_token com ele, então o gateway perguntou ao endpoint userinfo do IdP pelas reivindicações do usuário. O IdP rejeitou o token de acesso atualizado lá. O gateway responde temporarily_unavailable, então Claude Code mantém o token de atualização mas não consegue renovar a sessão. Versões do gateway anteriores a v2.1.260 registram a mesma linha sem o detalhe (at …). Defina oidc.scope_on_refresh: true, disponível no gateway v2.1.260 ou posterior, para que a solicitação de atualização peça por openid novamente. Alguns IdPs, como Okta, retornam um id_token na atualização apenas quando solicitado. No PingFederate, ative Return ID Token On Refresh Grant sob Applications > OAuth > OpenID Connect Policy Management em vez disso. A chave não muda o comportamento do PingFederate. Para outros IdPs que ainda o omitem, verifique se o endpoint userinfo aceita tokens de acesso emitidos por uma atualização. Como uma solução temporária, aumente session.ttl_hours. Veja Identity provider setup para o tradeoff de desprovisionamento.
Every Amazon Bedrock request returns 502; log shows Could not load credentials from any providers No EC2, o hop limit padrão do IMDSv2 de 1 bloqueia a solicitação de metadados de instância de dentro do container. Boot e /readyz passam mesmo assim porque o AWS SDK resolve credenciais de instância na primeira solicitação, não na construção do cliente Aumente o hop limit com aws ec2 modify-instance-metadata-options --instance-id <id> --http-put-response-hop-limit 2, ou defina-o no modelo de lançamento. A mudança se aplica a cada container na instância. Prefira funções de tarefa ECS onde disponível, que leem credenciais do endpoint de credenciais do container ECS e evitam a mudança inteiramente, ou aplique a mudança em uma instância de gateway dedicada para limitar a exposição.
At peak load, responses are slow to start or appear to hang, or fail with a 502 all upstreams failed while the upstream is healthy Uma réplica tem mais solicitações abertas do que envia upstream de uma vez, então as solicitações extras esperam dentro do gateway. Em um upstream provider: anthropic, uma solicitação que espera mais tempo que timeouts.upstream_ttfb_ms desiste desse upstream, que produz o 502 quando nenhum upstream posterior a serve. O log mostra um aviso que contém client requests are open. Adicione réplicas, ou aumente o limite em cada réplica. Veja Concurrent upstream requests.
IdP error: unknown or unsupported scope O IdP rejeita escopos que não reconhece Defina oidc.scopes para exatamente a lista que seu IdP aceita; deve incluir openid. O padrão é openid profile email offline_access.
Sessions don't silently renew after setting oidc.scopes offline_access foi removido da substituição Adicione offline_access de volta se seu IdP o suporta. Sem um token de atualização, desenvolvedores executam novamente o login do navegador a cada session.ttl_hours.
Browser shows "This request came from another site and was blocked" POST de formulário entre sites, bloqueado como proteção CSRF. Esperado para páginas incorporadas ou proxied Abra o link de verificação diretamente
Chrome blocks the Approve button with "Refused to send form data … violates … Content Security Policy directive: form-action", but the same page works in Safari or Firefox Chrome impõe form-action contra toda a cadeia de redirecionamento. Seu IdP redireciona para um segundo host que não está na lista de permissões. Adicione cada origem adicional na cadeia de redirecionamento a oidc.form_action_origins. Abra Chrome DevTools → Console na página Approve para ver qual origem foi bloqueada.
Sign-in completes at the IdP but the callback fails, with a CSP error in Chrome or "this sign-in link has expired" in Safari O IdP retornou o código via response_mode=form_post, que o envia automaticamente entre origens via POST para /oauth/callback. Chrome bloqueia isso sob uma CSP rigorosa; Safari permite o envio mas o callback lê apenas a string de consulta. Certifique-se de que seu IdP honra response_mode=query, que o gateway solicita explicitamente para que o callback seja um redirecionamento simples
Login works locally but fails behind an ALB public_url ainda nomeia a origem http:// local ou interna, então o IdP obtém o redirect_uri errado Defina listen.public_url para a origem https:// externa e registre <public_url>/oauth/callback com o IdP
Developer sees the trust prompt repeatedly TLS cert is rotating per replica or per request Use a stable cert at the ingress, or terminate TLS once and run replicas over plain HTTP internally
CLI /login: "Could not verify the gateway's TLS certificate" or SELF_SIGNED_CERT_IN_CHAIN A cadeia TLS do gateway é assinada por uma CA privada não no armazenamento de confiança do host CLI Claude Code lê o armazenamento de confiança do SO por padrão no binário nativo e no Node 22.15 ou posterior; CLAUDE_CODE_CERT_STORE controla esse comportamento. Se a CA está instalada no armazenamento de confiança do SO, certifique-se de que os desenvolvedores estão em um runtime atual. Caso contrário, defina NODE_EXTRA_CA_CERTS para o PEM do certificado CA antes de iniciar. O prompt de impressão digital da primeira conexão ainda se aplica.
CLI /login completes the browser sign-in, then the session ends with Cloud gateway sign-in was not completed and a TLS certificate mismatch Na primeira solicitação após o login, o gateway apresentou um certificado que não corresponde à impressão digital que Claude Code fixou, então Claude Code não manteve nenhuma credencial de gateway. As causas usuais são réplicas atrás de um endereço que servem certificados diferentes, ou algo no caminho de rede que intercepta TLS. Sirva um certificado para o nome do host, por exemplo terminando TLS uma vez no ingress, depois peça ao desenvolvedor para executar /login novamente. Se esse certificado diferir do fixado, Claude Code mostra o prompt de confiança novamente com um aviso de que o certificado mudou.
CLI /login stops with The gateway's TLS certificate changed during sign-in: it no longer matches the one you trusted Uma solicitação de login alcançou um servidor cujo certificado não corresponde ao que o desenvolvedor aceitou quando /login começou: réplicas atrás de um endereço servindo certificados diferentes, interceptação TLS no caminho, ou uma rotação de certificado enquanto o login estava em andamento. Sirva um certificado para o nome do host, depois peça ao desenvolvedor para iniciar o login novamente e revisar o novo certificado no prompt de confiança.

A mensagem Cloud gateway sign-in was not completed nomeia o nome do host do gateway. Quando Claude Code tem tanto a impressão digital fixada quanto a apresentada, a mensagem também mostra os primeiros 16 caracteres de cada uma.

Se Claude Code relata couldn't load your organization's managed settings após um login no gateway, Claude Code nomeia o motivo, reinicia no lugar, e retoma a conversa. Se Claude Code não conseguir reiniciar, por exemplo em uma sessão em segundo plano, Claude Code encerra a sessão e mantém o login.