Skip to content

Security

Threat model

Tyr defends against:

  • AI coding agents reading credentials or source they shouldn’t.
  • Unsanctioned shell execs triggered by LLM output.
  • Silent egress to unapproved LLM providers or arbitrary domains.
  • Drift between the in-kernel verdict and policy intent (detected server-side).

Tyr does not defend against:

  • An attacker with root + CAP_BPF on your host who can detach tyrd’s programs.
  • Kernel-module-level compromise.
  • A compromised tyr-server — if the server is rooted, attackers can push any policy.

Authentication

Human operators → server (REST)

  • Passwords stored with argon2id (memory_cost=19456, time_cost=2, parallelism=1, per OWASP 2024).
  • Successful login yields a JWT HS256 with 24-hour TTL.
  • JWT signing key is stored in $TYR_DATA_DIR/jwt.key — generated on first boot, regenerated by deleting the file.

Rotating the JWT key:

Terminal window
sudo systemctl stop tyr-server
sudo rm /var/lib/tyr/jwt.key
sudo systemctl start tyr-server # generates a fresh key

All existing tokens are invalidated; users re-login.

Agents → server (gRPC)

  • First boot: Register RPC with a one-time enrollment token (stored argon2id-hashed).
  • Server signs the agent’s CSR and returns a client certificate.
  • Every subsequent connection uses mTLS with that certificate.

Revoking an agent:

Terminal window
# Delete the daemon record — its cert will be rejected on next heartbeat
tyr agent list # find UUID
# use REST or UI to delete daemon by ID

A revoked agent can re-enroll with a fresh token.

CA key protection

$TYR_DATA_DIR/ca.key is the root of agent identity. Loss = all agents must re-enroll.

Recommendations:

  • Back up ca.key out-of-band on server install (encrypted).
  • Run the server on disk-encrypted volumes.
  • Restrict ca.key to mode 0600, owned by the server user.

Future: HSM / KMS integration is tracked as a roadmap item.

Network

  • REST (:7701) — TLS by default. TYR_REST_NO_TLS=true only for behind-proxy deployments.
  • gRPC (:7700)always mTLS. Cannot be disabled.

Place the REST port behind a TLS-terminating reverse proxy (nginx, Caddy, Traefik) if you want:

  • Let’s Encrypt certs
  • Rate limiting
  • IP allowlists

Expose gRPC directly — the mTLS + client cert check is the sufficient security control.

Rotating enrollment tokens

Treat them like OTPs. Workflow:

  1. Set short TTLs (--expires-hours 24 for single-install sessions).
  2. Set --max-uses tight (1 for one-off, N for a known-size fleet).
  3. Revoke (delete record) when done if uses remain.

Policy as the blast-radius limit

Even if a misclassified AI agent evades identification, Tyr’s base policy applies to the daemon — not to the AI type. A strict base policy gives you defense-in-depth against detection errors.

Drift detection as a tamper signal

Every event is re-evaluated server-side. Persistent drift from a single agent (kernel allowing what server says to deny) is a strong signal that the agent is tampered or out-of-sync. Alert on drift_detected = true counts per agent.

Reporting vulnerabilities

See SECURITY.md. Private disclosure via GitHub security advisories.