TILLARK · POLICY FILES

Every policy in one file you can review.

A policy file declares how your sources are protected: schedules, retention, where copies may land, recovery objectives and verification. Keep it next to your code, review a change like any other, and see exactly what it does before anything changes. A plan applies whole or not at all, and every change lands in the audit log.

01The file

Say only what you mean to set

A file has a version and a list of policies. Each entry names a registered source and, when a source has more than one policy, the policy’s name (it is default when left out).

yaml
# yaml-language-server: $schema=https://tilldev.dev/schemas/tillark-policies.v1.json
version: 1
policies:
  - source: orders-db            # a registered source, by name or id
    schedule: "0 */6 * * *"      # UTC
    rpo: 7h30m
    retention:
      daily: 14
      monthly: 12
    placement:
      residency: eu
      copies: 2

  - source: ledger
    name: pitr                   # a second policy on the same source
    rto: 15m
    verify:
      cadence: "0 4 * * *"
  • A setting the file leaves out stays as it is. An entry for a policy that exists changes only what it gives; an entry for a new one starts from the defaults in the settings table.
  • Durations take seconds or units: 15m, 1h30m, 2d. Schedules are 5-field cron expressions in UTC.
  • YAML or JSON. The first line above points your editor at the file’s JSON Schema, so it completes keys, explains each one and marks mistakes as you type.
02Plan, then apply

See the change before it happens

bash
tilldev ark export -o policies.yaml       # every policy as it stands
# edit policies.yaml, then:
tilldev ark plan policies.yaml            # what it would change; changes nothing
tilldev ark apply policies.yaml           # shows the plan and asks before applying

A plan lists what the file would create (+), change (~, each setting from its current value to the new one) and remove (-). Policies the file doesn’t mention are listed and kept.

text
$ tilldev ark plan policies.yaml
Plan: 1 to create, 1 to change.
  ~ orders-db / default
      retention.daily   7 → 14
      placement.copies  1 → 2
  + ledger / pitr  new
      rpo               5m
      rto               15m
      verify.cadence    0 4 * * *

Not in the file, so kept (--prune removes them):
    orders-db / weekly

A change that weakens protection is flagged under its policy, so it can’t slip through review: one that keeps fewer backups, asks for fewer copies, lets a copy sit with the source’s provider or in its region, lets copies share credentials, changes where copies may be kept, loosens the recovery-point objective, or stops backups, scheduled verification, proving older backups, reading the repository’s data or pausing on a canary alarm.

On the dashboard, the Policy file panel on the Policies page does the same: load the current policies or open a file, plan it, and apply the plan.

03Problems

Refused, with the line that has it

A file with a problem is never applied, in part or at all. Each problem points at its line and column, and a misspelt key comes with the one you probably meant.

text
$ tilldev ark plan policies.yaml
policies.yaml:8:7  policies[0].retention.dayly: unknown key; did you mean "daily"?
That problem stops the file from being applied; nothing was changed.

A file is refused when it:

  • names a source that isn’t registered, or declares the same policy twice;
  • has a key TillArk doesn’t know, or a value outside what a setting takes;
  • keeps nothing: every retention count at 0;
  • gives a schedule that leaves longer between backups than the RPO objective allows. Changing an existing policy’s schedule? Give rpo with it.
04Apply

Every change or none

  • Planned again on apply. TillArk plans the file again against the policies as they are when you apply, in one transaction. If a policy the plan acts on has changed since, say someone edited it on the dashboard, nothing is applied and you are asked to plan again.
  • Reviewed plans stay reviewed. plan -o plan.json saves the plan with its file. apply plan.json applies exactly that, without a prompt, and only while nothing it acts on has changed.
  • Audited. Each change is an entry in the hash-chained audit log, with the settings it changed and the plan it came from.
  • Who can apply. Anyone in the workspace can plan. On the dashboard, applying needs an owner or admin. With a tark_ token, operator can create policies from a file, and changing or removing them needs admin.
bash
# In review: record the plan with the change.
tilldev ark plan policies.yaml -o plan.json --detailed-exitcode
#   exit 0: nothing to change · 2: changes · 1: a problem in the file

# After approval: apply exactly the plan that was reviewed.
tilldev ark apply plan.json
Removing policies
Policies the file leaves out are kept unless you pass --prune (or tick the box on the dashboard). Prune only removes policies on the sources the file names, and a removed policy’s backups stay restorable.
05Reference

Settings

Every setting a policy takes, and where a new policy starts when the file leaves it out. A new policy’s rpo follows its schedule: the longest gap between backups plus time for the backup to run (1h15m for hourly), or 5m when the source streams WAL.

SettingMeaningNew policy
enabledfalse stops this policy’s backups and verifications; backups already taken are kept.true
scheduleWhen backups run: a 5-field cron, in UTC.0 * * * *
retention.lastThe most recent backups kept.7
retention.hourlyOne backup per hour, for this many hours.24
retention.dailyOne backup per day, for this many days.7
retention.weeklyOne backup per week, for this many weeks.4
retention.monthlyOne backup per month, for this many months.12
retention.yearlyOne backup per year, for this many years.3
placement.different_providerKeep copies with a provider other than the source’s.true
placement.different_regionKeep copies in a region other than the source’s.true
placement.residencyWhere copies may be kept: a residency zone such as eu, or global.global
placement.copiesCopies of each backup, each in its own failure domain.1
placement.separate_credentialsKeep each copy under a different target credential domain.false
rpoThe most data a restore may lose. It must cover the schedule’s longest gap, unless the source streams WAL. 0 sets no objective.from the schedule
rtoHow long a restore may take.1h
verify.cadenceWhen restores are verified: a 5-field cron, in UTC, or off.0 6 * * *
verify.spreadHow long after each slot verifications may start; each policy keeps its place.1h
verify.older_everyEvery nth scheduled verification proves the older kept backup proven longest ago; 0 never.4
verify.read_partsParts a restic repository’s data is read in, one per scheduled verification; 0 never.30
incrementalBetween full backups, pgBackRest and WAL-G sources take differential (changes since the last full) or incremental (changes since the last backup) ones; off takes a full every time. restic always stores only what changed.off
full_everyHow often a policy with incremental on takes a full backup.7d
pause_on_alarmPause the source when its ransomware canary raises an alarm.false
06API

From your own tooling

The CLI and dashboard use these endpoints. They take the file as JSON, up to 1 MB; send the digest of the plan you reviewed so apply refuses anything else.

text
GET  /api/ark/policies/export    → { "document": "<policies.yaml>" }
POST /api/ark/policies/plan      { "document": {…}, "prune": false }
                                 → { "plan": { changes, unlisted, summary, issues, digest } }
POST /api/ark/policies/apply     { "document": {…}, "prune": false, "digest": "sha256:…" }
                                 → { "applied": [...], "plan": {…} }

Request and response shapes are in the API reference.


See Backups & retention for what each setting does, and the CLI reference for the per-policy commands. Back to the TillArk overview.