# Como a injeção de credenciais deve seguir a validação da solicitação

As credenciais devem entrar no fim do pipeline de uma solicitação de saída, depois que o cliente decidir o que aceita enviar. Se um componente adiciona uma chave de API ou uma credencial SSH antes de validar o destino real e o formato da solicitação, a decisão de segurança já foi tomada. Tudo o que vem depois é apenas correção de danos.

Essa ordem é ainda mais importante com agentes autônomos de programação. Um agente pode gerar uma solicitação plausível, seguir um link vindo de uma resposta de API, reutilizar um exemplo de um repositório ou aceitar um redirecionamento sem entender a consequência. Nada disso exige que o agente seja malicioso. Basta que o caminho da solicitação permita que uma entrada não confiável influencie para onde uma solicitação autenticada será enviada.

A regra útil é simples: analise a ação proposta, valide a ação completa, congele a ação, estabeleça a conexão correspondente e injete a credencial no último momento responsável. Se a solicitação mudar, descarte a decisão de autorização e recomece.

## As credenciais transformam a validação da solicitação em uma fronteira de segurança

Um injetor de credenciais não é apenas um wrapper conveniente em torno de um cliente HTTP. Ele decide qual parte remota receberá autoridade para agir em seu nome. Por isso, a fronteira de validação precisa incluir mais que um campo de hostname copiado de um objeto de solicitação.

Para uma ação HTTP, valide pelo menos o esquema, o hostname, a porta, o método, o caminho, as regras de consulta, os cabeçalhos relevantes e o corpo. Para SSH, valide o host, a porta, a decisão de confiança na chave do host, a conta remota, o comando, o encaminhamento do ambiente e qualquer destino de transferência de arquivos. Os detalhes mudam, mas a ordem não.

As equipes costumam misturar duas perguntas diferentes:

- Esta solicitação pode chegar ao serviço pretendido?
- Esta credencial deve autorizar exatamente esta solicitação?

Uma consulta DNS bem-sucedida e um certificado TLS válido respondem apenas a parte da primeira pergunta. Eles não respondem à segunda. Uma solicitação para `https://api.example.com:8443` não é automaticamente equivalente a uma enviada para a porta HTTPS padrão. Um `POST /v1/refunds` com um bearer token não pode ser trocado por um `GET /v1/me`, mesmo quando os dois chegam ao mesmo host.

O erro que mais vejo é uma regra ampla como «esta chave é para api.example.com», seguida por um cliente que aceita uma URL arbitrária, adiciona o cabeçalho e pede à biblioteca que a envie. Essa regra deixa autoridade demais nas mãos da análise de URLs, do tratamento de redirecionamentos, do comportamento do proxy e dos cabeçalhos controlados pelo agente. Ela também torna as revisões enganosas. Uma pessoa pode aprovar uma solicitação descrita de uma forma, enquanto a solicitação transmitida pela rede diz outra coisa.

O validador da solicitação precisa ser a autoridade dos dois lados dessa diferença. Ele deve tomar uma decisão explícita sobre uma solicitação estruturada, não procurar uma string por um domínio conhecido e torcer para que o restante se comporte como esperado.

## Analise o destino como uma origem canônica

Uma verificação de destino deve comparar componentes estruturados da URL, não prefixos de strings. A identidade relevante de uma origem HTTP é formada pelo esquema, host e porta. A RFC 3986 define a parte de autoridade como informações de usuário opcionais, um host e uma porta opcional. A RFC 9110 usa o conceito de origem para solicitações HTTP. São definições pequenas, mas com consequências grandes.

Comece analisando a URL com um analisador de URLs real. Rejeite valores de que a integração não precisa. Não corrija uma entrada malformada para torná-la mais permissiva. Um validador que tenta ajudar costuma criar um segundo analisador, cujo comportamento acaba divergindo do cliente HTTP.

Para uma credencial de API comum, uma regra de destino conservadora pode ser:

```text
accepted scheme: https
accepted host: api.billing.example
accepted port: 443 only
accepted paths: /v1/invoices/* and /v1/customers/*
userinfo: forbidden
fragments: ignored before sending, rejected in proposed actions
IP literals: forbidden unless explicitly configured
```

A canonicalização exige moderação. Converta um hostname DNS para minúsculas antes da comparação. Trate uma porta HTTPS omitida e a porta 443 como a mesma porta efetiva. Garanta que o analisador tenha separado as informações de usuário do host. Normalize segmentos com ponto apenas se você validar o caminho normalizado depois disso, e não decodifique caracteres reservados antes de saber como o cliente os interpretará.

Várias URLs mostram por que as verificações por prefixo falham:

```text
https://api.billing.example.attacker.invalid/v1/invoices
https://api.billing.example@attacker.invalid/v1/invoices
https://api.billing.example:8443/v1/invoices
https://api.billing.example/v1/../admin/users
```

Apenas os primeiros caracteres parecem conhecidos. A autoridade ou o caminho final podem ser diferentes. Vale testar especialmente a segunda URL, porque o texto antes de `@` é informação de usuário, não o host remoto. Um navegador pode apresentá-la de um modo que leve um revisor apressado a olhar para a parte errada.

Nomes de domínio internacionalizados exigem o mesmo cuidado. Escolha se a integração aceita um hostname ASCII fixo ou um conjunto definido de nomes internacionalizados. Converta e compare usando uma única regra documentada. Não compare uma forma de exibição em um lugar e uma forma transmitida pela rede em outro.

O DNS não é seu banco de dados de autorização. Você pode usá-lo para conectar depois de aceitar uma origem, mas não aceite um destino apenas porque ele resolve para um endereço esperado. Hospedagem compartilhada, balanceadores de carga, endereços de serviço que mudam e rebinding de DNS tornam frágeis as suposições baseadas em IP. Se precisar de proteções para redes privadas, aplique-as como uma regra adicional de conexão, não como substituta de uma lista de permissões de origens.

## Valide juntos o destino da conexão e a autoridade HTTP

A URL, o nome do servidor TLS e a autoridade HTTP precisam descrever o mesmo destino aprovado. Se não descreverem, o injetor de credenciais deve parar.

O HTTP tem mais de um lugar onde a autoridade pode aparecer. O HTTP/1.1 usa o cabeçalho `Host`. O HTTP/2 e o HTTP/3 usam o pseudo-cabeçalho `:authority`. Um proxy HTTP pode receber um destino de solicitação no formato absoluto contendo outra autoridade. A RFC 9112 exige que um cliente envie um cabeçalho Host no HTTP/1.1 e trata campos Host ausentes, repetidos ou inválidos como malformados. Essa regra existe porque o roteamento por autoridade não é um detalhe opcional.

Em um cliente que entende de credenciais, a configuração mais segura é manter a construção da autoridade fora do controle do agente. O transporte confiável cria `Host` ou `:authority` a partir da URL já aprovada. Ele não aceita uma segunda autoridade de roteamento fornecida pelo agente. Também não aceita cabeçalhos `Connection`, `Proxy-Authorization`, `Transfer-Encoding`, `Content-Length` ou `Expect fornecidos pelo agente, a menos que uma integração específica exija um deles e a implementação lide deliberadamente com o caso.

Isso evita uma solicitação dividida entre duas interpretações. Imagine um validador que aprova `https://api.billing.example/v1/invoices` e depois combina cabeçalhos arbitrários do agente. Se a camada HTTP inferior respeitar um valor `Host` fornecido, um proxy, gateway ou servidor mal configurado poderá encaminhar a solicitação por esse cabeçalho. O validador aprovou um destino, mas a solicitação chegou a outro.

A mesma regra vale para a configuração do proxy. Um proxy corporativo pode ser legítimo, mas ele é uma rota de transporte, não uma nova autoridade para a credencial. Mantenha as configurações do proxy fora dos dados da solicitação do agente. Valide o destino final de forma independente e torne o comportamento do proxy visível nos registros de auditoria.

A verificação do certificado TLS é obrigatória para HTTPS, mas a verificação do certificado não é uma permissão para usar qualquer credencial. O cliente deve verificar o hostname da URL aprovada, usar esse hostname para a indicação do nome do servidor quando aplicável e rejeitar uma incompatibilidade de certificado. Não ofereça a um agente uma opção para «ignorar a verificação». Um atalho temporário de diagnóstico tende a virar uma porta de escape permanente.

## Redirecionamentos são novas solicitações, não uma continuação

Um redirecionamento autenticado é uma segunda solicitação com um novo destino. Tratá-lo como uma continuação transparente é uma forma de fazer as credenciais ultrapassarem a fronteira que você pretendia impor.

O padrão mais seguro para clientes de API é desativar o acompanhamento automático de redirecionamentos sempre que uma solicitação carregar credenciais. Devolva a resposta de redirecionamento à camada confiável de solicitações, analise o valor de `Location`, resolva-o de acordo com as regras de URL e passe a solicitação resultante pelo validador completo. Só então decida se fará outra solicitação e só então injete uma credencial para essa nova solicitação.

Um redirecionamento para uma origem diferente não deve receber nenhuma credencial da solicitação original. Isso inclui esquema, hostname ou porta efetiva diferentes. Um redirecionamento de HTTPS para HTTP deve falhar imediatamente em uma chamada de API com credenciais. Um redirecionamento de `api.example.com` para `login.example.com` também é uma mudança de origem, mesmo que os dois nomes pertençam à mesma empresa. A propriedade comum da empresa não é uma regra de transporte.

O código de status HTTP muda o risco. A RFC 9110 especifica o comportamento dos redirecionamentos, incluindo códigos que preservam o método e o corpo da solicitação. A RFC 9700, a prática recomendada atual de segurança do OAuth 2.0, alerta que servidores de autorização não devem usar HTTP 307 ao redirecionar uma solicitação que possa conter credenciais do usuário. O motivo é direto: um cliente pode repetir o método e o corpo originais no novo local.

Isso leva a uma política prática de redirecionamentos:

1. Rejeite redirecionamentos por padrão em chamadas autenticadas entre máquinas.
2. Permita apenas um pequeno conjunto documentado de redirecionamentos quando uma integração precisar deles.
3. Revalide o destino resolvido, o método, os cabeçalhos e o corpo a cada salto.
4. Remova todas as credenciais antes de considerar o próximo salto.
5. Defina um limite baixo de redirecionamentos e registre cada decisão.

Não resolva isso confiando em qualquer subdomínio. `uploads.example.com` e `api.example.com` podem ser administrados por equipes diferentes, usar infraestruturas distintas ou expor caminhos de ataque diferentes. Um curinga que parece conveniente durante a configuração costuma sobreviver ao motivo que o criou.

Há uma armadilha relacionada nas solicitações assinadas. Se uma API assina o método, o caminho, determinados cabeçalhos ou o resumo do corpo, um redirecionamento geralmente não consegue preservar a assinatura. Assinar novamente só é apropriado depois que a próxima solicitação passar por sua própria validação. Uma assinatura prova que alguém com o segredo assinou os dados. Ela não prova que os dados ainda descrevem um destino aprovado.

## Os cabeçalhos precisam ter responsáveis antes de serem filtrados

Filtrar cabeçalhos fica mais fácil quando você decide quem é responsável por cada um. A camada de solicitações deve cuidar das credenciais e do roteamento. O agente pode cuidar apenas dos cabeçalhos de aplicação permitidos por uma integração específica.

Os cabeçalhos de credencial incluem `Authorization`, um cabeçalho de chave de API específico do fornecedor, cookies e, às vezes, um cabeçalho de assinatura. Injete-os depois da validação. Nunca aceite um deles do agente, mesmo que o agente diga que se trata de um placeholder. Um placeholder convida à substituição acidental e ensina a interface errada: o agente propõe uma ação, enquanto o componente confiável fornece a autoridade.

Os cabeçalhos de roteamento e enquadramento incluem `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Upgrade` e os pseudo-cabeçalhos HTTP/2. Deixe a biblioteca de transporte construí-los. A entrada do usuário não deve substituí-los.

Os cabeçalhos de aplicação podem ser permitidos, mas apenas como um esquema. Suponha que uma API aceite um identificador de cliente, uma chave de idempotência e um tipo de conteúdo. Permita esses nomes, valide seus valores e rejeite todo o resto. Não encaminhe um mapa arbitrário de cabeçalhos só porque a maioria das chamadas usa cabeçalhos inofensivos. O cabeçalho raro é o que transforma uma solicitação comum em uma instrução para o proxy, uma variante de cache, uma identidade alternativa ou um caminho de depuração.

`Authorization` também exige tratamento especial nos logs. Registre que o injetor usou a referência de credencial `billing-prod-readwrite`, não seu valor nem uma versão codificada. Ocultar um cabeçalho depois que um logger genérico já o capturou não é confiável. Crie um evento seguro a partir de campos estruturados antes que qualquer componente serialize a solicitação.

Credenciais em cabeçalhos personalizados não são menos sensíveis que bearer tokens só porque usam um nome como `X-Api-Key`. Se o serviço receptor aceita o valor como autoridade, qualquer pessoa que o receba pode conseguir reutilizá-lo. Nomes de cabeçalho diferentes mudam a interoperabilidade e os hábitos de registro. Eles não mudam a necessidade de validar para onde o valor será enviado.

## O método, o caminho e o corpo definem a ação

Uma lista de permissões de hosts é ampla demais quando uma credencial pode ler dados, alterá-los ou iniciar uma movimentação de dinheiro. O formato da solicitação precisa participar da decisão de permissão.

Comece pelo método. Permita os métodos de que a integração precisa e rejeite os demais. Não trate `POST` como inerentemente perigoso e `GET` como seguro. Muitas APIs expõem operações que alteram estado por endpoints GET, e um GET pode vazar informações privadas por parâmetros de consulta ou logs. As regras de método continuam importantes porque tornam a revisão da política concreta.

Depois valide o caminho usando modelos de rota, não um prefixo vago. Um modelo como `/v1/projects/{project_id}/deployments` pode impor o número de segmentos, os caracteres permitidos nos identificadores e se um agente pode escolher um projeto fora do escopo atribuído. Se um endpoint usa um parâmetro de consulta para escolher uma conta, valide esse parâmetro também. Um hostname correto não torna `/v1/accounts/other-team/export` aceitável.

O corpo precisa fazer parte da solicitação congelada. Um validador que aprova um objeto JSON e depois deixa outra camada serializá-lo ou alterá-lo talvez não esteja autorizando os bytes que saem da máquina. Isso fica evidente com chaves JSON duplicadas, codificação de formulários, limites multipart, conversões de ponto flutuante e middleware de solicitações que adiciona campos.

Um projeto prático faz o validador produzir um plano de execução imutável:

```json
{
  "method": "POST",
  "url": "https://api.billing.example/v1/invoices/inv_123/cancel",
  "headers": {
    "content-type": "application/json",
    "idempotency-key": "job-7f3c"
  },
  "body_sha256": "4d94c2...",
  "credential_ref": "billing-cancel"
}
```

O transporte recebe o plano e os bytes preparados do corpo. Ele confirma o resumo do corpo antes de abrir a solicitação autenticada. Deriva os cabeçalhos de roteamento da URL, adiciona o segredo de `credential_ref` e envia exatamente esses bytes. Se o resumo for diferente, a operação falha em vez de tentar adivinhar qual etapa alterou a solicitação.

Essa abordagem também melhora a aprovação humana. Um cartão de aprovação pode mostrar uma ação em linguagem simples, além da origem canônica, do método, da rota, do identificador de conta selecionado e do valor ou nome do recurso. Ele não deve pedir que uma pessoa aprove um bloco JSON bruto em que um campo perigoso esteja escondido perto do fim.

## Um validador pequeno é mais seguro que uma linguagem de políticas geral

O impulso comum é criar um mecanismo amplo de regras: condições arbitrárias, expressões regulares, variáveis, exceções e um bypass de emergência. Parece flexível até alguém precisar decidir se uma credencial pode chegar a um destino de redirecionamento com um cabeçalho de proxy e um corpo JSON montado por um agente.

A maioria dos casos de injeção de credenciais precisa de um modelo menor. Cada credencial deve ter um canal explícito e um contrato compacto de solicitação. Para HTTP, esse contrato define origens aceitas, métodos, rotas, cabeçalhos permitidos, comportamento de redirecionamentos e restrições do corpo. Para SSH, define hosts, usuários, expectativas sobre a chave do host, formatos de comando permitidos e restrições de transferência.

Uma configuração compacta pode ser assim:

```yaml
credential: billing-cancel
channel: https
origins:
  - https://api.billing.example:443
methods: [POST]
routes:
  - /v1/invoices/{invoice_id}/cancel
headers:
  content-type: application/json
  idempotency-key: generated
redirects: deny
body:
  required_fields: [reason]
  allowed_fields: [reason]
```

Esse fragmento não é um sistema de segurança completo. Ele demonstra a restrição importante: uma credencial está vinculada a um formato estreito de ação. Se a próxima integração precisar de `GET /v1/invoices/{invoice_id}`, forneça uma rota separada e, se possível, uma credencial separada, somente para leitura. Não transforme discretamente a credencial de cancelamento em uma chave geral da conta.

As expressões regulares merecem desconfiança nesse contexto. Podem ser úteis para um campo com uma gramática cuidadosamente definida, mas são um substituto ruim para analisar URLs, JSON, comandos shell ou cabeçalhos HTTP. Uma expressão que parece restringir um caminho pode falhar quando a decodificação, a normalização ou um roteador posterior interpreta os mesmos bytes de outra forma.

O Sallyport segue deliberadamente um caminho menor para ações de agentes: mantém os segredos em seu cofre criptografado e executa ações HTTP ou SSH sem expor esses segredos ao agente. Essa separação só é útil quando o gateway de ações valida a ação antes de pedir ao cofre que use uma credencial.

## A validação precisa sobreviver à transferência para o transporte

Um validador perfeito não ajuda se uma camada posterior puder alterar o destino. A fronteira precisa de uma transferência que preserve o que foi aprovado.

Não valide um objeto de solicitação mutável e entregue o mesmo objeto a um middleware que possa reescrever URLs, combinar cabeçalhos, anexar cookies, seguir redirecionamentos ou escolher um proxy a partir de variáveis de ambiente controladas pelo agente. Valide em um plano novo e imutável. Dê ao transporte a entrada menos expressiva possível.

A ordem de execução deve ser fixa e previsível:

1. Analise a ação proposta pelo agente em campos tipados.
2. Valide o destino canônico e o formato permitido da solicitação.
3. Serialize o payload aprovado uma única vez e registre seu resumo.
4. Crie a conexão usando o esquema, o host e a porta aprovados.
5. Injete a credencial no transporte confiável imediatamente antes da transmissão.

Não injete antes para facilitar o código de repetição. Uma repetição é outra transmissão e precisa das mesmas verificações de destino e solicitação. Ela pode reutilizar um plano imutável aprovado quando nada relevante tiver mudado. Se uma repetição alterar host, rota, modo de proxy, método, corpo ou esquema de autenticação, ela será uma nova ação.

A reutilização de conexões só é segura se a biblioteca HTTP mantiver intactas as fronteiras de autoridade. Uma conexão agrupada não pode permitir que os metadados de autorização de uma solicitação vazem para a próxima. Isso parece óbvio, mas mapas de cabeçalhos mutáveis compartilhados e interceptores com escopo inadequado são fontes comuns desse tipo de falha.

Para SSH, a falha equivalente ocorre quando um hostname é validado, mas um wrapper de comando pode passar um `ProxyCommand`, socket de agente, host de salto de destino ou comando remoto diferente depois da aprovação. A decisão de confiança precisa vincular toda a rota e a solicitação de execução, não apenas o primeiro hostname visível ao agente.

## Teste as falhas que os testes comuns de integração deixam de lado

Um injetor de credenciais deve ter testes que provem que ele recusa entradas suspeitas. Testes do caminho feliz confirmam que uma chamada de API funciona. Testes de recusa confirmam que o projeto ainda significa o que você pensa depois de uma atualização da biblioteca ou de um novo recurso do agente.

Monte uma tabela de ações propostas e decisões esperadas. Inclua pelo menos estes casos:

- Uma origem HTTPS e uma rota exatamente aprovadas, que devem funcionar.
- Um sufixo de hostname como `api.billing.example.attacker.invalid`, que deve falhar.
- Uma URL com informações de usuário antes de `@`, que deve falhar.
- Um host válido em uma porta inesperada, que deve falhar.
- Um redirecionamento para uma origem diferente, que deve falhar sem enviar credencial.
- Um cabeçalho `Host`, `Authorization` ou de proxy inesperado, que deve falhar.
- Um corpo que muda depois da aprovação, que deve falhar na verificação do resumo.

Use um servidor de teste local que registre todos os cabeçalhos recebidos. Isso é mais convincente que verificar um objeto de solicitação simulado. O teste deve confirmar que o servidor em um destino de redirecionamento não aprovado não recebeu chave de API, bearer token, cookies nem cabeçalho de assinatura. Teste tanto códigos de resposta de redirecionamento que preservam o corpo quanto os que normalmente se tornam um GET, porque os padrões das bibliotecas variam.

Teste também divergências entre analisadores. Envie ao validador e ao cliente HTTP de produção as mesmas URLs incomuns, incluindo codificação percentual, portas vazias, barras duplicadas, segmentos com ponto, literais IPv6 se houver suporte e nomes internacionalizados se houver suporte. Se eles discordarem sobre a autoridade ou o caminho, rejeite essa categoria até conseguir tornar o comportamento consistente.

Os registros de auditoria devem capturar a decisão do validador antes da chamada de rede e o resultado do transporte depois dela. Um registro útil informa qual referência de credencial foi solicitada, qual origem e rota canônicas foram aprovadas, se houve redirecionamento e por que uma solicitação foi negada. Ele nunca contém material secreto. Se não for possível reconstruir por que uma credencial de saída foi usada, não há evidências suficientes para revisar um incidente.

## A aprovação só é útil quando a solicitação é concreta

Um aviso de aprovação humana pode impedir que um agente use uma credencial no momento errado, mas o aviso precisa descrever uma solicitação que o sistema já tenha validado. Pedir aprovação primeiro e analisar depois transforma a pessoa em um analisador fraco de URLs.

Mostre a origem, a ação, o método, a rota e os campos comerciais importantes. Em uma chamada de pagamento, mostre o destinatário, a moeda e o valor. Para controle de código-fonte, mostre o repositório, a branch e a operação. Para uma API de infraestrutura, mostre a conta, a região, o recurso e o efeito destrutivo. Mantenha segredos brutos e corpos de solicitação sem limite fora do aviso.

A aprovação por chamada faz sentido para credenciais que podem causar danos significativos. A aprovação por sessão funciona para chamadas repetidas e de baixo risco quando a sessão tem uma identidade de processo reconhecível e uma duração curta. Nenhuma das duas substitui a validação da solicitação. Uma pessoa pode aprovar um processo de programação confiável, mas isso não significa que toda URL montada por esse processo mereça a mesma credencial.

A autorização por sessão do Sallyport e as aprovações opcionais de chaves por chamada entram depois dessa fronteira: o aplicativo pode pedir que uma pessoa autorize um processo de agente conhecido ou um uso específico de credencial, enquanto o caminho confiável mantém o segredo e registra a ação. A aprovação precisa abranger o plano de execução concreto e validado, não uma descrição informal da intenção do agente.

A primeira mudança geralmente não é um grande projeto de políticas. Desative redirecionamentos automáticos em chamadas autenticadas. Rejeite cabeçalhos de roteamento e credenciais controlados pelo agente. Analise o destino como uma origem canônica. Depois vincule o método, a rota, os cabeçalhos e o corpo antes que qualquer segredo entre na solicitação. Essa ordem impede toda uma família de vazamentos que nenhum armazenamento cuidadoso de segredos consegue reparar.
