Your first policy
By default, Tyr runs deny-by-default with no policies assigned — meaning unless you ship rules, every governed action is denied. This guide walks you through applying a starter policy, assigning it, and observing evaluation.
1. Look at the example policies
The repo ships two starter policies:
examples/policies/default-policy.yaml— alert-only. Lets everything through but flags sensitive activity.examples/policies/strict-policy.yaml— deny-by-default with explicit allow lists.
Start with the default:
# examples/policies/default-policy.yaml (excerpt)apiVersion: tyr.dev/v1kind: Policymetadata: name: tyr-defaultspec: rules: - name: alert-sensitive-file-writes action: file_write resource_pattern: "/etc/*" verdict: alert severity: high - name: alert-process-execution action: exec verdict: alert severity: medium2. Log in and apply it
-
Log in to the server:
Terminal window tyr --server https://localhost:7701 login --username admin# prompts for passwordThis stores a JWT in
~/.config/tyr/token. -
Apply the policy:
Terminal window tyr policy apply -f examples/policies/default-policy.yamlOutput:
✓ Applied policy version 1 (tyr-default)The server parsed the YAML, compiled it to Cedar + BPF map entries, and stored it as immutable version 1.
-
Assign it to your agent:
Terminal window tyr agent list# find the agent_id of "docker-host" (or your host name)tyr policy assign \--target-type daemon \--target-id <agent_id> \--version 1Within a few seconds, the agent receives the updated policy over gRPC and hot-reloads it in-kernel — no restart.
3. Observe
Tail live events:
tyr audit tailThen run something triggering a rule on the monitored host:
# on the host where tyrd is runningecho test | sudo tee -a /etc/tyr-test.txtYou should see:
2026-04-20T10:45:02Z alert file_write /etc/tyr-test.txt pid=12345 teeThe event is also visible in the web UI at http://localhost:7701.
4. Go strict
When you trust your rules, apply the strict policy:
tyr policy apply -f examples/policies/strict-policy.yamltyr policy assign --target-type daemon --target-id <agent_id> --version 2Now a file_write to /etc/* returns EPERM — the syscall fails at kernel level. The event is still captured with verdict deny.
Verdict pipeline
flowchart TD Sys(["AI process syscall"]) --> Hook["eBPF LSM hook<br/>/ tracepoint"] Hook -- allow --> Proceed["syscall proceeds"] Hook -- deny --> Eperm["syscall returns EPERM"] Hook -- alert --> Proceed2["syscall proceeds + event emitted"] Hook --> RB[["ring buffer"]] RB --> US["tyrd userspace<br/>(Cedar evaluate for richer rules)"] US -- "gRPC / mTLS" --> Srv["tyr-server<br/>persist, drift-check, SSE"]→ Next: Writing policies · Policy YAML reference