TenantGuard
Escanea plataformas de agentes de IA multiinquilino autoalojadas en busca de brechas de aislamiento de inquilinos mediante una herramienta MCP.
Documentación
TenantGuard
Instalar • Inicio rápido • Características • Referencia de CLI • Servidor MCP • Comparar • Preguntas frecuentes
Encuentre la brecha de aislamiento de inquilinos en su plataforma de agentes de IA multiinquilino autoalojada antes de que lo haga un auditor, o un atacante.

Instalar
npm install -g tenantguard-cli
Esta es la instalación recomendada hoy en día. El paquete npm tenantguard-cli ahora publica (renombrado del antiguo tenantguard, que está obsoleto); incluye el binario de plataforma correspondiente como un optionalDependency de npm (verificado con cosign en el momento de la publicación, por lo que no hay un paso de verificación separado para usted) y coloca un comando tenantguard en su PATH.
La cobertura de plataforma en vivo al momento de escribir esto: macOS en Intel y Apple Silicon, Linux en x64 y arm64, y Windows en x64 y arm64.
go install github.com/RudrenduPaul/TenantGuard/cmd/tenantguard@v0.1.1
go install funciona en todas las plataformas que Go soporta y no depende de ningún estado de publicación del registro, por lo que es el respaldo si su plataforma no está cubierta arriba.
También puede omitir el paquete de nivel superior e instalar un paquete binario de plataforma individual directamente:
npm install tenantguard-darwin-arm64 # swap for your platform: darwin-x64, linux-x64, linux-arm64, win32-x64, win32-arm64
./node_modules/tenantguard-darwin-arm64/bin/tenantguard scan --demo
Python (pip / uvx)
Un paquete PyPI, tenantguard-cli, vive en este repositorio bajo python/ y se compila y prueba en CI. Descarga y ejecuta el mismo binario de GitHub Releases que usan los paquetes npm, verificando el SHA-256 checksums.txt de la versión en la primera ejecución (en sí mismo verificado por firma Sigstore antes de que se confíe en cualquier digesto interno) y almacenando en caché el binario verificado localmente después de eso. Eso es un límite de confianza diferente al de los paquetes npm, que incrustan un binario verificado con cosign en el momento de la publicación y no necesitan ninguna descarga en tiempo de ejecución; la verificación de suma de comprobación del envoltorio PyPI es la garantía equivalente para una ruta que tiene que obtener el binario en la máquina del usuario final.
Las versiones de PyPI hasta la 0.1.2 inclusive incluían un error que hacía que pip install tenantguard-cli tuviera éxito pero tenantguard scan --demo fallara en la primera ejecución con could not parse checksums.txt.pem as a PEM certificate (el envoltorio no decodificaba en base64 los activos de certificado/firma producidos por cosign antes de analizarlos). Eso se corrigió en tenantguard-cli 0.1.3, publicado en PyPI el 2026-08-03; pip install tenantguard-cli ahora instala una herramienta funcional sin pasos adicionales.
Inicio rápido
tenantguard scan --demo
Salida real capturada:
TenantGuard: Tenant-Isolation Audit
Target: /var/folders/m0/5tzdd47n6znb166d4w3m2q0c0000gn/T/tenantguard-demo-488625596
[FAIL] TA01 sandbox/workspace mount path is not scoped per-tenant (no ${TENANT_ID} placeholder and no explicit scoped_per_tenant declaration)
.../deployment.yaml:12
Maps to: goclaw#1163 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA02 MCP tool URL targets a private/loopback/reserved address (via real CIDR containment on a literal or DNS-resolved IP) without a verified, IP-pinned SSRF validator or an explicit host allowlist entry. CAVEAT: a PASS trusts the deployment's own pins_resolved_ip/validates_private declaration -- TenantGuard cannot verify the real validator actually pins the resolved IP for the connection itself, so DNS-rebinding/TOCTOU risk persists if that declaration is inaccurate
.../deployment.yaml:22
Maps to: goclaw#1070 | HIPAA Sec164.312(e)(1) Transmission Security (provisional)
[FAIL] TA03 cron binding's target agent does not belong to the declaring tenant
.../deployment.yaml:35
Maps to: goclaw#1217 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA04 exec tool denies direct env dump but not indirect env reads (e.g. jq $ENV), or allows credential-chain leakage via allow_chain_exec (goclaw#1033)
.../deployment.yaml:25
Maps to: goclaw#1227 | HIPAA Sec164.312(a)(2)(iv) Encryption/Decryption (provisional)
[FAIL] TA05 exec-approval allow-always entry is keyed on basename only, not a full path scope
.../deployment.yaml:30
Maps to: goclaw#1216 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA09 sandbox fail-closed posture not declared (sandbox.on_unavailable must be "fail_closed")
.../tenantguard-demo-488625596:0
Maps to: goclaw#246 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA10 agent does not explicitly declare a per-agent config override (workspace restriction or sandbox config), risking silent inheritance of an undeclared global default
.../deployment.yaml:40
Maps to: goclaw#145 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA13 MCP/CLI bridge does not declare HMAC-signed context headers (bridge.hmac_enabled and bridge.context_headers_signed)
.../tenantguard-demo-488625596:0
Maps to: goclaw#91 | HIPAA Sec164.312(e)(1) Transmission Security (provisional)
[FAIL] TA06 cron binding does not declare that its store layer captures/replays the human creator's sender identity at fire time
.../deployment.yaml:35
Maps to: goclaw#1129 | HIPAA Sec164.312(b) Audit Controls (provisional)
[FAIL] TA07 sandbox container privilege is not hardened (root user by default, full host-env passthrough, tmpfs missing noexec/nosuid/nodev, or a dangerous Linux capability added)
.../deployment.yaml:12
Maps to: goclaw#1014 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA11 channel/session device identity is shared across channel_instances declaring different tenants
.../deployment.yaml:54
Maps to: goclaw#1064 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA11 channel/session device identity is shared across channel_instances declaring different tenants
.../deployment.yaml:57
Maps to: goclaw#1064 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA15 channel_instances entry does not declare reload_strategy: differential, so any single create/update/delete on that entry triggers a full stop/restart of every running channel instance across all tenants (no per-instance fingerprint/diff step). CAVEAT: a PASS trusts the deployment's own reload_strategy declaration -- TenantGuard cannot verify the real InstanceLoader actually performs a differential (fingerprint-diffed) reload rather than the destructive full rebuild, so a mismatched declaration would still scan clean
.../deployment.yaml:54
Maps to: goclaw#1147 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[FAIL] TA15 channel_instances entry does not declare reload_strategy: differential, so any single create/update/delete on that entry triggers a full stop/restart of every running channel instance across all tenants (no per-instance fingerprint/diff step). CAVEAT: a PASS trusts the deployment's own reload_strategy declaration -- TenantGuard cannot verify the real InstanceLoader actually performs a differential (fingerprint-diffed) reload rather than the destructive full rebuild, so a mismatched declaration would still scan clean
.../deployment.yaml:57
Maps to: goclaw#1147 | HIPAA Sec164.312(a)(1) Access Control (provisional)
[PASS] 1 check(s) clear
Summary: 14 FAIL, 1 PASS
Findings map to confirmed open goclaw issues where applicable. HIPAA citations are provisional, see README.
El fixture incluido es deliberadamente ruidoso: existe para ejercitar casi todas las reglas a la vez. TA08 (cifrado de almacenamiento de credenciales) y TA14 (aislamiento de perfil de recursos por agente) son comprobaciones por entrada que solo se activan contra entradas providers y resource_profiles en la configuración escaneada, y este fixture declara cero entradas de cualquiera de los dos tipos, por lo que ambas reglas no tienen nada que evaluar y no producen ningún hallazgo, ni PASS ni FAIL. TA16 (SSRF de conexión de proveedor) es el mismo tipo de comprobación por entrada contra entradas providers, por lo que tampoco produce nada en este fixture. La única línea que se muestra como aprobada, "1 check(s) clear," es TA12 (recuperación de propietario/administrador), que los valores owner_ids y has_recovery_command del fixture están deliberadamente configurados para satisfacer. El código de salida es 1, ya que hay hallazgos; consulte Referencia de CLI para el contrato completo de códigos de salida.
Escanee una implementación real y emita SARIF para el escaneo de código en su lugar:
tenantguard scan --target ./deployment --format sarif --sarif-out tenantguard-report.sarif

O emita JSON plano, para un script o agente que prefiera analizar una matriz plana de hallazgos en lugar de un documento SARIF:
tenantguard scan --target ./deployment --format json

Características
TenantGuard escanea la configuración de una implementación de agentes de IA multiinquilino autoalojada contra 16 reglas, cada una derivada de un modo de fallo real y confirmado de aislamiento de inquilinos. Cada regla es de cierre ante fallo: una configuración no declarada o ambigua es una violación, no un pase silencioso.
Límites de aislamiento de inquilinos
| Regla | Qué detecta |
|---|---|
| TA01 | Un montaje de sandbox/workspace es una violación a menos que su ruta contenga el marcador de alcance ${TENANT_ID} o scoped_per_tenant esté explícitamente declarado como verdadero. Se asigna a goclaw#1163. |
| TA03 | El target_agent de un enlace cron debe pertenecer al inquilino que declaró el enlace; una referencia colgante o entre inquilinos falla de forma cerrada. Se asigna a goclaw#1217. |
| TA11 | Marca dos entradas channel_instances que comparten el mismo device_session_id pero declaran inquilinos diferentes (por ejemplo, una fila compartida de dispositivo WhatsApp). Se asigna a goclaw#1064/#1065. |
| TA14 | Un perfil de recursos por agente (navegador/contenedor) es una violación a menos que su ruta contenga el marcador ${TENANT_ID}. Se asigna a goclaw#778. |
| TA15 | Marca una entrada channel_instances que no declara explícitamente reload_strategy: differential; un valor no declarado o full ambos significan que cualquier creación/actualización/eliminación única en esa entrada desencadena una detención/reinicio destructivo completo de cada instancia de canal en ejecución en todos los inquilinos. Confía en la declaración de la propia implementación (TenantGuard no puede verificar que el cargador real realmente diferencie por huella digital). Se asigna a goclaw#1147. |
Exposición de red y credenciales
| Regla | Qué detecta |
|---|---|
| TA02 | Marca una URL de herramienta MCP guardada que apunta a una dirección privada/loopback/reservada, usando net.cidr_contains real en una IP literal o resuelta por DNS (no coincidencia de cadenas), a menos que la implementación declare tanto validates_private como pins_resolved_ip (o el host esté explícitamente en la lista blanca). Documenta explícitamente la limitación de DNS-rebinding/TOCTOU. Se asigna a goclaw#1070. |
| TA04 | Marca una herramienta exec que niega lecturas directas de volcado de entorno pero no lecturas indirectas (por ejemplo, jq $ENV), y de forma independiente marca cualquier herramienta con allow_chain_exec: true, ya que las variables de entorno de credenciales se filtran a cada comando en una cadena de operadores de shell. Se asigna a goclaw#1227 y goclaw#1033. |
| TA08 | Una configuración de proveedor es una violación a menos que declare un algoritmo de cifrado fuerte reconocido (actualmente solo aes-256-gcm) para tokens OAuth/credenciales almacenados. Se asigna a goclaw#65. |
| TA16 | Marca una URL de conexión de proveedor (por ejemplo, litellm, bifrost) que apunta a una dirección privada/loopback/reservada, usando la misma lógica basada en net.cidr_contains que TA02 aplica a las herramientas MCP, a menos que la implementación declare tanto validates_private como pins_resolved_ip (o el host esté explícitamente en la lista blanca). Se asigna a goclaw#1430. |
Endurecimiento de ejecución y aprobación
| Regla | Qué detecta |
|---|---|
| TA05 | Una aprobación de ejecución "permitir siempre" basada solo en el nombre base, no en una ruta completa, es una violación, ya que puede reutilizarse contra un ejecutable diferente que comparta ese nombre base. Se asigna a goclaw#1216. |
| TA07 | Marca la ejecución por defecto como root, el paso completo del entorno del host, montajes tmpfs que carecen de noexec/nosuid/nodev, o cualquier capacidad peligrosa de Linux añadida (SETUID, SETGID, CHOWN, SYS_ADMIN, DAC_OVERRIDE, NET_ADMIN, SYS_PTRACE). Se asigna a goclaw#1014, #1015, #524. |
| TA09 | Una implementación debe declarar explícitamente sandbox.on_unavailable: fail_closed; un valor no declarado se trata como una violación, no como un pase silencioso. Se asigna a goclaw#246. |
Identidad, auditoría y recuperación
| Regla | Qué detecta |
|---|---|
| TA06 | Un enlace cron cuya configuración no declara captures_creator_identity es una violación; sin él, un trabajo de contexto de grupo se ejecuta bajo una identidad system en lugar del creador humano real. Se asigna a goclaw#1129. |
| TA12 | Comprobación a nivel de implementación: una violación si owner_ids está vacío o no se declara ningún comando de recuperación/reinicio, arriesgando un bloqueo permanente del operador. Se asigna a goclaw#954. |
| TA13 | Comprobación a nivel de implementación: una violación si bridge_hmac_enabled o bridge_context_headers_signed no se declara como verdadero; una declaración faltante por defecto es sin firmar y falla, nunca pasa silenciosamente. Se asigna a goclaw#91. |
| TA10 | Proxy de configuración estática de mejor esfuerzo: marca un agente cuya entrada no declara explícitamente has_workspace_restriction_override o has_sandbox_config_override. Se asigna a goclaw#145. |
Otras capacidades verificadas:
- Salida SARIF 2.1.0 (
--format sarif), válida según esquema, con ubicaciones reales de bytes/líneas y mensajes, lista paragithub/codeql-action/upload-sarify el escaneo de código de GitHub. - Salida JSON plana (
--format json), una alternativa ligera de esquema a SARIF para un script o agente que solo quiere resultados crudosrule_id/status/file/linesin el modelo de objetos de herramienta/ejecución/regla/taxonomía de SARIF. A diferencia de SARIF (que solo informa FAIL como un "resultado"), el modo JSON incluye también cada PASS, además de un recuentosummary.fail/summary.pass. Fusionado enmain, aún no en una versión etiquetada. Consulte la nota bajo Referencia de CLI. - Citas HIPAA provisionales en cada hallazgo (
--control hipaa), mapeadas por regla, marcadas como provisionales (consulte Preguntas frecuentes). - Modo demo sin configuración (
--demo) que escanea una implementación sintética incluida, sin necesidad de configuración de destino. - Acción de GitHub (
action/action.yml) que instala una versión fijada mediantego instally sube el informe SARIF automáticamente. - Modo servidor MCP (
tenantguard mcp) que expone el mismo motor de escaneo como una herramienta que un agente de IA puede llamar directamente a través de stdio, en lugar de solo a través de un humano escribiendotenantguard scan. Fusionado enmain, aún no en una versión etiquetada. Consulte Servidor MCP (uso nativo de agente) a continuación para saber qué se necesita para ejecutarlo hoy.
Referencia de CLI
TenantGuard tiene dos subcomandos: scan (la auditoría en sí) y mcp (ejecuta el mismo motor de escaneo como un servidor MCP a través de stdio, consulte Servidor MCP (uso nativo de agente)). No hay una bandera de nivel superior --help o --version; ejecutar tenantguard sin argumentos, tenantguard --help, o cualquier primer argumento que no sea scan o mcp imprime las líneas de uso a continuación en stderr y sale con 2.
[!WARNING] Estado de la versión:
--format jsony el subcomandomcpque se muestra a continuación están implementados enmainpero aún no están en la última versión publicada (consulte la insignia npm arriba para la versión actual), confirmado al ejecutar el binarionpm install -g tenantguard-clien vivo justo ahora:--format jsonse ignora silenciosamente (cae a la salida de terminal) ymcpno se reconoce como subcomando.go install .../cmd/tenantguard@v0.1.1se resuelve a un binario más antiguo, etiquetado por separado (aún no se ha cortado una versión de GitHub que coincida) con la misma limitación. Para usar--format jsonotenantguard mcpahora mismo, compile desde el código fuente en su lugar:go install github.com/RudrenduPaul/TenantGuard/cmd/tenantguard@main. Ambos se enviarán una vez que se corte una versión etiquetada que coincida; esta nota se eliminará entonces.
usage: tenantguard scan [--target DIR | --demo] [--format terminal|sarif|json] [--control hipaa]
tenantguard mcp
Salida de tenantguard scan --help:
Usage of scan:
-control string
compliance framework to cite (hipaa)
-demo
scan a bundled synthetic deployment instead of --target (zero setup)
-format string
output format: terminal, sarif, or json (default "terminal")
-sarif-out string
file to write SARIF output to when --format=sarif (default "tenantguard-report.sarif")
-target string
path to the deployment config directory to scan
Códigos de salida (definidos en cmd/tenantguard/main.go):
| Código | Significado |
|---|---|
0 | Escaneo limpio, sin hallazgos |
1 | El escaneo se ejecutó correctamente, hay hallazgos |
2 | Error de escaneo o de uso |
Servidor MCP (uso nativo de agente)
[!WARNING] Aún no en una versión publicada o etiquetada. Todo en esta sección describe el comportamiento de la rama
main. Ejecutego install github.com/RudrenduPaul/TenantGuard/cmd/tenantguard@mainpara obtener el subcomandomcphoy; los paquetes npm/pip publicados actualmente y el binariov0.1.1go installen Instalar aún no lo tienen y imprimirán un error de uso si lo intenta.
Todo lo anterior asume un humano escribiendo tenantguard scan en una terminal. TenantGuard también se ejecuta como un servidor MCP, por lo que un agente de IA (un asistente de codificación, un agente de operaciones, cualquier cosa que hable el Protocolo de Contexto de Modelo) puede llamar al motor de escaneo directamente como una llamada de herramienta, en lugar de invocar la CLI y analizar texto.
tenantguard mcp
Esto inicia un servidor MCP en stdio y se bloquea hasta que el cliente se desconecta, de la misma manera que cualquier otro servidor MCP basado en stdio se ejecuta bajo la supervisión de procesos de su cliente. No acepta banderas ni argumentos posicionales. Internamente es un adaptador de protocolo delgado (internal/mcpserver) sobre exactamente el mismo pipeline internal/collector -> internal/policy -> internal/compliance -> internal/report que ejecuta el subcomando scan de la CLI; no hay lógica separada de evaluación de reglas que mantener sincronizada.
Expone una única herramienta, scan, con tres argumentos que reflejan las propias banderas de la CLI:
| Argumento | Se asigna a | Notas |
|---|---|---|
target | --target | Obligatorio. Ruta al directorio de configuración de despliegue a escanear. |
format | --format | Opcional. json, sarif o terminal. El valor predeterminado es json para MCP (la propia CLI usa terminal por defecto), ya que un agente que invoca la herramienta casi siempre quiere salida estructurada, no un informe formateado para humanos. |
control | --control | Opcional. Solo se reconoce hipaa hoy; un valor vacío también usa hipaa por defecto, coincidiendo con la CLI. |
Para la salida json y sarif, el resultado se devuelve tanto como texto como StructuredContent de MCP, de modo que un cliente que quiera leer los campos directamente (rule_id, status, file, line) no tenga que volver a analizar el bloque de texto por sí mismo. Los fallos a nivel de herramienta (una ruta de destino incorrecta, un error al cargar una política) se devuelven como un resultado de error MCP normal, no como un fallo a nivel de protocolo, de modo que un agente que invoca la herramienta pueda manejar "el escaneo falló" de la misma manera que maneja cualquier otra llamada de herramienta fallida.
Para registrar TenantGuard con un cliente compatible con MCP como Claude Desktop, añádelo a la configuración de servidores del cliente:
{
"mcpServers": {
"tenantguard": {
"command": "tenantguard",
"args": ["mcp"]
}
}
}
Esto asume que tenantguard ya está en tu PATH (consulta Instalación). Si lo instalaste en otro lugar, reemplaza "command" con la ruta completa al binario.
Antes de que esto se publicara, la única forma de ejecutar un escaneo era que una persona invocara la CLI directamente. Con tenantguard mcp, un agente puede llamar a scan como herramienta, obtener hallazgos estructurados y actuar sobre ellos en la misma sesión, sin que una persona lea la salida del terminal y escriba el siguiente comando manualmente.
Cómo se compara TenantGuard
| Herramienta | Enfoque | Consciente de agentes de IA multiinquilino | Salida SARIF | Número de reglas | Madurez del proyecto |
|---|---|---|---|---|---|
| TenantGuard | Auditoría de configuración de aislamiento de inquilinos para plataformas multiagente autoalojadas | Sí, diseñado específicamente para esta única superficie | Sí, verificada (SARIF 2.1.0) | 16, todas centradas en el aislamiento de inquilinos | Activo en npm/PyPI (consulta las insignias arriba); dos versiones etiquetadas en GitHub (v0.1.0, v0.1.1) |
| Checkov | Escáner de configuración incorrecta de IaC/nube de propósito general (Terraform, CloudFormation, Kubernetes, Dockerfile y más) | No, el README no hace referencia a plataformas de agentes de IA multiinquilino ni a comprobaciones de aislamiento de inquilinos | Sí, verificada (-o sarif) | 1.000+, políticas generales de nube/IaC | 8,9k estrellas en GitHub, establecido desde hace tiempo, mantenido activamente |
| Conftest | Herramienta de referencia de prueba de políticas OPA/Rego para datos de configuración estructurados (más de 18 formatos de entrada) | No, es el banco de pruebas Rego genérico sobre el que otras herramientas construyen paquetes de políticas; sin paquete de reglas integrado de aislamiento de inquilinos o agentes de IA | Sí, verificada (-o sarif, SARIF 2.1.0) | 0 integradas (un motor de prueba de políticas, no un paquete de reglas) | Proyecto OPA de referencia establecido desde hace tiempo, mantenido activamente |
| PolicyGuard | Escáner de configuración incorrecta de AWS/Azure para Terraform/OpenTofu (Go + OPA/Rego, CLI Cobra, motor OPA en sandbox) | No, está limitado estrictamente a recursos AWS/Azure de Terraform/OpenTofu; no menciona sistemas multiinquilino ni plataformas de agentes de IA | Sí, verificada (SARIF 2.1.0 con huellas estables y etiquetas CWE) | 15+ comprobaciones de recursos AWS/Azure | 1 estrella, 2 bifurcaciones, 4 versiones (v0.3.1) |
| AgentShield | Escáner de seguridad de agentes de IA (secretos, permisos, hooks, seguridad del servidor MCP, revisión de configuración de agentes) | No, está limitado explícitamente al directorio local .claude/ de un único usuario de Claude Code (entorno de desarrollo de un solo usuario/equipo), no al aislamiento SaaS multiinquilino | Sí, verificada (--format sarif, SARIF 2.1.0) | 102, en 5 categorías | Más de 1.000 estrellas en GitHub, mantenido activamente (comenzó en un hackathon de febrero de 2026) |
TenantGuard intercambia amplitud por profundidad: 16 reglas es una fracción de las más de 1.000 de Checkov, y TenantGuard solo tiene dos versiones etiquetadas frente a las trayectorias mucho más largas de Checkov, Conftest y PolicyGuard. Lo que TenantGuard tiene que ninguno de los demás tiene es un paquete de reglas diseñado específicamente para el aislamiento entre inquilinos en despliegues autoalojados de agentes de IA, una superficie que ninguno de los escáneres de IaC de propósito general cubre y que incluso AgentShield, la coincidencia de dominio más cercana, no llega a cubrir: audita la configuración local de un único desarrollador, no el aislamiento entre inquilinos en un despliegue autoalojado y multiinquilino. Ese es el nicho al que TenantGuard apunta, de forma estrecha y deliberada.
Los puntos de referencia de precisión/exhaustividad para el propio conjunto de reglas de TenantGuard contra fixtures etiquetados aún no se han publicado; cuando un competidor de arriba reporta un número (por ejemplo, la precisión/exhaustividad de PolicyGuard), las cifras se citan del propio README de ese proyecto, no se han verificado de forma independiente aquí.
Qué es TenantGuard y por qué existe
TenantGuard es un escáner de políticas como código de línea de comandos, escrito en Go y construido sobre OPA/Rego, que audita la configuración de una plataforma multiinquilino autoalojada de agentes de IA en busca de defectos de aislamiento entre inquilinos: la clase de error donde el agente, sandbox, trabajo cron o credencial de un inquilino puede alcanzar o afectar a otro.
TenantGuard existe porque una plataforma real y confirmada de agentes de IA multiinquilino (goclaw) ha tenido múltiples problemas abiertos y sin resolver exactamente en esta categoría, incluyendo un montaje de sandbox no limitado por inquilino, una brecha de autorización entre agentes, una herramienta exec que filtra secretos a través de una ruta indirecta, una omisión de aprobación basada en un nombre de archivo en lugar de un ámbito de ruta real, y una discrepancia de validación SSRF en URLs de herramientas guardadas y conexiones de proveedores de LLM. Ningún escáner de IaC de propósito general existente (Checkov, Conftest, PolicyGuard) ni escáner de seguridad de agentes de IA (AgentShield) comprueba esta categoría específica de fallos: aislamiento entre inquilinos en un despliegue autoalojado y multiagente. TenantGuard llena ese vacío con 16 reglas de cierre ante fallo, cada una trazable a un problema real y citado.
TenantGuard no es un escáner genérico de Terraform/Kubernetes y no reemplaza a Checkov ni a Conftest para la configuración incorrecta general de infraestructura en la nube. Está enfocado específicamente a la superficie de aislamiento entre inquilinos de despliegues de agentes multiinquilino autoalojados.
Preguntas frecuentes
¿En qué se diferencia TenantGuard de un escáner de IaC genérico como Checkov o Conftest? Checkov y Conftest escanean infraestructura como código general (Terraform, Kubernetes, CloudFormation y similares) en busca de categorías amplias de configuración incorrecta. Ninguno incluye un paquete de reglas para despliegues de agentes de IA multiinquilino. Las 16 reglas de TenantGuard están diseñadas específicamente para esa única superficie: montajes de sandbox, vinculaciones cron/agente, registros de herramientas MCP, conexiones de proveedores de LLM, aprobaciones de exec e identidad de canal/sesión, cada una derivada de un defecto real y citado.
¿Reemplaza TenantGuard a OPA o Conftest? No. Las reglas de TenantGuard están escritas en Rego y TenantGuard incluye su propia ruta de evaluación; es un paquete de políticas y una CLI de propósito específico, no un banco de pruebas Rego de propósito general. Si necesitas probar configuración estructurada arbitraria contra políticas Rego arbitrarias, Conftest es la herramienta general adecuada. TenantGuard es la herramienta adecuada específicamente para comprobaciones de aislamiento entre inquilinos en un despliegue multiagente.
¿Qué significa la cita de HIPAA en cada hallazgo? Cada hallazgo está anotado con una cita relacionada de la Regla de Seguridad de HIPAA (por ejemplo, Sec164.312(a)(1) Control de Acceso) para ayudar a mapear un hallazgo técnico a un control de cumplimiento que un revisor quizás ya rastrea. Estas citas están marcadas como provisionales: indican un mapeo plausible entre el control técnico y la sección de HIPAA citada, no una determinación de cumplimiento legal o auditada. Trátalas como un punto de partida para tu propia revisión de cumplimiento, no como un sustituto de ella.
¿Un PASS en TA02 (SSRF) significa que la URL de la herramienta MCP está realmente a salvo del reenlace de DNS?
No completamente. TA02 usa contención CIDR real contra una IP literal o resuelta por DNS, no coincidencia de cadenas, pero un PASS confía en la propia declaración pins_resolved_ip/validates_private del despliegue. TenantGuard no puede verificar de forma independiente que el validador real fije la IP resuelta para la conexión real, por lo que un riesgo de reenlace de DNS/TOCTOU persiste si esa declaración es inexacta. Esta limitación está documentada directamente en la regla TA02.
¿Puedo escanear un despliegue real en lugar de la demo incluida?
Sí: tenantguard scan --target <path-to-deployment-config-dir>. --demo existe para que puedas ver la herramienta funcionar sin configuración previa antes de apuntarla a una configuración real.
¿TenantGuard produce salida que una canalización de CI o el escaneo de código de GitHub puedan consumir?
Sí. --format sarif --sarif-out <file> produce un documento SARIF 2.1.0 válido según el esquema con ubicaciones y mensajes de resultados reales. La acción de GitHub incluida (action/action.yml) ejecuta un escaneo y sube el informe SARIF mediante github/codeql-action/upload-sarif en un solo paso.
¿Por qué TenantGuard tiene tanto --format sarif como --format json? ¿No es ya SARIF una salida estructurada?
Sí, SARIF es un formato real, estándar y analizable por máquina, y es la opción adecuada para la integración con CI/escaneo de código. --format json existe para un consumidor diferente: un script o agente que quiera analizar rule_id/status/file/line directamente, sin recorrer primero el modelo de objetos de herramienta/ejecución/regla/taxonomía de SARIF. También reporta cada PASS junto a cada FAIL, lo que SARIF deliberadamente no hace (los resultados de SARIF representan problemas encontrados, no una lista de verificación completa), de modo que un llamador pueda responder "qué comprobaste" y no solo "qué marcaste" desde un único documento. Nota: --format json está en main, aún no en la versión que los paquetes de npm/pip instalan hoy, consulta la nota bajo Referencia de la CLI.
¿Qué significan los códigos de salida de la CLI?
0 es un escaneo limpio sin hallazgos, 1 significa que el escaneo se ejecutó correctamente y encontró violaciones, y 2 es un error de escaneo o de uso (incluyendo ejecutar tenantguard sin subcomando, o cualquier subcomando distinto de scan o mcp).
¿Hay un paquete npm?
Sí, npm install -g tenantguard-cli está activo y es la ruta de instalación recomendada (renombrado del antiguo tenantguard simple, que está obsoleto). Depende de un paquete de binario de plataforma correspondiente como optionalDependency de npm; los seis paquetes de plataforma están activos (macOS x64/arm64, Linux x64/arm64, Windows x64/arm64). Consulta Instalación arriba.
¿Hay un paquete PyPI?
Sí, tenantguard-cli está activo en PyPI (código fuente bajo python/, compilado y probado en CI). Las versiones hasta la 0.1.2 inclusive tenían un error de primera ejecución que se corrigió en 0.1.3 (consulta Instalación arriba); pip install tenantguard-cli ahora funciona sin configuración adicional.
¿Puede un agente de IA ejecutar TenantGuard directamente, sin que una persona escriba comandos de CLI?
Sí, mediante tenantguard mcp, que inicia un servidor MCP en stdio exponiendo el motor de escaneo como una herramienta scan. Consulta Servidor MCP (uso nativo por agentes) arriba para la configuración exacta del cliente y los argumentos de la herramienta, y para la nota sobre qué ruta de instalación tiene esto hoy.
¿Es TenantGuard una biblioteca que puedo importar en mi propio programa Go?
No, actualmente no. Todo lo que está fuera de cmd/tenantguard (el recolector, el mapeo de cumplimiento, el fixture de demostración, el motor de políticas y el formato de informes) vive bajo internal/, que las propias herramientas de Go hacen no importable desde fuera de este módulo. TenantGuard se distribuye como un binario de CLI y una acción de GitHub, no como un paquete Go importable.
¿Puedo usar TenantGuard en un producto comercial o de código cerrado?
Sí. TenantGuard está licenciado bajo la Apache License 2.0, que permite el uso comercial, modificación, uso privado y redistribución, incluso dentro de un producto propietario o SaaS, sujeto a los términos estándar de aviso y atribución de la licencia (conservar el aviso de copyright y una copia de la licencia, y marcar cualquier archivo modificado). No se ofrece ninguna garantía, como se indica en la licencia. Consulte LICENSE para conocer los términos completos y autoritativos.
Contribuciones
Las contribuciones son bienvenidas. Consulte CONTRIBUTING.md para saber cómo agregar una nueva regla; cada regla necesita tanto un fixture vulnerable como uno limpio antes de publicarse.
Licencia
Apache License 2.0. Consulte LICENSE.