Como escrever o prompt com chave de API sem colar a credencial no chat

prompt com chave de API sem expor credencial no código
Resposta rápida

Um prompt com chave de API não precisa da chave dentro dele. Você descreve a integração pelo nome da variável (ANTHROPIC_API_KEY, GITHUB_TOKEN), usa um valor fictício, diz qual serviço e qual endpoint, e deixa o segredo fora do texto. Do lado da configuração: permissions.deny no settings.json bloqueia descoberta, busca, leitura, edição e escrita nos arquivos de segredo, o .mcp.json aceita ${VAR}, e sandbox.credentials protege o que roda nos comandos. O resto continua com você: cofre de segredos, rotação, revogação e chaves separadas por ambiente

Fala aí, beleza? Colar a chave no chat pra "adiantar" a integração é o reflexo mais comum do vibe coding, e também o mais caro

Parece inofensivo: você joga o token no enunciado, o agente entende o contexto na hora, a integração sai em dois minutos

Só que o prompt não morre no prompt

Ele vira transcript de sessão, o transcript vira histórico, e a credencial passa a existir em mais lugares do que você consegue apagar depois. A documentação de uso de dados do Claude Code descreve prazos de retenção que variam por plano: Free, Pro e Max com uso permitido para melhoria do modelo ficam em 5 anos, sem permitir caem para 30 dias, e Team, Enterprise e API usam 30 dias como padrão

A boa notícia é que dá pra descrever QUALQUER integração sem entregar o segredo, usando nome de variável e valor fictício, e empurrando a credencial de verdade pra fora do texto

Bora montar um prompt com chave de API que não tem chave de API nenhuma dentro? 😀

O que preparar antes de escrever o prompt

Checklist curto, tudo verificável em menos de cinco minutos:

  • A chave já existe fora da conversa, no ambiente ou no seu gerenciador de segredos. As boas práticas da Anthropic pedem cofre de segredos, chaves diferentes para desenvolvimento, teste e produção, e rotação em cadência consistente (o exemplo citado é a cada 90 dias)
  • Os arquivos .env estão no ignore do controle de versão, também recomendação explícita das boas práticas de chave de API
  • Você sabe onde as credenciais do próprio Claude Code moram: no Keychain do macOS quando disponível, e no Linux e no Windows em ~/.claude/.credentials.json, ou sob $CLAUDE_CONFIG_DIR se essa variável estiver definida, protegido por permissões de arquivo
  • Os dois comandos que você vai usar nos passos: /permissions, que abre o diálogo com todas as regras e o settings.json de origem de cada uma, e /sandbox, que abre a interface de configuração do sandbox
Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 118 aulas
  • 4 projetos
  • 9h 33min

Repara que nada disso é sobre o texto do prompt ainda

É configuração

E é justamente por isso que funciona: o enunciado fica limpo porque o segredo já está resolvido em outro lugar

Passo a passo: descrever a integração sem entregar a credencial

  1. Escreva o enunciado pelo nome da variável, com valor fictício

Diga qual serviço, qual endpoint, qual header, e referencie a credencial pelo NOME. Nada de colar o valor real

Integre o serviço X neste projeto.
A autenticação vai no header Authorization, no formato Bearer <token>.
O token vem da variável de ambiente SERVICE_X_API_KEY (nunca leia o valor, apenas referencie o nome).
Para os exemplos de código, use o placeholder sk-exemplo-nao-real.
Endpoint: POST https://api.exemplo.com/v1/mensagens

A régua de um bom enunciado aqui é a mesma de escrever o pedido sem código: contexto, objetivo e formato, sem enfeite

O erro comum deste passo: colar a chave "só uma vez, pra ele testar". Uma vez basta pra ela entrar no histórico

  1. Bloqueie a leitura dos arquivos de segredo no settings.json

A lista permissions.deny é o mecanismo recomendado pela documentação para arquivos que guardam chaves de API, segredos ou valores de ambiente. Esse é o exemplo oficial:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Quando um caminho cai numa regra deny, o Claude Code exclui o arquivo da descoberta e da busca, nega a leitura e bloqueia Edit e Write naquele caminho. Ou seja: cobre os cinco verbos, não só o "ler"

O erro comum deste passo: inventar o esquema. Escrever permissions.read.deny no lugar de permissions.deny com "Read(./.env)" é chave errada em JSON, e chave errada em JSON não protege nada

  1. Confira o que realmente está valendo com /permissions
/permissions

O diálogo lista todas as regras e mostra de qual settings.json cada uma veio, o que resolve na hora aquela dúvida de "será que é o do projeto ou o meu global?"

Duas notas que valem ouro aqui: a ordem de avaliação é deny, depois ask, depois allow, e as regras deny e ask passam a valer imediatamente, sem depender de você confiar na pasta. E quando você adiciona ou remove uma regra, a mudança vale a partir da próxima chamada de ferramenta do mesmo turno

O erro comum deste passo: escrever a regra e não conferir a origem. Um allow largo num arquivo e um deny estreito em outro geram uma confusão que o diálogo mata em dois segundos

  1. No .mcp.json, referencie a credencial pelo nome

O arquivo aceita expansão de variável de ambiente nas sintaxes ${VAR} e ${VAR:-default}, válidas em command, args, env, url e headers

{
  "mcpServers": {
    "meu-servico": {
      "url": "https://api.exemplo.com/mcp",
      "headers": {
        "Authorization": "Bearer ${API_KEY}"
      }
    }
  }
}

O arquivo pode ir pro repositório sem drama, porque o que está ali é o NOME, não o valor

O erro comum deste passo: esquecer de definir a variável. Se ela não existe e não tem valor padrão, a configuração ainda carrega e o texto ${VAR} fica literal. O sintoma aparece no claude mcp list, que mostra um aviso de variável ausente pra aquele servidor

  1. Prefere o CLI? Passe a variável no registro do servidor
claude mcp add <name> -- <command> [args...]

O exemplo da própria documentação:

claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable -- npx -y airtable-mcp-server

O erro comum deste passo: digitar a chave crua no terminal e deixar ela no histórico do shell. Se for usar essa forma, puxe o valor de uma variável já carregada no ambiente em vez de teclar o segredo

  1. Proteja o que roda no sandbox com /sandbox e sandbox.credentials

O sandbox do Bash já isola sistema de arquivos e rede: escrita presa ao diretório de trabalho, bloqueio de modificação fora dele, e internet só via socket ligado a um proxy externo ao sandbox, sem nenhum domínio pré-liberado por padrão

Pra abrir a interface de configuração do sandbox dentro do Claude Code, roda:

/sandbox

E o bloco sandbox.credentials é onde você declara arquivos e variáveis de ambiente a proteger dos comandos rodados no sandbox, com dois modos: deny esconde a credencial lá dentro, e mask mostra um placeholder ao comando enquanto o proxy do sandbox substitui pelo valor real na requisição de saída

{
  "sandbox": {
    "credentials": {
      "files": [{ "path": "~/.aws/credentials", "mode": "deny" }],
      "envVars": [{ "name": "GITHUB_TOKEN", "mode": "deny" }]
    }
  }
}

O erro comum deste passo: achar que credencial é protegida por padrão. NÃO é. O isolamento do sandbox segura a MODIFICAÇÃO fora do diretório de trabalho, e não a leitura: por padrão os comandos Bash rodados no sandbox herdam o ambiente do processo pai, incluindo credenciais, e conseguem ler arquivos como ~/.aws/credentials e ~/.ssh/. Não existe deny list de credenciais embutida: só vale o que você listar

  1. Tire as credenciais dos subprocessos de uma vez

Existe uma variável de ambiente que remove credenciais da Anthropic e de provedores de nuvem de todos os subprocessos:

CLAUDE_CODE_SUBPROCESS_ENV_SCRUB

É o tipo de guardrail (limite) que você liga uma vez e esquece que existe, do jeito bom

Como fica o prompt em cada tipo de integração

A lógica é sempre a mesma: o prompt descreve o CONTRATO, a configuração guarda o SEGREDO

API de terceiro com token no header

No prompt:

Crie um cliente HTTP para a API de pagamentos.
O header Authorization usa Bearer com o valor de PAYMENTS_API_KEY.
Nos testes e na documentação, use o placeholder pk-teste-0000.

Fora dele: a variável real vive no ambiente ou no cofre, e o .env está coberto por Read(./.env) na lista deny

Servidor MCP que precisa de chave

No prompt:

Configure o servidor MCP do serviço Y neste projeto.
A chave deve ser referenciada como ${SERVICE_Y_TOKEN} no .mcp.json, nunca em valor literal.

Fora dele: o .mcp.json com ${SERVICE_Y_TOKEN} no headers ou no env, e a variável definida no ambiente. Se o claude mcp list reclamar de variável ausente, é ela que faltou

Script que lê credencial de nuvem

No prompt:

Escreva um script que use o perfil de credencial padrão da nuvem.
Não leia, não imprima e não copie o conteúdo do arquivo de credencial.

Fora dele: sandbox.credentials com ~/.aws/credentials em mode: "deny", porque sem isso o subprocesso herda tudo do pai

Quando o agente não pode ver a chave de jeito nenhum

Aí você usa o padrão de proxy, descrito na documentação de segurança como alternativa a entregar a chave ao agente: um proxy fora do ambiente do agente injeta a credencial nas requisições, e o agente faz as chamadas sem nunca ver o segredo

No prompt você fala só do endpoint e do formato da resposta

O mesmo racional aparece no mode: "mask" do sandbox, onde o comando enxerga um placeholder e o proxy troca pelo valor real na saída

Resumo em tabela:

Situação O que entra no prompt O que fica configurado fora
API de terceiro no header nome da variável e valor fictício variável no ambiente, .env na lista deny
Servidor MCP referência ${VAR} .mcp.json e a variável definida
Script com credencial de nuvem caminho lógico, sem conteúdo sandbox.credentials em mode: "deny"
Agente não pode ver a chave endpoint e formato da chamada proxy externo injeta a credencial

Quando dá errado: sintomas comuns e o que checar

Erro de autenticação com uma chave que você jura que trocou

Sintoma: falha de autenticação apontando pra uma chave desatualizada, que não é a que está no seu cofre

Causa: ferramentas como direnv, plugins de shell dotenv e o terminal da IDE podem carregar uma chave antiga vinda de um .env do projeto sem você ter definido nada. É causa comum e passa despercebida, porque o ambiente foi montado antes de você abrir o editor

Solução: rastrear quem está exportando a variável no shell em que o Claude Code roda, e limpar a fonte antiga

Como prevenir: usar a configuração apiKeyHelper, que aponta pra um script de shell devolvendo a chave em vez de deixar ela fixa. Ele é chamado após 5 minutos ou em resposta a um HTTP 401, e o intervalo de atualização é ajustável por CLAUDE_CODE_API_KEY_HELPER_TTL_MS

Cobrança de API inesperada mesmo tendo assinatura

Sintoma: você paga assinatura, mas o consumo aparece como uso de API

Causa: a variável ANTHROPIC_API_KEY tem prioridade sobre a assinatura autenticada no Claude Code

Solução: pra usar a assinatura, manter ANTHROPIC_API_KEY sem valor definido

Como prevenir: mesma checagem do caso anterior, já que quase sempre é um .env de projeto ou um plugin de shell definindo a variável nas suas costas

Bloqueio configurado e o arquivo lido mesmo assim

Sintoma: existe regra de bloqueio, e o segredo aparece na conversa do mesmo jeito

Causa: em 28/01/2026 o The Register publicou uma reportagem apontando que o Claude Code ignorava regras de ignore feitas pra bloquear segredos. O caso do issue 24846 no repositório anthropics/claude-code foi fechado como duplicata, e o relato aponta que o usuário havia escrito o esquema errado (permissions.read.deny) no lugar da forma documentada (permissions.deny com "Read(./.env)")

O changelog também registra correção no comportamento de precedência no macOS: regras de read deny com curinga (por exemplo **/.env) passaram a ter precedência dentro de regiões de leitura liberadas, a cobrir o conteúdo dos diretórios que casam com o padrão e a não poderem ser contornadas renomeando o arquivo bloqueado

Solução: conferir o esquema com /permissions e corrigir pra forma documentada

Como prevenir: conhecer o limite do deny. Regras deny de Read e Edit valem pras ferramentas de arquivo nativas e pros comandos de arquivo que o Claude Code reconhece no Bash, cobrindo cat, head, tail e sed, mas NÃO cobrem subprocesso arbitrário. Por isso a documentação de segurança pede menor privilégio: não dar ao agente acesso a segredos de que ele não precisa, rodar ferramentas em ambiente isolado e escopar permissões o mais estreito possível

E do lado do repositório: o push protection do GitHub bloqueia o push antes de o segredo chegar ao repositório, inclusive em repositórios públicos gratuitos, e segredos de parceiros encontrados em repositório público são encaminhados ao provedor, que pode revogar a credencial. Somando a isso, as boas práticas recomendam varrer o repo com ferramentas SAST como Gitleaks

O que continua na sua mão

A divisão é bem clara, e é bom encarar ela sem ilusão

A ferramenta cobre: bloqueio de arquivo de segredo com permissions.deny, referência por nome com ${VAR} no .mcp.json, isolamento de sistema de arquivos e rede no sandbox, proteção declarada em sandbox.credentials e limpeza de credenciais nos subprocessos com CLAUDE_CODE_SUBPROCESS_ENV_SCRUB

Você cobre: cofre de segredos, rotação em cadência consistente (o exemplo citado é a cada 90 dias), revogação de qualquer chave suspeita de vazamento, chaves separadas para desenvolvimento, teste e produção, .env no ignore do controle de versão e menor privilégio em cada permissão que você concede

E tem um detalhe que quase ninguém lembra: quando você aceita compartilhar o transcript de uma sessão, sobem o transcript da conversa, os transcripts de subagentes e o log bruto da sessão. Padrões conhecidos de chave de API e de token são redigidos antes do upload, mas código-fonte e conteúdo de arquivos sobem como estão, e transcripts compartilhados ficam retidos por até 6 meses. Nada é enviado sem você escolher Sim no diálogo, e a preferência de uso de dados é alterável em claude.ai/settings/data-privacy-controls

O próximo passo é ridiculamente simples: abre o settings.json agora e escreve a primeira regra deny, com Read(./.env)

Depois roda /permissions e confirma que ela está lá

Dois minutos de configuração que te poupam aquele domingo de revogar chave às pressas… 😀

até o próximo post!

Perguntas frequentes

Colar a chave de API direto no chat do Claude Code é seguro?

Não é a prática recomendada, porque o prompt vira transcript de sessão e passa a existir em mais lugares do que dá pra apagar depois. Os prazos de retenção variam por plano: Free, Pro e Max com uso permitido para melhoria do modelo ficam em 5 anos, sem permitir caem para 30 dias, e Team, Enterprise e API usam 30 dias como padrão.

Por que o Claude Code pode acabar lendo um arquivo .env mesmo com regra de bloqueio configurada?

Geralmente é erro de esquema no settings.json. The Register publicou em 28/01/2026 um caso em que o Claude Code parecia ignorar regras de bloqueio, e o issue relacionado no repositório anthropics/claude-code foi fechado como duplicata porque o usuário tinha escrito permissions.read.deny em vez da forma documentada, permissions.deny com Read(./.env). No macOS, o changelog também registra que regras de read deny com curinga, como **/.env, passaram a valer dentro de regiões de leitura liberadas e não podem ser contornadas renomeando o arquivo.

Qual a diferença entre os modos deny e mask do sandbox.credentials?

Os dois protegem arquivos e variáveis de ambiente dos comandos rodados no sandbox, mas de jeitos diferentes. O modo deny esconde a credencial completamente de dentro do sandbox, e o modo mask mostra um placeholder ao comando enquanto o proxy do sandbox substitui pelo valor real só na requisição de saída.

A variável ANTHROPIC_API_KEY pode gerar cobrança inesperada mesmo com assinatura paga ativa?

Pode, porque essa variável tem prioridade sobre a assinatura autenticada no Claude Code. Pra usar a assinatura e evitar cobrança de API inesperada, o recomendado é manter ANTHROPIC_API_KEY sem valor definido.

O que é o apiKeyHelper e como ele evita deixar a chave fixa no settings.json?

É uma configuração que aponta pra um script de shell que devolve a chave em vez de deixá-la fixa no arquivo. Ele é chamado depois de 5 minutos ou em resposta a um erro HTTP 401, e o intervalo de atualização dá pra ajustar pela variável CLAUDE_CODE_API_KEY_HELPER_TTL_MS.

Se eu compartilhar o transcript de uma sessão, a chave de API que digitei some antes do upload?

Só se ela seguir um padrão conhecido de chave ou token, porque esses padrões são redigidos antes do upload. Código-fonte e conteúdo de arquivo sobem como estão, e nada é enviado sem você escolher Sim no diálogo; transcripts compartilhados ficam retidos por até 6 meses.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares