TILLARK · PII-SCRUBBED CLONES

Last night's data, safely on a dev box.

BETA

Teams need realistic data to build and test against — and reach for a copy of production, which is how real customer PII ends up in staging, laptops, and screenshots. TillArk already holds a clean, recent copy of your data, so it can hand you a masked, prod-like clone instead: same shape, same volume, no real PII, gone by morning.

01How it works

Restore to scratch, mask in place, prove it

A clone rides the same verify-before-trust restore rail as a recovery — but into a throwaway scratch target, never one of your registered sources, so it can never touch production. Once the bytes land, the masker rewrites every PII column in place and records exactly what it did.

text
tilldev ark clone create --backup <id> --profile standard --ttl 4h
        │
        ├─▶ enqueues a restore (kind=clone) into a SCRATCH target
        │      (synthetic, ephemeral — never one of your registered sources)
        ├─▶ agent verifies the signed manifest, restores the bytes to scratch
        ├─▶ the masker scans the schema and applies @tilldev/scrub-core's plan:
        │      email/phone/name ─▶ deterministic fake   (joins still work)
        │      national-id/mpesa ─▶ keyed pseudonym      (referential integrity)
        │      card / secret     ─▶ redact / null        (never fabricated)
        │      free-text columns ─▶ value-scrubbed       (embedded PII swept)
        └─▶ clone goes READY with a proof of every column it masked
              └─ auto-expires at its TTL; teardown is guaranteed
One source of truth for PII rules
The masker uses @tilldev/scrub-core — the same rule set as the SDK on-device scrubber and the server-side ingest filter. M-Pesa transaction ids, national IDs (SA / Nigerian NIN · BVN), phone numbers, emails and cards are recognised identically everywhere, so the rules can never drift apart.
02Masking

The right transform per column

Masking isn’t one hammer. The planner classifies each column (by name and by the shape of its values) and picks a transform that keeps the clone usable while making the real value unrecoverable:

ColumnTransformWhy
email · phone · namedeterministic fakeSame input → same fake within the clone, so app logic and joins still work — but the real value is gone.
national-id · M-Pesa refkeyed pseudonymHMAC under a per-clone salt: referential integrity is preserved, reversal is not (and the salt isn’t stored with the data).
card · secretredact / nullNever fabricated — a card number or credential is removed outright.
notes / free-textvalue-scrubSwept with the same pattern rules, so PII embedded in a comment field is caught too.
ids / foreign keys / metricspassthroughNon-PII is left intact so the dataset stays realistic.
text
standard   mask detected PII, scrub free-text        ← the default
strict     also NULL national-ids, addresses, DOB    ← maximum safety
none       no masking — REAL PII                      ← four-eyes + admin only
03Guardrails

Ephemeral, scoped, and audited

  • Auto-expiring. Every clone carries a bounded TTL (default 1h, max 24h). It is torn down at expiry — a clone is never a place stale PII quietly accumulates.
  • Scratch-only. The destination is a synthetic, ephemeral ref — validated to never be a registered source, so a clone can’t clobber production.
  • Proof of masking. Every clone lists the columns it neutralised, so a reviewer can confirm no real PII shipped — surfaced on the clone card and in tilldev ark clone show.
  • Raw clones are gated. A --profile none (real-PII) clone — for forensic recovery — requires admin scope and a four-eyes approval, and is marked as production data everywhere it appears.
Control plane today, masked bytes with the agent
The clone API, the masking planner, the scratch-target guard, the TTL, and the dashboard are live in beta. The in-place column rewrite runs on the agent execution phase (like every other engine body) — which is the deliberate last step of the build, wired with the storage vendors.

Create one from the CLI, or read how the ransomware canary uses the same byte-level view. Back to the TillArk overview.