Pular para a documentação
DocumentaçãoModelo de segurança

Como o Sallyport protege suas chaves

Onde uma chave fica e quando ela abre, como as contas ficam separadas, o que o filtro de rede recusa e como o registro é assinado.

Nesta página

A chave percorre um só trecho: do Sallyport até o serviço

Um único processo guarda o cofre e o registro e faz a chamada de saída por conta própria. O agente nomeia a ação. O Sallyport coloca a chave na requisição e a envia. O agente nunca recebe a chave.

  • Nenhuma rota devolve uma chave. Nem para um dono, nem para o suporte, nem pela API. Você pode trocar ou apagar uma chave; ninguém pode exibi-la.
  • Uma chave vai só para os endereços com que foi salva. Uma conexão nova, um endereço novo ou um novo endpoint de tokens para uma chave salva são recusados: outro endereço pede uma chave nova, digitada de novo. Uma chave do catálogo também chega aos hosts da API do seu serviço.
  • Uma chave abre só para três coisas: uma chamada do agente liberada para sair, a verificação que você inicia ao salvar uma chave ou ao clicar em “Verificar de novo”, e a leitura da lista de ferramentas de um servidor MCP que você conectou. Cada abertura entra no registro antes de a chave ser usada.
  • Na memória, a chave continua em bytes e é apagada depois da chamada. Uma string de Go não pode ser apagada, então um teste quebra o build se uma chave virar uma.

Cada registro salvo tem sua própria chave

A chave raiz abre uma chave por conta. Da chave da conta, o HKDF-SHA256 deriva uma chave por tipo de dado: chaves de serviço, renovações de OAuth, requisições que os agentes enviam, segredos de webhooks. Dela sai uma chave por registro.

Cada registro é selado com ChaCha20-Poly1305 e fica ligado à sua conta, tipo, registro e versão. Mude qualquer um dos quatro e o registro deixa de abrir.

  • A chave raiz nunca fica no banco de dados. Ela é um arquivo no host do gateway. Quaisquer duas das três partes de recuperação a reconstroem.
  • A chave raiz é testada todo dia. Uma tarefa diária abre com ela uma chave de conta real, e uma falha chega aos operadores na hora.

As contas nunca veem os dados umas das outras

O gateway se conecta ao banco com um papel que não é dono de nenhuma tabela e não consegue contornar a segurança por linha. Cada consulta roda numa transação que nomeia a conta e os espaços de trabalho que ela pode ver.

  • Um teste quebra o build se faltar a política em alguma tabela ou partição do registro.
  • Seu tráfego segue pelas suas próprias conexões. O Sallyport mantém um transporte HTTP por conta e host do serviço, então a requisição de outra conta nunca reaproveita a sua conexão.

Um agente não consegue apontar o gateway para o próprio gateway

O Sallyport chama só serviços públicos da internet. Antes de abrir uma conexão, o gateway resolve o nome e confere cada endereço com uma lista de bloqueio compilada no binário. A configuração só pode ampliar essa lista.

  • São recusados, diga o que disser a conexão: faixas privadas, loopback, link-local e endereços de metadados da nuvem, CGNAT, multicast e todos os nomes e redes do Sallyport.
  • O nome é resolvido de novo quando a chamada roda, inclusive a que esperou por uma pessoa. O endereço é conferido e fixado no momento do envio.
  • Sua chave nunca segue um redirecionamento. Um 3xx volta ao agente como resultado. Se o agente quiser o novo endereço, ele faz uma nova chamada e todas as verificações rodam de novo.

Os agentes entram com os próprios tokens

Cada agente tem os próprios tokens, mostrados uma vez na criação. O banco guarda só um HMAC-SHA-256 de cada token com um pepper que fica fora do banco. Uma cópia do banco não traz nenhum token válido.

  • Corte um agente com um clique. “Pausar agente”, na página dele, recusa a próxima chamada, venha com o token ou o login que vier. Revogar um token em “Tokens” para só esse token. “Excluir agente”, no fim da página dele, o retira de vez.
  • Um cliente MCP que entra com OAuth recebe um token do Sallyport depois que uma pessoa aprova o cliente numa tela de consentimento. O cliente nunca vê uma chave de serviço.
  • Uma plataforma que roda agentes em máquinas próprias se conecta como um acesso para gerenciar agentes, não como um agente. O token próprio dela não chama nada: o endpoint MCP e o proxy o recusam. Ela recebe um token de uma hora por máquina só depois do consentimento de uma pessoa. Cada um desses agentes começa sem acesso, e só uma pessoa dá acesso a ele. Cada token age como o agente próprio dessa máquina e termina com a conexão.
  • A lista de ferramentas muda conforme o agente, por isso é marcada como privada. Um cliente não pode guardar em cache as ferramentas de um agente e mostrá-las a outro.

Uma pessoa decide onde você pede, e em duas ações sempre

Por padrão, toda chamada roda sem perguntar. Ative “Perguntar sempre” para um agente e uma conexão quando quiser ver cada chamada antes.

  • O cartão mostra a requisição que o Sallyport vai enviar: método, host e caminho. As palavras do próprio agente ficam num bloco separado, marcado como não verificado.
  • “Aprovar” cobre uma requisição exata. Essa aprovação fica ligada a um digest dessa requisição, e antes do envio a requisição salva é conferida com ele. O botão de permissão do cartão cobre mais: o mesmo agente, conexão, classe e caminho, por um tempo e um número de chamadas definidos.
  • Um DELETE não passa por um GET. Cabeçalhos e parâmetros que trocam o método são removidos antes de a chamada ser classificada e antes do digest.
  • Um limite de frequência ou de concorrência responde com um horário para tentar de novo. Ele nunca cria um cartão, porque ninguém tem nada a decidir.

Toda chamada é registrada antes de rodar

A intenção da chamada e sua entrada no registro dividem uma transação com a decisão de enviar. Os números de sequência vêm de uma linha contadora que um rollback não consegue pular. A numeração não tem buracos, então uma entrada faltando se lê como exclusão.

  • Cada entrada se compromete com a anterior. O hash dela cobre o esquema, a conta, o número de sequência, o hash anterior e o evento. O esquema se chama spc-chain/2.
  • Cada entrada é assinada com Ed25519. As chaves públicas, a ativa e as aposentadas, ficam publicadas em https://mcp.sallyport.cloud/.well-known/sallyport-audit-keys.json, e uma chave aposentada continua nessa lista depois de uma troca de chave.
  • O gateway não consegue editar o próprio registro. O papel dele no banco adiciona entradas e as lê, e não tem permissão para alterar nenhuma.
  • Os eventos ficam guardados como JSON canônico legível, e a cadeia é calculada sobre esses mesmos bytes. Quem receber o arquivo lê o mesmo que você.
  • “Baixar registro”, na tela “Atividade”, salva o registro inteiro em JSON Lines, cada entrada com seu hash e sua assinatura. É para quem audita todos os espaços de trabalho: um proprietário, ou um administrador ou auditor da organização inteira sem papel mais restrito em nenhum espaço.
  • Cada entrada do registro pertence ao espaço de trabalho daquilo a que se refere. A aba Registro e um webhook mostram a cada pessoa as entradas dos espaços onde ela é proprietária, administradora ou auditora, e as da própria organização. Um administrador da organização que no espaço de um cliente é só membro não lê as entradas desse cliente.

O que acontece com as respostas que suas chamadas trazem

Uma resposta que cabe vai direto ao agente. Uma mais longa é guardada para o agente ler o resto em partes.

  • Uma resposta guardada pode ser lida pelo agente cuja chamada a produziu e pelas pessoas da sua conta que podem ler o registro. Cada leitura entra no registro.
  • As respostas guardadas, a resposta de cada chamada e os corpos de pedido acima de 1 MiB são apagados depois de 30 dias. Um corpo grande fica selado com uma chave própria.
  • O histórico de chamadas, a requisição de cada agente e o registro ficam 180 dias por padrão. Mude em “Configurações”, “Organização”, “Registro e histórico de chamadas (dias)”.
  • Uma notificação do navegador nomeia o agente, o tipo de ação e o serviço, com os identificadores do caminho substituídos. Ela nunca leva valores de argumentos, um corpo ou uma chave.

Reinícios e quedas nunca perdem nem repetem uma chamada

  • Uma chamada que espera por uma pessoa fica no banco. Um deploy não a perde, e o agente continua com o mesmo id de chamada.
  • Se o processo parar depois de uma requisição sair para o serviço, a chamada é marcada com resultado desconhecido. O Sallyport nunca a repete por conta própria, então um pagamento nunca sai duas vezes.