A small binary that runs where your data lives.
PREVIEWThe agent is the only Go component in TillDev — a single static, stdlib-only binary that runs in your (or our) environment. It claims jobs, drives the engines locally, encrypts client-side, and reports signed manifests. It caches its policy, so it can execute a pre-authorized failover even if the control plane is unreachable.
Claim, run, sign, report
The control plane never touches your backup bytes — the agent does. It registers with an Ed25519 public key, polls for pending jobs, claims one atomically, and runs the loop below. Backup data is encrypted inside the agent before it leaves your environment; the control plane only ever receives a hybrid-signed manifest and an integrity result.
┌─ heartbeat ────────────────────────────────────────────────┐
│ register (Ed25519 pubkey) → heartbeat → CLAIM a job │
│ │ │
│ ┌──────────────────────────┴───────────┐ │
│ backup restore/verify │
│ │ │ │
│ run engine (argv-only) VERIFY manifest signature │
│ encrypt CLIENT-SIDE │ ✗ → refuse: the │
│ stream ciphertext → target │ engine never │
│ │ │ runs (red) │
│ sign manifest (Ed25519+ML-DSA-65) │ ✓ │
│ │ run engine restore │
│ report ─────────────────────────▶ report + integrity result │
└──────────────────────────────────────────────────────────────┘
no decrypted credential ever transits this channel (Phase 1)Build and run
Because the module has zero third-party dependencies (AES-256-GCM and Ed25519 come from Go’s standard library), it builds and runs with no network — the right shape for a self-hosted or air-gapped, always-on daemon.
# Build a single static binary (stdlib-only → no network, no go.sum).
GOPROXY=off go build -o ark-agent ./cmd/ark-agent
# Run it against your control plane.
TILLARK_CP_URL=https://ark.example \
TILLARK_AGENT_TOKEN=tark_… \
TILLARK_ENGINES=restic \
./ark-agentEnvironment variables
| Variable | Meaning |
|---|---|
TILLARK_CP_URL | Control-plane base URL. HTTPS only. Required. |
TILLARK_AGENT_TOKEN | The tark_… bearer token the agent authenticates with. Required. |
TILLARK_ENGINES | Comma list of engines this agent may drive (default restic). |
TILLARK_AGENT_DATA_DIR | Where the signing key and the cached policy live (path-traversal-safe). |
TILLARK_POLL_INTERVAL_MS | How often to poll for pending jobs. |
TILLARK_HEARTBEAT_INTERVAL_MS | How often to heartbeat + refresh cached policy. |
TILLARK_ALLOW_INSECURE_LOCAL | Set 1 to permit a localhost http control plane — local dev only. |
Mint the token with tilldev ark tokens create --scope operator (an agent needs operator to claim and report). The secret is shown once and stored sha256-hash-only.
Security properties
The agent connects to user-named engines and endpoints and shells out to binaries — exactly the surfaces an attacker probes. Each is closed by construction, and each property is unit-tested (including against a real subprocess for exec, and a live cross-language crypto vector):
| Property | How |
|---|---|
| Argv-only exec (CWE-78) | A real subprocess with an argv array — never a shell. NUL-byte rejection, output cap, timeout-kill, and a minimal env allowlist so the engine never inherits the agent’s secrets. |
| SSRF-safe (CWE-918) | Target / replica URLs are validated and the resolved IP is pinned — a public name resolving to link-local / metadata is refused. DNS rebinding is closed. |
| Client-side AEAD | Data is AES-256-GCM encrypted in the agent before upload; the storage vendor sees only ciphertext. |
| Signed manifests | Ed25519 now (ML-DSA-65 registered), byte-compatible with the control plane’s envelope — either side reads the other’s ciphertext. |
| HTTPS-only channel | The control-plane client refuses an https→http downgrade or cross-host redirect, so the tark_ token can’t reach a cleartext or foreign endpoint. No decrypted credential transits this channel in Phase 1. |
| Autonomy, safely | The offline policy cache drives a pure failover-guardrail decision (quorum, confirmation window, staleness bound, anti-flap) and defers entirely while the control plane is reachable. |
The Phase-1 boundary
The command construction (argv), signing, verification, SSRF guarding, and autonomy logic are real and tested today. The actual engine subprocess run, object-storage streaming, --json parsing, and content hashing land at vendor wireup — the deliberate last step.
ErrExecutorNotProvisioned rather than fake a green backup. The one unforgivable bug in a backup product is a false success — so the agent refuses to claim one.See Architecture for how the agent fits the control plane, Security for the crypto details, or the CLI reference. Back to the TillArk overview.