Skip to main content

tirith-config

Operate tirith, the terminal guard against homograph URLs, ANSI injection, and pipe-to-shell. Use when editing ~/.config/tirith/policy.yaml, debugging a blocked command or paste, choosing trust / allowlist / download-and-run / TIRITH=0, or quieting a noisy rule.

Informations de source

Dépôt
nweii/agent-stuff
Dernière activité de la source
2 octobre 2026 à 15:59
Langue détectée de SKILL.md
anglais
Étoiles
10
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
tirith-config
description
Operate tirith, the terminal guard against homograph URLs, ANSI injection, and pipe-to-shell. Use when editing ~/.config/tirith/policy.yaml, debugging a blocked command or paste, choosing trust / allowlist / download-and-run / TIRITH=0, or quieting a noisy rule.
metadata
{"author":"nweii","version":"1.2.0"}
# tirith-config Tirith intercepts shell commands and pasted content to catch homograph URLs (Cyrillic lookalikes, mixed scripts), ANSI escape injection, and `curl | bash`–style pipe-to-shell patterns. This skill encodes operating procedure — decision logic, verification rituals, and inherent gotchas. The current allowlist and tool version are not encoded here; query them at runtime. ## Operating model Tirith has four moving parts. Treat the live config as source of truth, not memory: - **Shell hook** — sourced via `eval "$(tirith init --shell zsh)"` in the user's shell profile. This is what wires per-command interception. Hook source files at `~/.local/share/tirith/shell/` are inert until the eval line is added to the profile. - **Policy file** — `~/.config/tirith/policy.yaml` (global) and `.tirith/policy.yaml` (per-project, walks up from cwd). The per-project file wins when present. - **Audit log** — `~/.local/share/tirith/log.jsonl`. Redacted previews, not full commands. - **Receipts** — created by `tirith run <url>`. Verifiable later with `tirith receipt verify <sha256>`. `tirith doctor` is the canonical health check; it surfaces hook status, policy detection, and bypass mode in one shot. ## Decision tree: a command was blocked Four responses, each appropriate for a different shape of problem: Run `tirith why` first. The rule ID decides which response fits: a pipe-to-shell rule (`curl_pipe_shell`) and a hostname rule (`lookalike_tld`, which flags `.dev`, `.app`, `.zip` and similar TLDs) both clear through trust, but only the first is about the script itself. 1. **Trust the source** — for a vendor you trust. `tirith trust last` shows the last trigger and offers to trust its domain interactively; `tirith trust from-last-trigger` prints the narrowest matching `tirith trust add` command (`--apply` runs it). Entries are scoped to one rule when `--rule` is given, expire after 30 days unless `--permanent` or `--ttl` says otherwise, and are recorded in the trust audit (`tirith trust list`, `tirith trust audit`). Prefer this over the policy allowlist for anything short of a canonical installer. 2. **Allowlist the hostname** — only for canonical installer domains you pipe-shell from repeatedly (e.g., `get.docker.com`, `sh.rustup.rs`). Add to `allowlist:` in `~/.config/tirith/policy.yaml`. An entry suppresses every hostname-scoped rule for that exact host, `lookalike_tld` included; content-level checks (homograph, mixed-script, ANSI) still run. It never expires, which is why trust (1) is the better default. 3. **Download, read, run** — `curl -fsSL <url> -o /tmp/install.sh`, read the file, then `sh /tmp/install.sh`. A plain download is not pipe-to-shell and only trips hostname rules, which warn. This is the most reliable one-off path, and the only one that takes interpreter arguments (`curl … | bash -s -- --prefix /opt`). 4. **`tirith run <url>`** — downloads to a temp file, shows SHA256, runs static analysis, and writes a receipt. It fetches the URL itself, so the original `curl` flags have no counterpart. **Execution is Linux-only**: on macOS it inspects and stops, so follow it with (3) to actually install. `tirith run <url> | sh` pipes the analysis report, not the script, into the shell. 5. **`TIRITH=0` prefix** — honored when the command is checked at Enter, not by the paste scanner. The paste scanner analyzes the pasted text and does not read an assignment inside it, so pasting `TIRITH=0 curl … | sh` is still blocked at paste time, and typing `TIRITH=0 ` before pasting does not help because only the pasted chunk is scanned. It works for a command typed in full. `export TIRITH=0` disables both checks for the whole shell until `unset TIRITH`, which is broader than the problem. Policy's `allow_bypass_env` governs both. Confirm against the installed build: `tirith check --interactive --shell posix -- 'TIRITH=0 curl -fsSL https://example.com/x.sh | sh'` exits 0, while the same text piped to `tirith paste --shell posix --interactive` exits 1. If none of these fit, the command probably shouldn't run. ## Adding to the allowlist ```yaml allowlist: - "vendor.example.com" # one entry per line, exact hostname ``` Hostnames only — no globs, no path-aware matching. After editing: ```bash tirith doctor # confirm policies: still resolves tirith check -- curl -fsSL https://vendor.example.com \| bash # should exit 0 tirith check -- curl -fsSL https://vendor-not-listed.com \| bash # should still exit 1 with curl_pipe_shell ``` Both checks together confirm the allowlist took effect *and* didn't accidentally widen the policy. ## Quieting a noisy rule When a rule fires mostly on legitimate traffic, lower its severity instead of disabling tirith or allowlisting around it: ```yaml severity_overrides: lookalike_tld: LOW ``` At paranoia 1–2, only Medium+ findings surface, so LOW keeps the rule in the audit log without interrupting. `tirith warnings` and `tirith doctor`'s detection-coverage block still count it. `tirith explain --rule <id>` documents any rule (`--list` enumerates them), and `tirith policy tune --from-audit` suggests changes from the log. ## Anti-patterns for the allowlist - **Don't allowlist broad CDNs.** `raw.githubusercontent.com`, `gist.githubusercontent.com`, `cdn.jsdelivr.net`, `s3.amazonaws.com`, `*.vercel.app` — anyone can host arbitrary scripts on these. Allowlisting them gives a security tool a wide blind spot. Use download-read-run, or a URL-scoped `tirith trust add <host>/<path>`, for one-off scripts hosted on shared infrastructure. - **Don't allowlist subdomains preemptively.** Add what you actually use, not what you might use someday. - **Don't allowlist as a way to silence noise.** If tirith blocks something repeatedly that you don't actually trust, the right move is to stop running that command, not to suppress the warning. ## Verification ritual after any config change Run all four: ```bash tirith policy validate # 0 errors, 0 warnings tirith doctor # hook status: configured / policies: <path> tirith policy test '<a known-blocked cmd>' # action: Block — rules still fire tirith policy test '<an allowlisted cmd>' # action: Allow — the change took effect ``` `tirith doctor` alone is not sufficient — it reports config detection, not rule behavior. `tirith policy validate` is the only check that catches misspelled fields: tirith ignores unknown keys with a warning, so `allow_bypass:` (the real key is `allow_bypass_env`) or `version:` (the real key is `schema_version`) silently do nothing. `tirith policy effective` prints the fully resolved policy with defaults filled in. To test a candidate policy without touching the live file, point `TIRITH_POLICY_ROOT` at a directory holding `.tirith/policy.yaml` and run `tirith policy test` with it set. ## After a brew upgrade `brew upgrade tirith` may re-materialize hook source files. The shell profile line stays put, so usually nothing breaks, but verify: ```bash tirith --version tirith doctor ``` If `hook status` ever drops back to `NOT CONFIGURED` after an upgrade, re-run `eval "$(tirith init --shell zsh)"` and confirm the profile line is still present. Do not blindly append a duplicate. ## Reading the audit log ```bash tail -20 ~/.local/share/tirith/log.jsonl | jq . # last 20 events tirith why # explains last triggered rule tirith receipt last # last `tirith run` receipt tirith receipt list # all receipts ``` The log only stores redacted command previews — not full commands, env vars, or file contents. Disable logging entirely with `export TIRITH_LOG=0`. ## Per-project policies For client work that needs stricter rules than the global config, drop a `.tirith/policy.yaml` at the project root. Tirith walks up from the current directory and uses the first match. A repo-scoped policy is **tightening-only**: weakening fields such as `allowlist` are ignored with a notice, so a cloned repo cannot loosen your protection. Loosen at user scope (global policy or `tirith trust add --scope user`). `tirith policy effective` shows which fields were neutralized. ## Inherent gotchas - **Profile edits affect new shells only.** After modifying the shell profile, open a fresh terminal tab or `source ~/.zshrc`. The current shell will not pick up the change. - **`tirith check -- <cmd>`** — the `--` is required. Without it, flags on `<cmd>` (e.g., `-sSL`) get parsed as tirith's own flags. - **Shell quoting matters in `tirith check`.** Pipe characters and parens need escaping (`\|`, `\(`) since the command is parsed by your shell first. - **`fail_mode: open`** allows commands through when tirith itself errors internally. Use `fail_mode: closed` only in environments where blocking on parser errors is acceptable. - **License key absence is normal.** OSS rules work without one; only paid features (e.g., team audit) require activation. ## What this skill deliberately does not encode - **The current allowlist contents** — read `~/.config/tirith/policy.yaml` directly. - **The current tirith version** — `tirith --version`. - **Whether the hook is currently configured** — `tirith doctor`. - **Specific zshrc line text** — `tirith init --shell zsh` always prints the current correct line; pipe its output rather than copy-pasting from anywhere. The skill is a stable operating manual. Live state is queried at runtime.
Voir sur GitHub