8 min de lectura

Parámetros destructivos de API: valida antes de eliminar

Los parámetros destructivos de API necesitan algo más que un JSON válido. Verifica la propiedad de la cuenta, los ID inmutables, el alcance, la vigencia, las aprobaciones, los reintentos y las pruebas de auditoría.

Parámetros destructivos de API: valida antes de eliminar

Los agentes de IA realizan llamadas destructivas a las API con demasiada facilidad cuando una solicitud parece correcta desde el punto de vista sintáctico. Un cuerpo JSON válido, un nombre de cuenta conocido y una búsqueda exitosa no demuestran que el agente vaya a eliminar el objeto correcto. Antes de que una solicitud externa elimine, revoque, desconecte, cancele o sobrescriba datos, valida la identidad, la propiedad, el alcance y la vigencia directamente con el servicio.

He visto a ingenieros cuidadosos leer una solicitud como «elimina este entorno de pruebas», mientras que la API la interpretaba como «elimina todos los entornos de esta organización». En sentido estricto, el código muchas veces no tenía un error. Aceptaba un selector formado de manera imprecisa, resolvía un nombre en la cuenta equivocada o confiaba en datos obtenidos antes durante la ejecución. Un agente autónomo comete esos errores cotidianos más rápido y con mayor confianza.

Esto no se soluciona pidiendo al modelo que sea más prudente. Coloca una barrera determinista entre la solicitud propuesta por el agente y la solicitud autenticada. La barrera debe rechazar la ambigüedad por defecto y hacer que una persona apruebe el objetivo y el efecto reales.

Una solicitud bien formada aún puede referirse al objeto equivocado

Una solicitud solo está suficientemente preparada para enviarse después de establecer cuatro hechos independientes: el recurso es del tipo correcto, su identificador inmutable es el previsto, pertenece a la cuenta principal aprobada y la operación afectará al conjunto aprobado. Los equipos suelen mezclar estos hechos en una sola búsqueda. Ese atajo es el origen de muchos problemas al eliminar.

Considera un servicio que expone tanto un nombre visible como un ID:

{
  "id": "env_7d3a",
  "name": "staging",
  "account_id": "acct_blue",
  "state": "active"
}

Un agente que busca staging ha encontrado un candidato, no una autorización para eliminarlo. Muchas cuentas tienen un entorno staging. Incluso dentro de una cuenta, los nombres pueden reutilizarse cuando desaparece un objeto antiguo. La única solicitud de acción segura es la que usa el ID inmutable devuelto y lo comprueba contra el ID principal esperado.

La diferencia importa especialmente cuando una API admite una ruta principal como /accounts/{account_id}/environments/{environment_id}. Comprueba ambos segmentos. No deduzcas la propiedad porque el ID apareciera en una respuesta de búsqueda anterior o porque el agente incluyera el mismo nombre de cuenta en su plan. La cuenta principal de la URL de acción forma parte del límite de autorización.

El tipo de recurso merece su propia comprobación. Las API suelen usar un punto de búsqueda compartido o devolver registros mezclados. Un resultado llamado staging puede ser un entorno, un proyecto, un grupo de acceso o una plantilla guardada. Si el servicio tiene distintos puntos de eliminación, selecciona el punto solo después de verificar el tipo devuelto. No construyas un punto concatenando una cadena de tipo producida por el modelo.

Por último, define el efecto esperado antes de inspeccionar los candidatos. «Eliminar la implementación antigua» puede significar borrar un registro de implementación, detener un trabajo en ejecución, revocar un token emitido para él o borrar todo el entorno. Esos efectos no pueden compartir una operación genérica delete. Haz explícitos el verbo solicitado y el tipo de objeto en el contrato de acción.

Los nombres ayudan a las personas, los ID controlan la solicitud

Usa un ID inmutable para dirigirte a un recurso, pero muestra a quien aprueba suficiente contexto humano para detectar una mala elección. Una tarjeta de aprobación que solo dice env_7d3a invita a aprobar sin revisar. Una que solo dice staging deja espacio para la ambigüedad. Muestra ambos datos al operador, junto con la cuenta principal y las consecuencias de la operación.

Un registro de objetivo útil puede tener este aspecto:

{
  "operation": "delete_environment",
  "account": {"id": "acct_blue", "name": "Blue Team"},
  "target": {"id": "env_7d3a", "name": "staging", "type": "environment"},
  "expected_state": "active",
  "effect": "permanently removes this environment and its managed resources"
}

El nombre visible de la cuenta ayuda al operador a detectar que el agente terminó en el tenant equivocado. El nombre del recurso le ayuda a reconocer el objeto. Los ID hacen que la solicitud no sea ambigua. El efecto declarado evita un fallo común de aprobación: la persona cree haber aprobado una detención reversible, cuando el proveedor va a eliminar datos.

No resuelvas un nombre tomando el primer resultado de búsqueda. Los puntos de búsqueda suelen ordenar por relevancia, devolver coincidencias parciales o paginar. Si una tarea proporciona un nombre exacto, exige exactamente un candidato después de filtrar por la cuenta principal y el tipo esperado. Cero candidatos debe hacer fallar la operación. Más de un candidato también. Pedir al agente que elija uno no arregla el problema, porque carece de pruebas para distinguirlos.

El tratamiento de mayúsculas y minúsculas también necesita una regla específica del servicio. Algunos proveedores distinguen entre mayúsculas y minúsculas; otros normalizan los nombres. No normalices los nombres por tu cuenta y supongas que el proveedor actuará del mismo modo. Usa el recurso devuelto por el proveedor como autoridad y conserva la etiqueta exacta en el registro de aprobación.

Las etiquetas, los rótulos y las descripciones aportan contexto, no identidad. Cambian con frecuencia y los usuarios pueden escribir casi cualquier cosa en ellos. Una etiqueta como temporary=true puede acotar una lista revisada, pero no debe sustituir la vinculación con una cuenta ni un ID de recurso inmutable.

El alcance debe ser concreto antes de que el agente pida aprobación

Una operación destructiva tiene un alcance aunque su cuerpo de solicitud contenga un solo ID. El alcance incluye la cuenta principal, los recursos seleccionados, los recursos secundarios que el proveedor elimine automáticamente y cualquier filtro que amplíe la selección. Hazlo concreto antes de pedir la aprobación.

La eliminación de un solo objeto tiene un contrato sencillo: un ID inmutable, una cuenta principal esperada y un tipo de recurso. La eliminación masiva necesita otro contrato. Primero debe producir un conjunto resuelto y después obtener aprobación para ese conjunto o para un resumen acotado que una persona pueda revisar. Enviar un selector directamente a un punto destructivo deja que el servicio externo decida el alcance después de la aprobación.

Supón que un agente propone esta solicitud:

{
  "account_id": "acct_blue",
  "filter": {"label": "cleanup-candidate"},
  "delete": true
}

Ese cuerpo oculta el único dato que el operador necesita: qué recursos coinciden ahora mismo. Expande el selector mediante una llamada de listado de solo lectura, rechaza cualquier paginación que no hayas inspeccionado por completo y normaliza el resultado en ID. Después muestra un recuento y una muestra breve con nombres. Si el conjunto supera el límite aprobado, detente y exige una instrucción nueva.

Nunca permitas que un filtro omitido signifique «todos». En los esquemas de solicitud, distingue entre una lista vacía obligatoria y un selector ausente. Mejor aún, prohíbe que los puntos destructivos acepten filtros dentro de la interfaz de acciones del agente. Haz que la puerta de enlace acepte únicamente una lista de ID resueltos para el trabajo masivo.

Una estructura práctica es:

{
  "operation": "delete_resources",
  "account_id": "acct_blue",
  "resource_type": "snapshot",
  "resource_ids": ["snap_104", "snap_105"],
  "selection_observed_at": "2025-03-08T14:32:11Z"
}

Rechaza una matriz resource_ids vacía, salvo que el flujo permita explícitamente ese caso. Rechaza los ID duplicados. Rechaza los ID de otra cuenta. Aplica un máximo que encaje con la operación aprobada por la persona. Un límite no sustituye la revisión, pero evita que un bucle mal formado convierta una limpieza de dos recursos en un incidente de mil recursos.

Las eliminaciones en cascada también forman parte del alcance. Si borrar un proyecto elimina repositorios, claves de implementación, entornos o registros de facturación, indícalo antes de la aprobación. Si el proveedor solo muestra los detalles de la cascada después de una llamada previa, conserva esa respuesta y exige que el agente la presente. «Eliminar proyecto» es demasiado impreciso cuando el proyecto tiene objetos dependientes.

Lee el servicio dos veces cuando el tiempo pueda cambiar el objetivo

Una lectura previa verifica la intención, pero no congela el objeto. El recurso puede cambiar, trasladarse a otra cuenta o desaparecer entre la validación y la eliminación. Para operaciones sensibles, vuelve a leer el objetivo justo antes de la mutación y utiliza el control de concurrencia del servicio cuando exista.

HTTP ofrece un mecanismo estándar para este patrón. RFC 9110 define solicitudes condicionales con If-Match: el servidor ejecuta el método solicitado solo si la representación actual coincide con una etiqueta de entidad proporcionada por el cliente. Un GET puede devolver un ETag, y un DELETE posterior puede incluir exactamente ese valor.

GET /v1/accounts/acct_blue/environments/env_7d3a HTTP/1.1
Authorization: Bearer [injected credential]

HTTP/1.1 200 OK
ETag: "v42"
Content-Type: application/json

{"id":"env_7d3a","account_id":"acct_blue","name":"staging","state":"active"}

Después de comparar el cuerpo con el objetivo aprobado, envía:

DELETE /v1/accounts/acct_blue/environments/env_7d3a HTTP/1.1
If-Match: "v42"
Authorization: Bearer [injected credential]

Si el servicio devuelve 412 Precondition Failed, considéralo una barrera activada correctamente. No pidas al agente que vuelva a intentar la eliminación sin condición. Obtén de nuevo el recurso, compáralo con los hechos aprobados y solicita una aprobación nueva si cambió algún dato relevante. Un conflicto de versión demuestra que la aprobación anterior quizá ya no sea válida.

Algunos servicios usan números de revisión, marcas de actualización, campos de generación o tokens de solicitud en lugar de ETag HTTP. Usa el mecanismo documentado por el proveedor. Si no ofrece ninguno, reduce el intervalo entre la lectura final y la escritura, haz que la acción sea secuencial y acepta que no puedes demostrar que el objetivo permaneció sin cambios. Esa limitación debe influir en si permites eliminaciones sin supervisión.

No confundas un GET exitoso con permiso para modificar. La credencial de lectura puede ver más de lo que la de escritura puede cambiar, y la autorización puede cambiar de forma independiente del estado del objeto. La respuesta de la mutación sigue determinando si el proveedor aceptó la solicitud.

La validación pertenece al límite de las credenciales

Revoca una ejecución de riesgo
Aprueba una ejecución del agente y revoca esa sesión al instante si su trabajo cambia.

La validación hecha únicamente en una instrucción para el agente o en código generado es orientativa. El componente que conserva o inyecta la credencial debe aplicar las comprobaciones, porque es el último punto capaz de impedir una solicitud saliente.

Este límite debe recibir una propuesta de acción estructurada, no una URL libre ni encabezados arbitrarios. Una definición de acción limitada puede exigir campos como el ID de cuenta, el ID de recurso, el método, el tipo esperado y la versión esperada. Puede construir la ruta saliente a partir de segmentos validados y rechazar parámetros de consulta que amplíen el alcance.

No aceptes una URL completa del agente para intentar deducir su seguridad después. La codificación de URL, las claves de consulta repetidas, los nombres de host alternativos y la normalización de rutas convierten esto en una disputa entre analizadores. Acepta campos tipados, valida cada uno contra el contrato del proveedor y construye tú la URL. Aplica la misma regla a los cuerpos de solicitud. Genera una estructura conocida en lugar de pasar un bloque cuyos campos no inspeccionaste.

Una barrera mínima puede imponer esta secuencia:

  1. Confirma que la operación solicitada existe en una lista permitida y que su método es destructivo por diseño.
  2. Resuelve cada objetivo declarado con una llamada de lectura realizada bajo la misma cuenta principal.
  3. Compara el ID, el tipo, la cuenta principal y el estado requerido devueltos con la propuesta estructurada.
  4. Obtén aprobación para el efecto resuelto, vuelve a comprobar la vigencia y envía la mutación.
  5. Registra el resultado, incluido el ID de solicitud del proveedor cuando lo devuelva.

Mantén pequeña la lista permitida. Una vía de escape genérica llamada raw_http anula todas las comprobaciones de este artículo porque el agente puede volver a introducir destinos, métodos y cuerpos arbitrarios. Los ingenieros añaden estas vías cuando falta un punto y luego olvidan que existen, hasta que eluden las barreras que creían tener.

Las credenciales deben permanecer fuera del contexto del agente. El agente necesita el resultado de una acción permitida, no un token de portador que pueda copiar en un comando curl, un registro o una integración de terceros. Sallyport sigue este modelo para sus acciones HTTP: conserva la credencial en su bóveda cifrada, ejecuta la solicitud por sí mismo y devuelve el resultado al agente.

DELETE no significa que la solicitud sea sencilla o reversible

Los nombres de los métodos HTTP no describen todo el efecto empresarial. RFC 9110 indica que DELETE pide al servidor de origen eliminar la asociación entre un recurso objetivo y su funcionalidad actual. La norma no promete que los datos desaparezcan de inmediato, que los datos relacionados sobrevivan ni que un reintento sea inocuo en una API concreta.

La documentación del proveedor debe definir el efecto real. Algunas API marcan un objeto para eliminarlo más adelante. Algunas crean un tombstone. Otras lo separan de su cuenta principal. Otras eliminan también los elementos secundarios. Lee los códigos de respuesta del punto y las notas sobre su ciclo de vida antes de clasificar una operación como de bajo riesgo.

No envíes un cuerpo con DELETE salvo que el proveedor lo documente explícitamente. RFC 9110 indica que el contenido recibido en una solicitud DELETE no tiene una semántica general definida y puede hacer que las implementaciones rechacen la solicitud. Una API de eliminación que dependa de filtros en un cuerpo puede ser válida para ese proveedor, pero merece pruebas adicionales mediante su ruta de cliente documentada. No debe convertirse en una excusa para pasar selectores libres desde un agente.

Los reintentos requieren el mismo cuidado. Un tiempo de espera de red crea un resultado desconocido: el proveedor puede haber completado la eliminación después de que el cliente dejara de esperar. Reintentar de inmediato puede generar registros engañosos, provocar un segundo efecto en un punto mal diseñado o eliminar un recurso sustituido si el reintento vuelve a resolver por nombre.

Gestiona un resultado desconocido con una regla de inspección previa. Consulta el ID inmutable exacto bajo la cuenta principal exacta. Si el objeto ya no existe y el modelo de eliminación del proveedor permite esa interpretación, registra la operación como completada, indicando que la primera respuesta era incierta. Si todavía existe, inspecciona su estado y el historial de solicitudes del proveedor cuando esté disponible antes de decidir si reintentas. Reutiliza una clave de idempotencia en las operaciones que la admitan, pero no inventes idempotencia cuando el proveedor no la ofrece.

Un 204 No Content solo indica que el servidor aceptó y completó la interacción HTTP tal como la define ese punto. No demuestra que toda la limpieza posterior haya terminado. Si la siguiente acción del agente depende de que la eliminación esté completa, consulta el estado documentado de la operación o del recurso en lugar de tratar el cuerpo vacío como una garantía.

La aprobación debe mostrar las consecuencias, no el transporte en bruto

Mantén las credenciales de eliminación fuera
Guarda las credenciales destructivas de API en la bóveda cifrada de Sallyport, no en el contexto del agente.

Las personas toman mejores decisiones cuando la aprobación describe el efecto en términos corrientes e incluye los identificadores necesarios para verificarlo. Mostrar un método, una ruta y un cuerpo JSON es útil para un ingeniero de API, pero obliga a la persona que debe detectar un objetivo incorrecto a hacer demasiadas interpretaciones.

Para un recurso individual, la aprobación debe indicar qué cambiará, nombrar la cuenta principal, mostrar el nombre y el ID del recurso y mencionar los efectos irreversibles o en cascada. Para una operación masiva, muestra el recuento, una muestra limitada, la regla de selección usada para crear la lista y el hecho de que la acción final utiliza los ID congelados, no la regla.

No pidas una aprobación amplia al principio de una ejecución larga del agente y la uses para todas las eliminaciones posteriores. El conjunto objetivo cambia a medida que el agente descubre recursos. Vincula la aprobación a una sesión y a la acción resuelta. Si cambia el proceso del agente, la aprobación no debe seguir silenciosamente a un proceso nuevo que quizá tenga código o instrucciones diferentes.

El fallo opuesto es la fatiga de aprobación. Pedir que alguien haga clic para cada lectura inofensiva le enseña a hacer clic sin leer, y después da a una eliminación peligrosa el mismo peso visual. Mantén las lecturas sin interacción cuando corresponda, exige autorización de sesión para un agente que acaba de iniciarse y reserva la confirmación por acción para credenciales o acciones con efecto destructivo. Una persona que ve menos avisos puede examinar los importantes.

El registro de aprobación necesita una caducidad clara. Cuanto más espera un agente después de la validación, menos significa la comprobación previa. Si la acción no puede ejecutarse pronto, haz que vuelva a resolver el objetivo y solicite otra aprobación. Puede parecer estricto durante una tarea de limpieza. Es menos costoso que explicar por qué una aprobación de hace una hora se aplicó a un recurso que entretanto había sido creado de nuevo.

Las pruebas de auditoría deben reconstruir la decisión sin exponer secretos

Pon las acciones detrás de Sallyport
Ejecuta la puerta de enlace como una aplicación firmada de la barra de menús de Mac, con el núcleo de la bóveda en el mismo proceso.

Un registro de auditoría útil responde a algo más que «¿ocurrió una solicitud?». Debe permitir reconstruir lo que propuso el agente, lo que informó el servicio antes de la mutación, lo que aprobó una persona, lo que envió la puerta de enlace y lo que devolvió el servicio.

Captura los campos normalizados, no solo una cadena de solicitud sin procesar. Registra el nombre de la acción, la identidad de la sesión del agente, el ID de la cuenta principal, los ID de los recursos, las versiones esperadas, la hora de selección, el efecto aprobado, la hora de aprobación, el método y la ruta salientes, el estado de respuesta y el ID de solicitud del proveedor. Guarda hashes o formas redactadas del material de solicitud cuando pueda contener valores sensibles. Un registro que copia encabezados de autorización se ha convertido en un segundo almacén de credenciales.

Conserva la respuesta previa o un resumen protegido mediante integridad. Sin ella, un revisor posterior no puede saber si el agente eliminó el objeto equivocado porque falló la validación, porque el objeto cambió después de validarse o porque el servicio externo se comportó de forma distinta a la documentada. La diferencia determina cómo reparar el problema.

La evidencia contra manipulaciones importa cuando la misma máquina ejecuta el agente y la puerta de enlace de acciones. Un registro de texto modificable puede ser editado por el proceso que causó el incidente. Sallyport genera sus diarios Sessions y Activity a partir de un registro de auditoría cifrado y encadenado mediante hashes, y sp audit verify puede comprobar esa cadena sin conexión y sin una clave de la bóveda. Eso no convierte una mala aprobación en una buena, pero dificulta ocultar una alteración posterior del registro.

Prueba los registros tanto con solicitudes fallidas como exitosas. Los rechazos, las aprobaciones caducadas, los conflictos de versión y los ID mal formados muestran si los controles realmente bloquearon el trabajo. Un diario lleno de éxitos dice muy poco sobre si la barrera rechazaría una solicitud peligrosa.

Construye las acciones destructivas como contratos limitados

La acción de API más segura es deliberadamente limitada. Acepta una operación conocida, exige una cuenta principal y un ID de objeto conocidos, realiza una comprobación previa y declara el efecto. Las interfaces generales parecen productivas hasta que un agente hace una solicitud inesperada y tu única defensa consiste en esperar que un operador detecte un parámetro sutil.

Empieza haciendo un inventario de las acciones que pueden eliminar, revocar, rotar, desactivar, sobrescribir, publicar o generar cargos. Para cada acción, anota los campos de objetivo inmutables, los campos principales, los estados permitidos, el comportamiento en cascada, el mecanismo de vigencia, el comportamiento de los reintentos y el texto de aprobación. Si no puedes expresar esos hechos, todavía no ofrezcas la acción a un agente autónomo.

Después introduce deliberadamente entradas incorrectas en la barrera: un ID de recurso válido bajo la cuenta equivocada, un nombre visible coincidente con dos resultados, un ETag obsoleto, una lista masiva vacía, un filtro omitido, un objetivo creado de nuevo con el mismo nombre y un tiempo de espera después del envío. Estas entradas revelan si el límite valida el significado o solo valida el JSON.

No resuelvas la ambigüedad haciendo que el agente escriba un plan más largo. Haz que la ambigüedad no pueda representarse en el contrato de acción. Un agente puede proponer una intención y reunir pruebas. El límite de las credenciales debe decidir si esas pruebas identifican un efecto permitido, en este momento y bajo esta cuenta. Esta división te proporciona un sistema que puedes inspeccionar cuando la solicitud es rutinaria y en el que puedes confiar cuando no lo es.

FAQ

¿Basta con validar el formato antes de que un agente de IA elimine un recurso?

No. Un identificador plausible solo demuestra que la solicitud tiene el formato correcto. La comprobación previa debe confirmar que el objeto existe, pertenece a la cuenta o al proyecto previsto, tiene el nombre y el tipo esperados y está dentro del alcance aprobado.

¿Cómo puedo confirmar que un ID de recurso de API pertenece a la cuenta correcta?

Primero pide al servicio externo la representación actual y compara los identificadores inmutables con los campos que aprobó el operador. No permitas que el agente trate un resultado de búsqueda, un nombre visible o una respuesta antigua almacenada en caché como prueba de identidad.

¿La aprobación de una eliminación debe mostrar nombres de recursos o ID?

Usa los ID para ejecutar la acción, pero muestra a las personas tanto el ID como una etiqueta reconocible, por ejemplo, el nombre de la cuenta, la ruta del proyecto, el tipo de recurso y su estado actual. Los nombres ayudan a detectar errores de intención; los ID evitan coincidencias ambiguas.

¿Puedo confiar en una simulación de API para operaciones destructivas?

Solo son seguros si el proveedor los documenta claramente y ejecutan el mismo flujo de autorización y validación que la solicitud real. Una simulación local que simplemente imprime lo que ocurriría sirve para depurar, pero no demuestra que el proveedor acepte la solicitud ni que vaya a afectar a los objetos previstos.

¿Qué ocurre si el recurso cambia después de que el agente lo valide?

Trátalo como una prueba obsoleta. Vuelve a leer el objetivo justo antes de la mutación, incluye un token de versión como un ETag cuando la API lo admita y falla si el objeto cambió. No puedes eliminar todas las condiciones de carrera, pero sí hacer que la ventana peligrosa sea pequeña y visible.

¿Por qué son peligrosos los filtros vacíos en las solicitudes automatizadas de eliminación?

Una lista vacía debe detener la ejecución, salvo que la persona haya aprobado explícitamente una operación que pueda afectar a cero objetivos. Los valores de alcance vacíos son una vía clásica hacia una eliminación amplia, porque muchas API o envoltorios de comandos interpretan la ausencia como «todo».

¿Puede un agente de IA reintentar de forma segura una solicitud DELETE fallida?

No. Los reintentos después de un tiempo de espera requieren un tratamiento específico para cada operación. Usa una clave de idempotencia cuando el proveedor la admita, inspecciona el estado del objeto antes de reintentar y nunca supongas que una respuesta no recibida significa que el proveedor no hizo nada.

¿Cuál es la diferencia entre eliminar un recurso y hacer una eliminación masiva?

Una solicitud para eliminar la base de datos indicada tiene un objetivo limitado y claro. Una solicitud para eliminar todas las bases de datos que coincidan con una etiqueta, todo lo que haya en una cuenta o cada objeto anterior a una fecha tiene un alcance mayor y necesita un recuento, una muestra y una aprobación independiente.

¿Qué debe registrar una auditoría de una eliminación gestionada por IA?

Registra la sesión del agente, la solicitud normalizada, la respuesta de la comprobación previa usada para la comparación, la aprobación, el método y la ruta exactos de salida, la respuesta y un resumen estable del material sensible. Mantén los secretos fuera del diario, pero conserva pruebas suficientes para reconstruir la decisión.

¿Necesito un motor de políticas para controlar las llamadas destructivas de API de los agentes?

Las buenas barreras no necesitan un lenguaje de reglas general. Las comprobaciones fijas de vinculación de cuentas, identidad exacta del recurso, alcance permitido, vigencia y aprobación explícita cubren los fallos que causan la mayoría de los daños y siguen siendo comprensibles durante un incidente.

Sallyport

Sallyport ejecuta llamadas de API y comandos SSH por tu agente de IA. Las claves se quedan en una bóveda local de tu Mac; tú apruebas cada ejecución y cada acción queda en un registro sellado.

© 2026 Sallyport · Código abierto bajo Apache-2.0 · Oleg Sotnikov