8 min de leitura

Solicitações pendentes em um cofre bloqueado devem esperar?

Solicitações pendentes em um cofre bloqueado precisam de um caminho explícito de falha, contexto atualizado após o desbloqueio, regras restritas de repetição e registros de auditoria que expliquem cada negação.

Solicitações pendentes em um cofre bloqueado devem esperar?

Uma solicitação de agente que chega a um cofre bloqueado deve falhar naquele momento. Ela não deve se transformar em um comando adormecido que volta à vida quando alguém desbloqueia o cofre uma hora depois.

Isso parece rigoroso até você pensar no que um desbloqueio realmente prova. Ele prova que uma pessoa autorizou o acesso a um repositório de segredos neste momento. Não prova que um processo antigo do agente ainda tem a mesma tarefa, que uma implantação continua sendo desejável, que uma pull request não mudou ou que o antigo corpo HTTP e o comando SSH ainda fazem sentido.

Essa é uma daquelas decisões que acabam disfarçadas de recurso de conveniência. Alguém vê uma execução bloqueada e propõe uma fila: guardar a solicitação, mostrar uma notificação e liberar o trabalho depois do Touch ID. A fila parece útil porque a solicitação já está pronta. É justamente por isso que ela é perigosa. Uma solicitação pronta já passou da linha que separa um plano de uma ação aguardando autorização.

A regra mais segura é simples: enquanto o cofre estiver bloqueado, negue as ações e descarte sua forma pronta para envio. Depois do desbloqueio, o agente pode verificar seu estado atual e enviar uma nova solicitação. Essa segunda solicitação pode receber autorização de sessão ou aprovação por chamada, de acordo com o contexto atual.

Um cofre bloqueado deve rejeitar a ação imediatamente

O bloqueio do cofre é um limite de acesso, não uma interrupção temporária de rede. Tratá-lo como uma indisponibilidade incentiva tentativas automáticas, exatamente o que você não quer quando há uma intenção antiga de um agente envolvida.

Quando um agente solicita uma chamada de API ou uma conexão SSH, o gateway já tem informação suficiente para decidir se a solicitação pode prosseguir. Se o cofre estiver bloqueado, não é necessário inspecionar um corpo, resolver um host, iniciar uma conexão ou esperar pelo usuário. O gateway deve retornar a negação antes de tocar no mundo externo.

O resultado precisa informar ao agente o que aconteceu sem convidá-lo a repetir a chamada às cegas. Um formato útil seria:

{
  "ok": false,
  "error": {
    "code": "VAULT_LOCKED",
    "message": "The credential vault is locked. This action was not queued or sent.",
    "request_id": "req_7d4c1f",
    "retryable": false
  }
}

retryable: false pode parecer contraintuitivo. O agente pode fazer uma nova solicitação mais tarde, mas a solicitação que falhou não é segura para repetição. Essa distinção impede que autores de clientes criem um loop genérico de espera que transforme um desbloqueio em uma sequência não revisada de tarefas antigas.

Não substitua isso por 503 Service Unavailable, um timeout ou um erro de transporte genérico. Essas respostas dizem a um cliente bem-intencionado para repetir exatamente a mesma ação. O gateway precisa de um resultado semântico que diga: «Uma condição de segurança controlada por uma pessoa bloqueou esta chamada, e esta chamada específica terminou».

A regra vale tanto para leituras quanto para gravações. As equipes costumam reservar a cautela para gravações porque uma gravação obsoleta pode apagar ou implantar algo. Uma leitura obsoleta também pode expor informações de clientes, revelar uma configuração de produção ou levar um agente a tomar uma decisão posterior com base em dados que o usuário já não pretendia consultar.

Desbloquear não aprova uma intenção anterior

Um evento de desbloqueio e uma resposta de aprovação de ação respondem a perguntas diferentes. O desbloqueio pergunta se o cofre pode usar seus segredos. A aprovação pergunta se esse processo pode fazer esse tipo específico de chamada externa durante a tarefa atual.

Combinar essas decisões cria um erro sutil de autorização. Imagine que um agente prepare um comando SSH para reiniciar um serviço. O desenvolvedor fecha o laptop, o cofre é bloqueado e o agente envia a chamada mesmo assim. Quarenta minutos depois, o desenvolvedor volta e desbloqueia o Mac para investigar outro problema. O serviço é reiniciado porque o gateway manteve o comando antigo. A pessoa não aprovou um reinício naquele momento. Ela aprovou o acesso ao cofre para si mesma.

O mesmo problema aparece de formas menos evidentes:

  • Um agente preparou um comentário em uma pull request, mas o revisor já resolveu o problema.
  • Um agente preparou uma chamada de API de nuvem usando um nome de branch que já não aponta para o mesmo commit.
  • Um agente preparou uma consulta ao sistema de suporte, mas a solicitação do cliente que a justificava já terminou.
  • Um agente preparou a publicação de um pacote, mas um teste falhou enquanto o acesso estava bloqueado.

O contra-argumento comum é que a solicitação já havia sido autorizada antes do bloqueio. Às vezes isso é verdade, mas ainda não justifica o envio adiado. A autorização pode continuar válida durante uma sessão enquanto o processo existir. A intenção não continua válida apenas porque uma sequência de bytes está em uma fila.

Por isso, um gateway deve separar claramente as decisões:

  1. O bloqueio do cofre decide se uma ação que depende de segredos pode começar.
  2. A autorização da sessão decide se esse processo de agente é reconhecido durante sua execução atual.
  3. A aprovação por chamada decide se uma credencial marcada para confirmação individual pode ser usada agora.

Se a primeira decisão for negativa, pare. Não avalie as decisões seguintes e não preserve uma solicitação pronta para envio até que a resposta mude.

Uma notificação não é uma fila de solicitações

É possível avisar uma pessoa de que o trabalho está bloqueado sem manter um trabalho que possa ser executado. São projetos diferentes, mas as equipes os confundem porque ambos são chamados de «solicitações pendentes».

Uma notificação é um fato não acionável. Ela pode informar que um processo tentou usar uma referência de credencial nomeada contra uma classe de destino em determinado momento. Isso ajuda a pessoa a decidir se deve desbloquear o cofre e voltar à tarefa. A notificação não pode reconstruir cabeçalhos, um corpo de solicitação, um comando SSH ou um token de aprovação.

Uma fila de solicitações retém material suficiente para fazer um envio posterior. Ela pode incluir um método HTTP, uma URL, um corpo, argumentos de comando, a seleção da credencial, uma decisão de autorização ou um token assinado para reprodução. Ao guardar esse material, você criou uma execução adiada.

A diferença importa na implementação. Isto é aceitável como aviso de trabalho bloqueado:

{
  "event": "action_denied",
  "reason": "vault_locked",
  "session_id": "ses_31b8",
  "channel": "ssh",
  "credential_label": "production-deploy",
  "destination": "deploy host",
  "occurred_at": "2026-07-22T21:14:05Z"
}

Isto não é aceitável se o sistema puder recuperar mais tarde o comando completo, o endereço de destino, o corpo privado da solicitação ou uma autorização para usar a credencial a partir do evento. O registro deve apoiar a investigação, não a reprodução.

Tenha cuidado também com hashes. Um resumo criptográfico costuma ser seguro para correlação, mas apenas se o gateway não puder usá-lo para recuperar um payload retido. Um resumo acompanhado de um blob oculto ainda é uma fila. Um resumo que existe apenas em um registro de auditoria somente de acréscimo é diferente.

Existe aqui uma tentação de produto: uma lista de solicitações pendentes faz um painel parecer responsivo. Resista, a menos que cada item exija que o agente envie uma nova chamada depois que o usuário agir. Uma tela que oferece «executar tudo após o desbloqueio» transformou um alerta de segurança em um agendador de tarefas adiadas.

Dê ao agente uma máquina de estados que não possa ser mal interpretada

Os agentes se comportam melhor quando o gateway expõe um modelo de estados pequeno e explícito. Erros ambíguos fazem os agentes inventarem planos de recuperação, e o plano inventado pode ser esperar, tentar novamente ou procurar outro caminho para a credencial.

Use uma máquina de estados na qual uma solicitação tenha um resultado terminal assim que o bloqueio do cofre a negar:

received
  |
  +-- vault locked --> denied_locked (terminal)
  |
  +-- vault unlocked --> session check
                           |
                           +-- not approved --> denied_session (terminal)
                           |
                           +-- approved --> per-call check
                                             |
                                             +-- approval declined --> denied_call (terminal)
                                             |
                                             +-- approved --> dispatched --> completed

A parte importante não é o diagrama. É o fato de que denied_locked não tem uma seta de volta para dispatched. Uma solicitação posterior pode entrar em received, mas a antiga não pode voltar a entrar em nenhum ponto.

Esse projeto também facilita o raciocínio sobre idempotência. Se uma chamada falhar porque o cofre estava bloqueado, não reserve um token de idempotência como se o servidor tivesse aceitado a ação. O agente deve criar outra solicitação depois, com um novo ID de solicitação. Se a API externa aceitar chaves de idempotência, a nova solicitação poderá usar uma chave no nível da aplicação que represente a operação de negócio pretendida, mas a negação do gateway não deve criar um registro de ação pela metade.

Para operações de gravação, faça o agente incluir sua própria pré-condição atual sempre que o destino aceitar uma. Pode ser um ID de revisão, a versão de uma entidade, a cabeça esperada de uma branch ou uma ETag. Quando o cofre abrir, o agente deve consultar o contexto atual outra vez e montar uma chamada que o reflita. Uma solicitação obsoleta não passa por uma boa pré-condição, e uma solicitação nova traz evidências de que o agente consultou o estado novamente.

Não tente inferir atualidade apenas pelo tempo transcorrido. Cinco segundos podem ser demais para uma implantação que muda rapidamente, enquanto uma hora pode não fazer diferença em uma consulta estática. A atualidade vem de reler o estado da tarefa e reconstruir a ação, não de um cronômetro.

A aprovação deve estar vinculada à chamada real

Confirme chamadas sensíveis individualmente
Exija confirmação por um clique ou Touch ID a cada uso de uma credencial selecionada.

Mesmo uma solicitação nova depois do desbloqueio ainda precisa de um modelo de aprovação restrito. Caso contrário, você remove a reprodução adiada apenas para substituí-la por uma permissão vaga que permite ao agente mudar de ideia depois que o usuário clica.

Um cartão de aprovação deve estar vinculado ao material que altera o significado de segurança da ação. Para HTTP, isso normalmente inclui o método, o destino normalizado, a referência da credencial e um resumo criptográfico do corpo da solicitação. Para SSH, inclui a identidade do host, a conta, o comando ou seu resumo criptográfico e a referência da credencial. Também deve estar vinculado ao processo do agente e expirar rapidamente.

Evite um cartão que diga apenas: «Permitir acesso do agente à produção». Essa frase faz a pessoa aprovar uma categoria enquanto o agente controla os detalhes. Alguém pode aceitar que um processo leia um endpoint, mas não que invoque um endpoint administrativo no mesmo hostname.

Um registro de aprovação prático pode ter esta aparência:

{
  "approval_id": "apr_8c62",
  "session_id": "ses_31b8",
  "process_identity": "signed-authority-and-process-instance",
  "channel": "http",
  "credential_label": "billing-api",
  "method": "POST",
  "destination": "api.example.internal/v1/invoices",
  "payload_digest": "sha256:...",
  "expires_at": "2026-07-22T21:16:00Z",
  "used": false
}

O gateway não precisa mostrar cada byte de um payload grande para ser honesto sobre o que aprova. Mas precisa vincular a aprovação aos bytes que enviará. Um resumo conciso para a pessoa pode aparecer ao lado de um digest, enquanto o digest protege a solicitação exata contra substituições.

Use registros de aprovação de uso único para credenciais que exigem aprovação por chamada. Marque a aprovação como usada antes do início do envio, não depois que uma resposta retornar. Se a conexão cair depois do envio, o agente talvez precise consultar o destino para saber se a ação teve efeito. Reutilizar a aprovação facilitaria gravações duplicadas.

O caso de falha a testar é desbloquear no momento errado

O teste mais revelador não é «a chamada falha enquanto o cofre está bloqueado?». É «o que acontece quando o mundo muda antes de o usuário desbloquear?».

Configure um serviço de teste inofensivo com um endpoint que registre um destino de implantação e outro que altere o destino permitido atual. Depois execute esta sequência:

  1. Inicie uma tarefa de agente que planeje enviar POST /deploy com {\"revision\":\"a1b2c3\"}.
  2. Bloqueie o cofre antes que o agente envie a chamada.
  3. Confirme que o gateway retorna VAULT_LOCKED e que o serviço de teste não recebe nada.
  4. Altere a revisão permitida para d4e5f6 enquanto o cofre continua bloqueado.
  5. Desbloqueie o cofre por um motivo não relacionado.
  6. Espere sem tocar no agente.

O resultado correto é sem graça: o serviço de teste continua sem receber nada. Se ele receber uma implantação para a1b2c3, seu gateway tem um caminho de execução adiada.

Depois informe ao agente que a chamada foi negada, deixe-o consultar novamente a revisão permitida e faça-o enviar uma nova solicitação. A solicitação esperada agora é d4e5f6, e o gateway pode pedir a autorização de sessão ou por chamada aplicável. Isso prova que o caminho de recuperação preserva o contexto atual, em vez de tratar o tempo em que o cofre ficou bloqueado como um botão invisível de pausa.

Execute o mesmo teste para SSH. Use um comando que escreva um marcador inofensivo contendo a revisão pretendida. Não teste apenas o estabelecimento da conexão. A implementação insegura muitas vezes mantém um comando depois de selecionar uma chave e o envia quando o cofre fica disponível. Você precisa provar que o próprio texto do comando morre no limite do bloqueio.

Não deixe os clientes esconderem a negação

Mantenha segredos HTTP fora do agente
Faça chamadas HTTP por injeção de credenciais, sem entregar segredos de bearer ou de cabeçalhos personalizados ao agente.

Um gateway pode tomar a decisão certa e ainda produzir um comportamento ruim se seus clientes transformarem todo erro em «tente novamente mais tarde». O protocolo precisa ter estrutura suficiente para que frameworks de agentes e scripts de wrapper tratem um cofre bloqueado de forma deliberada.

Os agentes devem receber três instruções no contrato de resposta. Primeiro, a ação não saiu do gateway. Segundo, o gateway descartou a solicitação. Terceiro, o agente não deve repetir automaticamente a mesma solicitação.

O próprio loop de recuperação do agente deve se parecer mais com isto:

if result.error.code == "VAULT_LOCKED":
    record_blocked_task()
    ask the user to unlock when appropriate
    stop this action

if user later resumes the task:
    reread relevant state
    decide whether the action is still needed
    create a new request

A linha decide whether the action is still needed é importante. Ela não deve ser substituída por retry request. Um agente que recebeu novas instruções, editou arquivos, trocou de branch ou descobriu que um teste falhou talvez precise agora de outra ação, ou de nenhuma ação.

Em execuções sem supervisão, devolva a negação ao orquestrador e encerre a execução em um estado bloqueado. Não faça o gateway esperar que alguém desbloqueie o cofre. Um processo de agente em espera mantém memória, retém contexto que pode se tornar sensível e cria pressão para tratar um desbloqueio posterior como autorização para continuar. Uma parada limpa dá à pessoa a chance de revisar a tarefa antes de retomá-la.

Se sua interface mostrar uma notificação, use uma mensagem precisa: «Uma ação do agente foi negada porque o cofre estava bloqueado». Evite botões com os rótulos «continuar» ou «aprovar pendente». Um botão pode abrir o cofre ou mostrar detalhes da sessão, mas não deve fazer uma ação antiga ser executada.

Os registros devem provar que nada foi enviado

Uma negação merece um registro de auditoria porque responde a uma pergunta que os operadores acabarão fazendo: o agente apenas tentou realizar a ação ou realmente entrou em contato com o sistema externo?

Registre o canal tentado, a identidade da execução do agente, a referência da credencial, um destino normalizado, o resultado e os horários. Marque claramente o estado do envio. Os operadores devem conseguir distinguir denied_before_dispatch de dispatch_started, remote_rejected e completed sem interpretar strings de exceção.

Por padrão, não registre segredos, cabeçalhos de autorização brutos, material de chave privada ou corpos completos. Para corpos sensíveis, registre um resumo criptográfico e um pequeno resumo aprovado, caso o sistema possa produzi-lo sem vazar conteúdo. O objetivo é estabelecer o que aconteceu, não criar uma segunda cópia dos dados que o cofre deveria proteger.

Uma consulta de auditoria deve conseguir responder a um relato de incidente como este:

21:14:05  session ses_31b8 attempted SSH action using production-deploy
21:14:05  vault gate denied action before dispatch
21:15:41  vault unlocked by local user action
21:16:09  no action dispatched from ses_31b8

Essa última linha pode ser inferida pela ausência de registros de envio, mas estados terminais explícitos tornam as investigações mais rápidas e reduzem a ambiguidade. Se você usa um registro encadeado por hashes, verifique a cadeia durante a investigação de incidentes e também nas verificações rotineiras. A evidência contra adulteração tem pouco valor se ninguém a usa quando o registro é importante.

A separação do Sallyport entre um diário Sessions para execuções e um diário Activity para chamadas individuais se encaixa bem nesse problema, porque uma negação causada pelo cofre bloqueado pertence tanto ao histórico da execução quanto ao rastro da ação. A verificação offline sp audit verify também permite testar a integridade desse histórico sem abrir o cofre.

Filas de conveniência criam um segundo sistema de autorização

Veja quem solicita acesso
O Sallyport mostra a autoridade de assinatura do código antes que você aprove um novo processo de agente.

Quando um gateway armazena solicitações para liberá-las depois, ele começa a acumular regras: por quanto tempo as solicitações vivem, quem pode liberá-las, se o processo original ainda precisa existir, se o conteúdo pode mudar, o que acontece depois de uma reinicialização e se um desbloqueio libera uma solicitação ou todas elas.

Essas regras são um mecanismo de políticas disfarçado. É difícil explicá-las aos usuários porque cada exceção muda o significado do desbloqueio. Um timeout curto da fila não resolve o problema de significado. Exigir que o processo original continue vivo também não, porque o processo pode estar comprometido ou simplesmente trabalhar com contexto obsoleto.

Mantenha o projeto menor. O bloqueio do cofre nega todas as ações enquanto ele estiver fechado. Uma nova sessão de processo pode exigir aprovação. Uma credencial marcada para aprovação por chamada exige uma confirmação explícita a cada uso. Todo o restante da conveniência deve ficar do lado do agente, como recuperação de tarefas, onde ele precisa reconstruir seu plano e a pessoa pode ver o que mudou.

Isso também cria um hábito confiável para os usuários: desbloquear restaura a capacidade de considerar novas ações. Nunca libera ações que eles esqueceram estar aguardando. As pessoas conseguem tomar boas decisões com esse modelo mental. Elas têm dificuldade quando uma tela de bloqueio também funciona como uma fila de trabalho oculta.

Torne o caminho seguro menos incômodo que o inseguro

As equipes criam filas porque uma falha imediata pode parecer uma interrupção durante o desenvolvimento normal. Corrija o atrito sem reter solicitações executáveis.

Mantenha a autorização da sessão limitada à vida útil do processo do agente para que um desenvolvedor não precise aprovar cada chamada comum. Reserve a confirmação por chamada para credenciais que merecem uma fricção deliberada, como administração de produção ou publicação externa. Retorne uma negação clara que permita ao agente informar o trabalho bloqueado em linguagem simples. Ofereça à pessoa uma forma de desbloquear o cofre, inspecionar a sessão do agente e retomar a tarefa conscientemente.

Depois, torne explícitas as instruções do agente. Diga aos agentes que as credenciais permanecem fora de seu contexto, que um resultado de cofre bloqueado encerra a ação tentada e que uma ação posterior deve ser reconstruída depois de verificar o estado atual. Um prompt de agente não consegue impor a regra, mas reduz tentativas inúteis e facilita o trabalho com o comportamento do protocolo.

O teste desse projeto é simples. Se uma pessoa desbloquear o cofre distraída, cansada ou ocupada com uma tarefa não relacionada, nenhuma ação anterior do agente deve ocorrer. Se isso não for verdade, remova a fila antes que ela se transforme em um relatório de incidente.

FAQ

Uma solicitação de agente de IA deve esperar até que o cofre seja desbloqueado?

Trate um cofre bloqueado como um limite de negação imediata. O gateway deve retornar um resultado identificável por máquina e descartar a solicitação acionável, em vez de armazená-la para execução posterior. O agente só pode tentar novamente depois de obter contexto atualizado e decidir fazer a chamada outra vez.

Por que desbloquear um cofre não deve executar automaticamente ações de agentes que estavam na fila?

Não. Desbloquear o cofre prova que uma pessoa pode acessar os segredos novamente. Isso não prova que uma solicitação anterior ainda seja desejada. O tempo, o estado do repositório, a intenção do usuário e o plano do agente podem ter mudado enquanto o cofre estava fechado.

Que erro um gateway deve retornar quando o cofre está bloqueado?

Use um erro específico, como VAULT_LOCKED, com retryable: false para a solicitação original. Inclua uma explicação curta para o agente e um ID de solicitação para investigação, mas não preserve para reprodução a ação que contém credenciais.

Um agente pode repetir uma solicitação com segurança depois que o cofre é aberto?

Em geral, não. Repetir uma chamada somente de leitura ainda pode revelar dados depois que o usuário mudou de tarefa, e repetir uma gravação pode criar alterações duplicadas ou obsoletas. O agente deve decidir se fará uma nova solicitação depois de receber contexto atualizado e reconstruí-la.

Um prazo curto de expiração é suficiente para tornar seguras as solicitações enfileiradas?

Um prazo de expiração limita o acúmulo acidental, mas não corrige uma intenção obsoleta. Uma solicitação feita antes da abertura do cofre ainda não prova que a tarefa atual do agente e a intenção atual da pessoa correspondem à ação original. A expiração é útil para cartões de aprovação, não para uma fila de execução oculta.

A que um cartão de aprovação deve estar vinculado?

Sim. A aprovação deve estar vinculada ao método exato, ao destino, à referência da credencial, ao resumo criptográfico da solicitação, ao processo do agente e a uma janela de tempo curta. Uma aprovação ampla que diga "permitir acesso do agente" deixa espaço demais para que um invasor ou um agente confuso altere a ação depois.

Como as negações causadas por um cofre bloqueado devem aparecer nos registros de auditoria?

O registro da sessão deve mostrar que o processo tentou realizar uma ação enquanto o acesso estava bloqueado e que o gateway a negou antes do envio. O registro da atividade deve identificar o canal e o destino tentados sem armazenar material secreto. Uma negação é um evento de segurança, não um ruído irrelevante.

Um gateway pode mostrar solicitações pendentes sem colocá-las em uma fila?

Isso pode funcionar se a sala de espera nunca contiver uma solicitação pronta para envio. Armazene apenas um aviso não acionável, como "o agente X precisa de acesso ao serviço Y", e obrigue o agente a enviar uma solicitação nova e completa depois do desbloqueio. Não retenha cabeçalhos, corpos, comandos ou estado de autorização.

O que acontece quando um agente autônomo é executado enquanto ninguém está presente?

O gateway deve preservar o limite humano mesmo quando um agente funciona sem supervisão. Se ninguém puder desbloquear o cofre e aprovar a ação, a execução deve parar, informar o trabalho bloqueado e esperar que uma pessoa a retome ou reinicie mais tarde.

Como evitar entregar credenciais aos agentes quando o cofre costuma estar bloqueado?

Nunca entregue uma credencial ao agente como solução alternativa. Aguarde uma sessão controlada por uma pessoa, use uma credencial não humana deliberadamente limitada em um sistema separado ou redesenhe a tarefa para que ela produza um plano revisável sem fazer a chamada externa.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov