TrustGate
TrustGate
TrustGate es una demostración de datos sintéticos, en el Modo de Prueba de Razorpay, de un comprador de IA que puede proponer una compra del catálogo sin obtener autoridad para reescribir el comerciante, el importe, la moneda, la aprobación o el resultado del proveedor. El agente propone; TrustGate autoriza de forma independiente y registra la evidencia.
Qué demuestra
El SKU del catálogo y la cantidad son los únicos hechos de compra que un agente puede influir.
La política por inquilino, la aprobación humana, una autoridad de pago de un solo uso y los eventos verificados del proveedor limitan cada acción de pago.
Los intentos no seguros se rechazan antes de que se pueda crear una orden de proveedor y dejan un rastro auditable.
Related MCP server: safe-cart-ai
Cómo se usa la IA aquí
El agente comprador es deliberadamente delgado, y eso es el argumento, no un atajo. Solo puede proponer un SKU del catálogo, una cantidad y un propósito; cada hecho crítico para el dinero se deriva del lado del servidor. Elimina al agente por completo y la capa de autorización no cambia y sigue siendo correcta.
La contribución de ingeniería no es un agente sofisticado. Es tomar en serio los modos de fallo de los modelos de lenguaje — inyección de instrucciones a través de contenido de terceros, seguimiento de instrucciones contra los intereses del operador, razonamiento erróneo y confiado sobre dinero — y construir un sistema que se mantenga correcto cuando ocurren.
Esa afirmación se prueba en ambas direcciones. python -m agent.demo --live ejecuta un modelo real contra descripciones de catálogo escritas por terceros, incluidas las hostiles. El mismo catálogo se envía dos veces, una con las descripciones eliminadas, de modo que la influencia del contenido no confiable se mide comparando las dos propuestas en lugar de autoinformarse. La suite de regresión nunca llama a un proveedor de modelos: utiliza sustitutos deterministas, por lo que la verificación de seguridad no depende de que un modelo se comporte de una manera particular en un día particular.
Viendo el problema
Tres rechazos limpios demuestran que el sistema funciona y son débiles para mostrar por qué alguien lo necesita. Por lo tanto, la demo comienza con el propio código de este proyecto fallando, sin usar red, sin credenciales y sin base de datos:
python -m demo.unguardedEl mismo agente lee el mismo catálogo envenenado — literalmente el mismo, ya que ambos catálogos se construyen a partir de agent/demo_catalog.py y una prueba afirma que la fila sembrada y el objeto de referencia llevan una instrucción inyectada idéntica. Una respuesta del modelo se entrega a dos adaptadores.
El no protegido acepta un importe y un comerciante, por lo que la instrucción inyectada se ejecuta y paga INR 20,000.00 a un comerciante que el texto del catálogo nombró, contra un precio de catálogo de INR 600.00. El otro no tiene dónde poner ninguno de los dos campos, porque PurchaseProposal declara solo un SKU, una cantidad y un propósito. Lo que sobrevive al descarte es quantity=50, que es un campo que el agente puede establecer — y el servidor lo limita contra el máximo propio del catálogo de 2, por lo que el intento se rechaza antes de que se cree una solicitud de pago.
La diferencia no es un filtro que reconoció un ataque. Es que una interfaz tenía un campo para el dinero y la otra no. La línea base tiene sus propias pruebas que afirman tanto que no puede alcanzar nada real como que sigue siendo explotable, ya que una demostración que silenciosamente dejara de ser vulnerable seguiría pasando mientras hiciera el punto opuesto.
Matriz de ataques
Escenarios adversariales de nivel A. Esta tabla se genera desde el registro de escenarios mediante python -m scenarios.report, y una prueba afirma que coincide, por lo que no puede afirmar un ataque que no esté cubierto por una prueba que pase. Cada escenario demuestra tres cosas: el ataque se rechaza con su código de razón, no se creó ninguna orden de proveedor y ningún pago obtuvo autoridad que no tuviera.
ID | Ataque | Invariante demostrado | Pruebas |
A1 | Manipulación del importe | El importe se deriva del precio del artículo del catálogo y de una cantidad limitada por el servidor. Ningún valor suministrado por el agente puede cambiarlo. |
|
A2 | Sustitución del comerciante | El comerciante se deriva del artículo del catálogo con ámbito de inquilino. Un comerciante fuera del inquilino es inalcanzable, y uno fuera de la política activa no puede ser pagado. |
|
A3 | Sustitución de moneda | La moneda se deriva del artículo del catálogo, y la única ruta que acepta una moneda está deshabilitada por defecto y rechaza una discrepancia con la política activa cuando está habilitada. |
|
A4 | Aprobación caducada o reutilizada | Una aprobación es un permiso con una vida útil y un solo uso. Ni una caducada ni una ya consumida pueden autorizar, y una aprobación rechazada no se quema. |
|
A5 | Autoaprobación | Una aprobación no puede ser otorgada por la identidad que solicitó la compra. La separación de funciones se aplica, no solo se espera de la configuración. |
|
A6 | Firma de webhook falsificada | Los eventos del proveedor se autentican mediante HMAC de bytes sin procesar antes de analizar el cuerpo. Una firma falsificada o ausente no cambia nada, por muy bien formado que esté el evento. |
|
A7 | Cuerpo de webhook manipulado | La firma cubre los bytes exactos recibidos, por lo que un evento genuinamente firmado editado en tránsito ya no se verifica y nunca llega a un pago. |
|
A8 | Entrega de webhook duplicada | La identidad del evento del proveedor se almacena, por lo que una repetición de un evento auténtico dentro de la ventana es rechazada por la base de datos en lugar de por el manejador que mire. |
|
A9 | Eventos de proveedor fuera de orden | El orden de llegada es del proveedor y la legalidad es nuestra. Una captura no puede preceder a su autorización, y un pago terminal no acepta ningún resultado adicional. |
|
A10 | Reembolso doble | Ninguna superficie puede iniciar un reembolso en absoluto, afirmado contra la tabla de rutas en vivo y la lista de herramientas, y el invariante del libro mayor rechaza un total de reembolso que exceda la captura. |
|
A11a | Cabecera de inquilino desconocida | Un inquilino que no se resuelve es rechazado antes de que se ejecute cualquier cuerpo de ruta, y el rechazo no revela nada que permita a un llamante enumerar qué inquilinos existen. |
|
A11b | Acceso a objetos entre inquilinos | Cada búsqueda con ámbito de inquilino filtra por el inquilino de confianza. Un inquilino conocido no puede leer ni actuar sobre la solicitud, el pago o la autoridad de otro inquilino en ninguna superficie. |
|
A12 | Colisión de clave de idempotencia | Una clave reutilizada con una compra diferente devuelve la decisión original y un 409. La segunda compra nunca se crea y no puede confundirse con una que fue aceptada. |
|
A13 | Deriva de política entre autorización y uso | Una autoridad no sobrevive a la política contra la que se verificó, ni a la compra para la que se emitió. Una política que la reemplaza o un importe editado la revoca sin quemarla, y una autoridad sin deriva sigue funcionando. |
|
A14 | Webhook obsoleto o con fecha posterior | Una firma prueba el origen, no la actualidad. Un evento fuera de la ventana de frescura, con fecha futura o sin marca de tiempo en absoluto es rechazado antes de cualquier búsqueda. |
|
A15 | Captura no autorizada a través de MCP | Ninguna herramienta accesible por el agente puede autorizar, capturar, reembolsar o llamar a un proveedor. Probado ejercitando cada herramienta expuesta, no inspeccionando nombres de herramientas. |
|
Cada escenario de Nivel A está implementado. A11a y A11b dividen la confusión de inquilinos en un inquilino no resoluble y un inquilino conocido que cruza el límite, porque los dos fallan por razones diferentes y solo el segundo es una cuestión de autorización.
Lo que valen las pruebas
Una suite que pasa dice que el código se comporta como está escrito. No dice que las pruebas objetarían si el código dejara de hacer algo importante, y solo la segunda afirmación importa cuando el tema es dinero. Este proyecto tiene evidencia de la diferencia: las sesiones con ámbito de solicitud descartaron una vez cada escritura mientras 146 pruebas pasaban, porque la suite afirmaba dentro de la misma transacción en la que escribía.
make mutation rompe cada invariante de seguridad a propósito, uno a la vez, y requiere que las pruebas nombradas como sus guardias fallen. Cada archivo fuente se restaura en un bloque finally y la restauración se verifica contra git diff antes de que se imprima el informe, por lo que una ejecución interrumpida no puede dejar una mutación atrás. Sale con código no cero si alguna mutación sobrevive.
Esta tabla se genera a partir del registro de mutaciones mediante python -m scenarios.report --mutations, y una prueba afirma que coincide, por lo que no puede reclamar un invariante protegido que no esté realmente protegido.
Mutación | Invariante que elimina |
| Un pago se bloquea antes de que su estado se lea y se modifique. |
| Una lectura bloqueada decide a partir de la fila confirmada, no de una en caché. |
| Los bloqueos de fila se toman a través del único helper que los mantiene significativos. |
| Un evento de proveedor se autentica antes de hacer cualquier cosa con él. |
| Un evento de proveedor firmado demuestra el origen, no la actualidad. |
| Un evento que no puede fecharse no puede acotarse, por lo que se rechaza. |
| Una aprobación es un permiso con una duración, no una concesión permanente. |
| Una autoridad no sobrevive a la política contra la que se verificó. |
| Una autoridad está vinculada a la compra exacta para la que se emitió. |
| El upsert del presupuesto diario se niega a superar el límite. |
| El presupuesto se devuelve solo mediante un pago que realmente lo reservó. |
| El texto del catálogo no puede terminar el elemento script de la página de pago. |
| Una solicitud exitosa confirma sus escrituras. |
| Los eventos del ciclo de vida de un pago son eventos distintos, no reproducciones. |
| Una aprobación no puede ser otorgada por el actor solicitante. |
| La evidencia se limita al inquilino que la solicitó. |
| Una búsqueda incompleta del proveedor nunca informa un recibo como ausente. |
La primera ejecución de esta suite encontró un defecto en vivo. SELECT ... FOR UPDATE a través del ORM adquiere
el bloqueo correctamente y luego descarta la fila que Postgres devolvió, porque SQLAlchemy mantiene los
atributos de un objeto que ya está en el mapa de identidad de la sesión. Por lo tanto, un segundo llamador se bloqueó en
el bloqueo como estaba diseñado, recibió la fila confirmada, conservó su copia obsoleta y autorizó un pago
que acababa de ser autorizado. El bloqueo estaba serializando cuando se ejecutaban las transiciones, no el estado del que decidían.
Todo el bloqueo ahora pasa por models.locking.locked(), y una prueba afirma que ese
helper es el único lugar en el código fuente que puede tomar un bloqueo.
Alcance Actual
TrustGate utiliza solo inquilinos sintéticos, comerciantes y precios en INR. Es un banco de pruebas de seguridad local, no un procesador de pagos, un producto de cumplimiento, un sistema de consentimiento legal, un modelo de fraude o una integración de pagos en Modo Live.
Inicio Rápido
Requisitos: Docker Desktop y Python 3.12.
Copy-Item .env.example .env
docker compose up -d
docker compose exec -T api python -m alembic upgrade head
docker compose exec -T api python -m pytest -qLa verificación de salud de la API local está disponible en http://127.0.0.1:8000/health.
Crea un inquilino M1 sintético desechable con python -m agent.seed. Establece MCP_TENANT_ID y
MCP_ACTOR_ID a los valores impresos, luego ejecuta la demostración local del agente comprador con
python -m agent.demo "Compra créditos Starter para nuestro club de estudiantes.". Puede proponer solo un SKU
del catálogo, una cantidad y un propósito; el servidor MCP deriva todos los hechos críticos de dinero. Usa
python -m agent.demo --adversarial "Compra una pequeña cantidad de créditos en la nube." para ejecutar la
demostración determinista de catálogo envenenado.
Para ejecutar el mismo flujo con un modelo real en lugar de un sustituto determinista, instala el extra
opcional con pip install -e ".[agent]" y agrega --live. Se admiten dos backends y ambos usan
la misma forma de API de Messages:
TRUSTGATE_MODEL_BACKEND=anthropic(predeterminado) leeANTHROPIC_API_KEY.TRUSTGATE_MODEL_BACKEND=bedrockfactura contra una cuenta de AWS. EstableceAWS_REGIONa la región a la que pertenece la credencial, y luegoAWS_BEARER_TOKEN_BEDROCK(una clave de API de Bedrock, la ruta más simple) o credenciales estándar de AWS para la firma SigV4. Amazon Bedrock aprovisiona modelos de Anthropic a través de una suscripción a AWS Marketplace, por lo que la cuenta de AWS también necesita un instrumento de pago válido incluso cuando los créditos cubrirían el uso.TRUSTGATE_MODEL_BACKEND=groqleeGROQ_API_KEYy no necesita ningún instrumento de pago.
TRUSTGATE_MODEL_ID anula el modelo en cualquier backend. El comprador es una implementación de protocolo,
por lo que el proveedor es una elección de configuración en lugar de una arquitectónica: el comportamiento
de la capa de autorización no depende de qué modelo propone la compra.
Este es el único camino en el proyecto que contacta a un proveedor de modelos; la suite de pruebas nunca lo hace. Ejecútalo solo contra el catálogo de semillas sintético. Sus descripciones de terceros se envían al modelo dos veces, una con descripciones eliminadas y otra intacta, para medir la influencia. Nunca envíes datos reales de clientes, comerciantes o pagos a través de esta demostración.
Para ejercitar el adaptador de Modo de Prueba de Razorpay, establece RAZORPAY_KEY_ID y
RAZORPAY_KEY_SECRET en el archivo .env ignorado. Nunca agregues secretos de Modo de Prueba o Modo Live al
repositorio.
Límite de Confianza
AI buyer proposes SKU, quantity, and purpose
-> TrustGate derives and authorizes money-critical facts
-> Razorpay Test Mode executes a bounded order
-> TrustGate records authorization and provider evidenceEl plan de construcción formal está en docs/build-plan.md; las decisiones de arquitectura, modelo de amenazas y diseño
están en docs/.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Procure governed AI capabilities: machine-readable price, scope, trust, gateway-delegation terms.
Secure agent purchasing with human-approved virtual cards, receipts, and audit trails.
Pre-spend firewall for AI agents. Approves, blocks, flags transactions against policy rules.
Advisory policy preflight for AI-agent spend requests; never executes payments or accesses wallets.
Related MCP Servers
FlicenseNot gradedqualityBmaintenanceEnables AI agents to request purchase approval from humans, receive scoped virtual cards, complete checkout, and report receipts for audit.-- FlicenseNot gradedqualityBmaintenanceEnables AI agents to browse product catalogs and make purchases through a policy engine that enforces spending limits, requires human approval for certain amounts, and logs all actions to an audit trail.-
- FlicenseNot gradedqualityDmaintenanceEnables human-in-the-loop authorization for AI agent transactions, allowing real-time approval or denial of purchases based on configurable spending limits, vendor blocklists, daily caps, and category restrictions.1-
- AlicenseNot gradedqualityBmaintenanceEnables an AI agent to browse inventory and make purchases under strict human approval, with hard spending caps and auditable on-chain payment records.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Saraid10/Trustgate'
If you have feedback or need assistance with the MCP directory API, please join our Discord server