Installation
Tiyi is a single Go binary. Pick a build path, drop the binary on your host, write a small YAML config, and choose the operational mode that matches the role this host should play in the cluster.
Build from source
From a fresh checkout of the Tiyi repo:
$ make proto # regenerate Connect Go + Protobuf Go from proto/
$ make web # build the Vben Admin frontend into web/dist/
$ make build # compile bin/tiyi with the frontend embedded
For a release artifact, use the guarded one-shot target. It refuses a dirty worktree, verifies the embedded vendor-license public-key fingerprint, rebuilds proto/frontend outputs, and produces the same single binary:
$ make release
Build inputs:
- Go 1.25+ — the module floor. Pure-Go SQLite via
modernc.org/sqlitemeans no CGo and clean cross-compilation. - Node 20+ and pnpm 9+ — for
make web. The output is embedded withgo:embedat the nextmake build. - buf — bundled at
tmp/buf/bin/buffor proto regeneration. Runmake prototo refresh generated Connect/PB Go after editingproto/tiyi/v1/*.proto.
Prebuilt binaries
Tiyi is one signed binary — free and full-featured on a single node. The canonical install script is published at https://www.tiyisec.com/install.sh:
$ curl -fsSL https://www.tiyisec.com/install.sh | bash
$ tiyi --version
tiyi v3.0.0-rc.1-57-gf297a22 linux/amd64
The script downloads the platform-matched binary, verifies its SHA-256 against the manifest, and drops it into /usr/local/bin/tiyi. linux/amd64 and linux/arm64 are first-class targets.
Bootstrap an agent from a running server
A running Tiyi server exposes GET /download/tiyi, an unauthenticated endpoint that streams the running binary. Use it to bootstrap agents on fresh machines:
$ curl -fsSL -o /usr/local/bin/tiyi http://primary:8080/download/tiyi
$ chmod +x /usr/local/bin/tiyi
For cross-platform downloads, append ?os=linux&arch=arm64 to serve an imported binary release instead of the running binary.
Config file
Tiyi reads a Koanf-based YAML config. Start from this minimal config and let the defaults handle the rest:
# /etc/tiyi/tiyi.yaml
api:
addr: "0.0.0.0:8080"
storage:
state_db: "/var/lib/tiyi/state.db"
crypto:
kek_file: "/etc/tiyi/kek.bin" # 32-byte at-rest encryption key
auth:
jwt_secret: "<32+ random bytes>" # HS256 signing secret
proxy:
http_addr: ":80"
https_addr: ":443"
caddy_admin_socket: "/var/lib/tiyi/caddy-admin.sock"
Pass it with --config:
$ tiyi standalone --config /etc/tiyi/tiyi.yaml
Two fields are mandatory before going live. crypto.kek_file and auth.jwt_secret have dev-friendly fallbacks that explicitly do not survive a restart. See Deployment → Production hardening for the contract.
Operational modes
The same binary exposes five subcommands. Pick the one that matches the host's role:
standalone- Master + agent in one process. Default for single-host installs. Mutations RW; data plane proxies on the same node. Five-minute install path.
server- Cluster control-plane leader plus its own embedded agent. Accepts agent registrations, serves the API and dashboard, proxies traffic.
secondary- Warm CP replica plus its own embedded agent. Read-only API, proxies traffic, gets promoted manually on failover with
tiyi promote. agent- Pure data plane: Caddy + Coraza receiving signed config bundles from the primary over a long-lived gRPC stream. No CP responsibility.
dashboard- UI-only mode for split deployments where the dashboard host doesn't proxy traffic.
Enrolling an agent
Agents enroll with a one-use token issued by the primary. From the primary host:
$ TOKEN="$(tiyi agents issue-token --tag edge-c | jq -r .token)"
On the agent host, with the binary already in place:
$ tiyi agent \
--api http://primary:8080 \
--enrollment-token "$TOKEN" \
--state-dir /var/lib/tiyi/agent \
--proxy-http-addr 0.0.0.0:80 \
--proxy-https-addr 0.0.0.0:443
The token is consumed on first contact. After enrollment, the agent persists its identity in <state-dir>/identity.json and the token is no longer needed. Lose the state directory and you'll need a fresh token to re-enroll.
systemd unit
For a long-lived deployment, run Tiyi under your init system. A minimal systemd unit:
# /etc/systemd/system/tiyi.service
[Unit]
Description=Tiyi WAF
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=tiyi
Group=tiyi
ExecStart=/usr/local/bin/tiyi server --config /etc/tiyi/tiyi.yaml
Restart=on-failure
RestartSec=2s
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/tiyi /etc/tiyi
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
What to read next
- Domain model — what sites, upstreams, certs, policies, and agents are.
- CLI reference — every
tiyisubcommand grouped by resource. - Deployment — production hardening, HA failover, SIEM egress.