Cómo protege Sallyport tus claves
Dónde se guarda una clave y cuándo se abre, cómo se separan las cuentas, qué rechaza el filtro de red y cómo se firma el registro.
En esta página
- La clave recorre un solo tramo: de Sallyport al servicio
- Cada registro guardado tiene su propia clave
- Las cuentas nunca ven los datos de otras
- Un agente no puede apuntar el gateway contra el gateway
- Los agentes entran con sus propios tokens
- Una persona decide donde tú lo pides, y en dos acciones siempre
- Cada llamada queda escrita antes de ejecutarse
- Qué pasa con las respuestas que traen tus llamadas
- Reinicios y caídas nunca pierden ni repiten una llamada
La clave recorre un solo tramo: de Sallyport al servicio
Un único proceso guarda la bóveda y el registro, y hace la llamada saliente por sí mismo. El agente nombra la acción. Sallyport pone la clave en la solicitud y la envía. El agente nunca recibe la clave.
- Ninguna ruta devuelve una clave. Ni a un propietario, ni a soporte, ni por la API. Puedes reemplazar o borrar una clave; nadie puede mostrarla.
- Una clave solo va a las direcciones con las que se guardó. Una conexión nueva, una dirección nueva o un nuevo endpoint de tokens para una clave guardada se rechazan: otra dirección pide una clave nueva, escrita otra vez. Una clave del catálogo también llega a los hosts de la API de su servicio.
- Una clave se abre solo para tres cosas: una llamada del agente con vía libre para salir, la comprobación que inicias al guardar una clave o al pulsar «Volver a comprobar», y la lectura de la lista de herramientas de un servidor MCP que conectaste. Cada apertura queda en el registro antes de usar la clave.
- En memoria, la clave sigue siendo bytes y se borra después de la llamada. Un string de Go no se puede borrar, así que una prueba rompe la compilación si una clave se convierte en uno.
Cada registro guardado tiene su propia clave
La clave raíz abre una clave por cuenta. De la clave de cuenta, HKDF-SHA256 deriva una clave por tipo de dato: claves de servicio, renovaciones de OAuth, solicitudes que envían los agentes, secretos de webhooks. De ella sale una clave por registro.
Cada registro se sella con ChaCha20-Poly1305 y queda ligado a su cuenta, tipo, registro y versión. Si cambias cualquiera de los cuatro, el registro deja de abrirse.
- La clave raíz nunca está en la base de datos. Es un archivo en el host del gateway. Dos cualesquiera de las tres partes de recuperación la reconstruyen.
- La clave raíz se prueba cada día. Una tarea diaria abre con ella una clave de cuenta real, y un fallo llega a los operadores al instante.
Las cuentas nunca ven los datos de otras
El gateway se conecta a la base de datos con un rol que no es dueño de ninguna tabla y no puede saltarse la seguridad a nivel de fila. Cada consulta corre en una transacción que nombra la cuenta y los espacios de trabajo que puede ver.
- Una prueba rompe la compilación si a una tabla o a una partición del registro le falta su política.
- Tu tráfico va por tus propias conexiones. Sallyport mantiene un transporte HTTP por cuenta y host del servicio, así que la solicitud de otra cuenta nunca reutiliza tu conexión.
Un agente no puede apuntar el gateway contra el gateway
Sallyport llama solo a servicios públicos de internet. Antes de abrir una conexión, el gateway resuelve el nombre y compara cada dirección con una lista de bloqueo compilada en el binario. La configuración solo puede ampliar esa lista.
- Se rechazan diga lo que diga la conexión: rangos privados, loopback, link-local y direcciones de metadatos de la nube, CGNAT, multicast y todos los nombres y redes de Sallyport.
- El nombre se resuelve de nuevo cuando la llamada se ejecuta, también si esperó a una persona. La dirección se comprueba y se fija en el momento del envío.
- Tu clave nunca sigue una redirección. Un 3xx vuelve al agente como resultado. Si el agente quiere la nueva dirección, hace una llamada nueva y todas las comprobaciones se repiten.
Los agentes entran con sus propios tokens
Cada agente tiene sus propios tokens, que se muestran una vez al crearlos. La base de datos guarda solo un HMAC-SHA-256 de cada token con un pepper que vive fuera de la base. Una copia de la base no contiene ningún token válido.
- Corta a un agente con un clic. «Pausar agente», en su página, rechaza su siguiente llamada, llegue con el token o el inicio de sesión que llegue. Revocar un token en «Tokens» detiene solo ese token. «Eliminar agente», al final de su página, lo retira para siempre.
- Un cliente MCP que entra con OAuth recibe un token de Sallyport después de que una persona apruebe el cliente en una pantalla de consentimiento. El cliente nunca ve una clave de servicio.
- Una plataforma que ejecuta agentes en máquinas propias se conecta como un acceso para gestionar agentes, no como un agente. Su propio token no llama a nada: el endpoint MCP y el proxy lo rechazan. Recibe un token de una hora por máquina solo después del consentimiento de una persona. Cada uno de esos agentes empieza sin acceso, y solo una persona se lo da. Cada token actúa como el agente propio de esa máquina y termina con la conexión.
- La lista de herramientas cambia según el agente, por eso se marca como privada. Un cliente no puede guardar en caché las herramientas de un agente y mostrárselas a otro.
Una persona decide donde tú lo pides, y en dos acciones siempre
Por defecto, cada llamada se ejecuta sin preguntar. Activa «Preguntar en cada llamada» para un agente y una conexión cuando quieras ver cada llamada antes.
- La tarjeta muestra la solicitud que enviará Sallyport: método, host y ruta. Las palabras del propio agente van en un bloque aparte marcado como no verificado.
- «Aprobar» cubre una solicitud exacta. Esa aprobación está ligada a un digest de esa solicitud, y antes del envío la solicitud guardada se compara con él. El botón de permiso de la tarjeta cubre más: el mismo agente, conexión, clase y ruta, durante un tiempo y un número de llamadas fijados.
- Un DELETE no puede pasar por un GET. Las cabeceras y los parámetros que cambian el método se eliminan antes de clasificar la llamada y antes del digest.
- Un límite de frecuencia o de concurrencia responde con un momento para reintentar. Nunca crea una tarjeta, porque nadie tiene nada que decidir.
Cada llamada queda escrita antes de ejecutarse
La intención de la llamada y su entrada en el registro comparten una transacción con la decisión de enviar. Los números de secuencia salen de una fila contador que un rollback no puede saltar. La numeración no tiene huecos, así que una entrada que falta se lee como un borrado.
- Cada entrada se compromete con la anterior. Su hash cubre el esquema, la cuenta, el número de secuencia, el hash anterior y el evento. El esquema se llama spc-chain/2.
- Cada entrada se firma con Ed25519. Las claves públicas, la activa y las retiradas, se publican en
https://mcp.sallyport.cloud/.well-known/sallyport-audit-keys.json, y una clave retirada sigue en esa lista tras un cambio de clave. - El gateway no puede editar su propio registro. Su rol en la base de datos añade entradas y las lee, y no tiene permiso para modificar ninguna.
- Los eventos se guardan como JSON canónico legible, y la cadena se calcula sobre esos mismos bytes. Quien reciba el archivo lee lo mismo que tú.
- «Descargar registro», en la pantalla «Actividad», guarda el registro completo en JSON Lines, cada entrada con su hash y su firma. Es para quien audita todos los espacios de trabajo: un propietario, o un administrador o auditor de toda la organización sin un rol más limitado en ningún espacio.
- Cada entrada del registro pertenece al espacio de trabajo de aquello a lo que se refiere. La pestaña Registro y un webhook muestran a cada persona las entradas de los espacios donde es propietaria, administradora o auditora, y las de la propia organización. Un administrador de la organización que en el espacio de un cliente solo es miembro no lee las entradas de ese cliente.
Qué pasa con las respuestas que traen tus llamadas
Una respuesta que cabe va directa al agente. Una más larga se guarda para que el agente lea el resto por partes.
- Una respuesta guardada la puede leer el agente cuya llamada la produjo y las personas de tu cuenta que pueden leer el registro. Cada lectura queda en el registro.
- Las respuestas guardadas, la respuesta de cada llamada y los cuerpos de solicitud de más de 1 MiB se borran a los 30 días. Un cuerpo grande se guarda sellado con una clave propia.
- El historial de llamadas, la solicitud de cada agente y el registro se conservan 180 días por defecto. Cámbialo en «Configuración», «Organización», «Registro e historial de llamadas (días)».
- Una notificación del navegador nombra al agente, el tipo de acción y el servicio, con los identificadores de la ruta reemplazados. Nunca lleva valores de argumentos, un cuerpo ni una clave.
Reinicios y caídas nunca pierden ni repiten una llamada
- Una llamada que espera a una persona vive en la base de datos. Un despliegue no la pierde, y el agente continúa con el mismo id de llamada.
- Si el proceso se detiene después de que una solicitud saliera hacia el servicio, la llamada se marca con resultado desconocido. Sallyport nunca la reintenta por su cuenta, así que un pago nunca se envía dos veces.