learn-cyber-security-with-phoebe / Builder session 6 of 8
Learn Cyber Security with Phoebe · Builder session 6 of 8

Destructive events

Everything so far has been about the customers table being read. Tonight it is about the table being gone. Time travel, snapshots and retention windows are features of the warehouse account, and whoever holds the admin login holds them too: drop the twelve tables, purge the recovery window, and there is nothing left to restore from before the ransom note arrives. On Ironwood's bench, recoverable tables read zero of twelve at every rung, including the one where every prevention control is on. You will build the one thing that moves that number: a nightly copy in an account the admin does not hold, locked so nobody can delete it before its retention ends, and restored once, timed, to prove it is real.

🟠 Advanced Platform and analytics engineers 45 min
0-3 · Welcome 3-20 · What the admin login can destroy 20-40 · Build-along: one immutable copy, one restore drill 40-45 · Q&A
Part 0

Where session 6 sits on the ladder

Five sessions have taken Ironwood from nine paths to three, and session 5 made all three visible. The third number on the bench has not moved once: recoverable tables, 0 of 12, at nothing on, at MFA, at rotation, at the private bucket, at pinned dependencies, at logging. Tonight's control, immutable, restore-tested backups, takes it to 12 with the path count still at three. It is the second rung on the ladder that moves no headline number and changes everything about Monday.

Live = presented in the 45 minutes Self-study = the full depth, after class 🔍 Every diagram zooms

★ What you walk out with tonight. A nightly export of the crown jewels to a bucket in an account your warehouse admin cannot log in to, with object lock or its equivalent so the copy cannot be deleted before its retention ends. Proof, from the admin credential itself, that the delete is refused. One restore into a scratch schema, timed and dated. And the "closed by" column of your inventory file filled in for the one edge that leads to the backups.

LiveWhy every prevention control leaves this number at zero3 min▶

MFA stops the admin login being phished. It does not change what the admin login can do once somebody holds it, whether that is an attacker who got past MFA, a contractor whose access outlived the contract, or the admin themselves on a bad day. Prevention shrinks the number of ways to the admin login; it never shrinks what the login reaches. And on Ironwood's graph the admin login reaches the backups, because the backups are the account's own time travel and snapshots.

That is why the bench shows recoverable at zero all the way up to the logging rung, and why the "all prevention, no detection" over-correction still shows twelve: it includes immutable backups. Recovery is a property of where the copy lives and who can delete it, not of how hard the front door is to open.

Real world

Ironwood's backup answer on the security questionnaire read "warehouse time travel, 7 days, plus weekly snapshots". Both were held by the same account that held the tables. A phished admin credential, used once, could have dropped the twelve tables and reduced the retention window to zero in the same session. Nothing on the questionnaire was false. Nothing on it was a backup either.

Self-studyThe vocabulary for tonight3 min▶
  • Time travel - the warehouse's ability to query or restore a table as it was at an earlier point inside a retention window. Superb for undoing a mistake. Held by the account.
  • Snapshot - a point-in-time copy of a table or database inside the same platform. Also held by the account, also subject to the account's retention settings.
  • Retention window - how far back time travel or snapshots reach. An account setting. Whoever can change the setting can shorten it to nothing.
  • Immutability, object lock - a storage setting that makes an object undeletable and unmodifiable until its retention period ends, by anyone, including the account's own administrators. The cloud providers each name it differently; the property is the same.
  • Separate account - a second cloud account or project whose credentials the warehouse administrator does not hold. The copy lives there.
  • Restore drill - actually restoring a copy into a scratch location, on a schedule, and timing it. The only proof a backup exists.
  • Recoverable - the bench's third number: whether an attacker who reaches the admin login can also destroy the copy you would restore from. Twelve tables, all or nothing.
Part 1 · covers what the admin login reaches, the ransomware pattern on data, and the canon 0 to 12

Time travel goes with the account

9 min live

The professional rule is short: a copy the same account can delete is a copy, not a backup. Time travel, snapshots and retention windows are excellent tools for undoing your own mistakes and useless against anyone who holds the admin login, because the login that can drop the table can also purge the window that would have brought it back.

One account holds everything admin login warehouse, 12 tables DROP time travel, snapshots purge retention held by the same account, gone in the same sitting recoverable 0 of 12 A copy the login cannot reach admin login warehouse, 12 tables DROP still works separate account, no admin login here object-locked nightly copy retention set, delete refused no delete right recoverable 12 of 12 Paths to the crown jewels stay at 3 on both sides. Only the right-hand estate has a Monday.
🔍 Click to zoom - the same admin login on both sides; only the right side has a copy it cannot reach.
LiveWhat the admin login reaches, in order3 min▶
  • The twelve tables. A drop is one statement per table, or one per schema. Seconds.
  • The retention window. Time travel and snapshot retention are account or object parameters, and the admin role sets them. Reducing retention to its minimum, or dropping the objects that hold the snapshots, purges the recovery window that the drop would otherwise have been undone from.
  • The warehouse-side export jobs. If your nightly copy is written by a job that the same admin controls, to a bucket the same account owns, the job can be stopped and the bucket emptied from the same seat. The copy has to live where the admin cannot follow it.
  • Not the object-locked copy in a separate account. This is the only item on the list the login does not reach, and it is the whole of tonight's control. The admin can still drop every table; on Monday morning the twelve tables come back from a copy the drop never touched.
LiveThe ransomware pattern on data, and the canon3 min▶

Ransomware against a data estate follows one shape: drop or encrypt the tables, purge whatever the account can reach that would restore them, then demand. The second step is the one that decides whether the third step has any leverage. An estate whose only recovery is the account's own time travel has handed the attacker both the tables and the undo button.

On the bench, recoverable tables read 0 of 12 at every rung from nothing on through query logging, and 0 at the "perimeter firewall only" over-correction too. Immutable, restore-tested backups take it to 12 with paths still at three and undetected still at zero. The path count is untouched because the copy removes no way in; it removes the admin-to-backups edge, which was never a path to the crown jewels. It was the path to Monday.

Ransomware does not need to exfiltrate to hurt you. A ransom note for the return of your own customers table works even if not one row left the building. Exfiltration detection in session 5 and recovery tonight are two different defences against two different endings of the same intrusion.

Self-studyWhy a copy the same account can delete is a copy, not a backup3 min▶

The test is one question: can the credential that can destroy the original also destroy the copy? If yes, the copy protects against hardware failure, bad deploys and accidental deletes, all of which are real and worth protecting against. It protects against nothing that holds the admin login, because whatever dropped the table can delete the copy in the next statement.

Kind of copyProtects againstHeld by the admin login?Counts as recoverable on the bench?
Time travelYour own mistakes inside the windowYes, including the windowNo
Snapshot in the same accountMistakes, bad deploys, some corruptionYesNo
Nightly export to a bucket the warehouse account ownsPlatform outage, mistakesYes, via the bucketNo
Export to a separate account, deletable thereEverything above, plus a compromised warehouse admin, until the second account is also compromisedNo, but its own admin can delete itNot yet
Object-locked copy in a separate account, restore-testedAll of the above, including anyone who holds either accountNo, and nobody can delete it earlyYes: 12 of 12

The fourth row is the one teams stop at, and it is nearly right. A separate account whose own administrator can still delete the copy has moved the problem, not removed it. Object lock is what turns a second account into a backup: the delete is refused for everyone until the retention period ends.

Part 2 · covers the three properties, the cost of immutability, what to back up, and the drill

Immutable, separate, restore-tested

8 min live

A backup that counts has three properties, and a copy that lacks any one of them is a hope with a storage bill. It cannot be deleted before its retention ends, by anyone. It lives in an account the warehouse administrator does not hold. And it has been restored, actually restored, into a real schema, and somebody wrote down how long it took.

nightly copy cannot be deleted object lock, or the platform's equivalent until retention ends, by anyone at all separate account the warehouse admin has no login here and the bucket policy refuses its delete restored in a drill last night's copy, into a scratch schema, row count checked, timed and dated drill date Fail any gate and it is a copy with a storage bill, not a backup. The output is a date, not a setting. A backup that has never been restored is a hope.
🔍 Click to zoom - three gates, one output: the date of the last restore that worked.
LiveThe three properties, and why each one is load-bearing3 min▶
  • Immutable. Object lock, or the storage platform's equivalent, with a retention period. Until the period ends the object cannot be deleted or overwritten by anyone, including the account's own root or owner. Without this, the second property only moves the problem to whoever administers the second account.
  • Separate. A different cloud account or project, with its own identities, that the warehouse administrator has no login to. The export job that writes the copy has write access to the destination and nothing else; the warehouse side can push and cannot list, read or delete. Without this, the warehouse admin credential reaches the copy through the account it already holds.
  • Restore-tested. Restored into a scratch schema on a schedule, with the row count compared to the source and the elapsed time written down. Without this, the first two properties protect a file that may not load, may be missing a table, or may take three days to bring back when the business expected three hours.
LiveThe honest cost of immutability2 min▶

A copy that nobody can delete for 30 days is a copy that you cannot delete for 30 days either. Your own mistakes, a copy that accidentally includes a column it should not, a table exported before a legal deletion request was honoured, all of them sit in the locked bucket until retention ends. That is not a flaw to engineer around; it is the property doing its job, and it is why the retention period is a governance decision with the data owner and whoever answers for privacy, not a platform default.

The practical shape: retention long enough that an intrusion discovered late still has a clean copy behind it, short enough that the storage cost and the deletion-request exposure are ones the business has agreed to. Thirty days is a common opening position. Write down who agreed and when.

Self-studyWhat to back up, and the drill as the only proof4 min▶

Not everything, nightly. Twelve tables at Ironwood, of which one is the incident and the rest can be rebuilt from source systems and pipelines if the definitions survive. The immutable copy carries the crown jewels and the metadata needed to rebuild the rest: table definitions, pipeline code, the grants, the inventory file. Copying every table every night into a locked bucket is a storage bill with a retention period; copying what cannot be rebuilt is a backup.

  • The crown jewels, full, nightly, in an open columnar format that any engine can read. The restore should not depend on the warehouse that was just dropped.
  • The definitions: DDL for all twelve tables, the pipeline repository at the deployed commit, the role and grant definitions. Small, and the reason the other eleven tables come back.
  • The inventory file itself, because after a destructive event it is the map of what existed.

The drill is the only proof. A backup that has never been restored is a hope with a storage bill. The drill is not a checkbox: it is a restore of last night's copy into a scratch schema, a row count compared against the source, and a stopwatch. The elapsed time is the number the business actually needs, because "we have backups" and "we can be back in four hours" are different promises. Do it monthly at first, quarterly once it is boring. The date of the last successful drill goes in the inventory file next to the edge it closes, and a drill date older than a quarter is a finding.

Real world

Ironwood's first restore drill loaded eleven of twelve tables. The twelfth, customers, failed on a column type the export had written one way and the restore read another. Nobody had known for eight months. The fix took an hour; discovering it during an actual incident would have cost the only table that mattered.

Build-along

One immutable copy, one restore drill

★ 20 min · everyone builds

Six steps, all against your own estate. The commands below are generic shapes: the unload statement, the object-lock setting, the bucket policy and the scheduler object all have platform-specific names, so substitute yours. Two of the steps need someone who can create a second cloud account or project; if that is not you, the step is a ticket with tonight's reasoning attached.

Export the customers table nightly to a bucket in a separate account. The destination account is one the warehouse admin has no login to. The credential the export uses can write to the destination prefix and nothing else: no list, no read, no delete. Use an open columnar format so the restore does not depend on the warehouse being alive.

★ Try it now -- run from the warehouse, nightly, by a scheduled job (task, job or DAG by platform) -- destination: a bucket in the BACKUP account, write-only credential, dated prefix copy into 'backup-bucket-in-separate-account/customers/dt=2026-09-08/' from customers credentials = ( <write-only credential for the backup prefix, held as a placeholder here> ) file_format = ( type = parquet ); -- alongside it, the definitions the other eleven tables are rebuilt from copy into 'backup-bucket-in-separate-account/ddl/dt=2026-09-08/' from ( select table_name, ddl from information_schema_ddl_view ) credentials = ( <REDACTED> ) file_format = ( type = parquet );

Enable object lock or the equivalent immutability setting, with a retention period. This is a bucket-level setting in the backup account, applied once, in compliance or governance mode rather than a mode any administrator can lift. The retention period is the governance decision from Part 2; 30 days is the opening position.

★ Try it now # in the BACKUP account, once, by its own administrator (the shape; the flags differ by provider) storage bucket create backup-bucket-in-separate-account --object-lock-enabled storage bucket set-retention backup-bucket-in-separate-account \ --mode compliance --retention-days 30 # compliance mode: no identity in the account, root or owner included, can shorten or remove it

Confirm the warehouse admin credential cannot delete the object. Prove it from the admin seat, not from the design document. The delete must be refused twice over: by the bucket policy, because the warehouse account has no delete right there, and by object lock, even for an identity in the backup account.

★ Try it now # as the WAREHOUSE admin credential (the one an attacker would hold) storage object delete backup-bucket-in-separate-account/customers/dt=2026-09-07/part-0.parquet # expected: access denied - the warehouse account has no delete right on this bucket # as an administrator IN the backup account, to prove the lock itself storage object delete backup-bucket-in-separate-account/customers/dt=2026-09-07/part-0.parquet # expected: refused - object is under a retention lock until 2026-10-07 # record both refusals, with the date, in the inventory file

If either delete succeeds, stop. You have a copy, not a backup, and the next three steps would be timing a restore from something an attacker could remove.

Perform a restore of last night's copy into a scratch schema, and time it. Restore into a schema that does not exist yet, so the drill cannot overwrite anything, and compare the row count to the source. The elapsed time is the number the business will ask for.

★ Try it now create schema restore_drill_2026_09_08; -- note the start time select current_timestamp as drill_started; create table restore_drill_2026_09_08.customers like customers; copy into restore_drill_2026_09_08.customers from 'backup-bucket-in-separate-account/customers/dt=2026-09-07/' credentials = ( <read-only credential for the backup prefix, placeholder> ) file_format = ( type = parquet ); -- note the end time, then prove the copy is whole select current_timestamp as drill_finished; select (select count(*) from restore_drill_2026_09_08.customers) as restored_rows, (select count(*) from customers) as source_rows; -- clean up once the numbers are recorded drop schema restore_drill_2026_09_08;

Record the restore date and elapsed time in the inventory file. The date is the control. A backup with no drill date on file is indistinguishable, on paper, from one that fails on the twelfth table.

★ The inventory file, recovery section # recovery backup_copy | customers + ddl, nightly, parquet, backup account, object lock 30d compliance delete_refused | 2026-09-08 by warehouse admin (policy) and by backup admin (lock), both recorded last_restore | 2026-09-08 | 12 tables of 12 | customers 1,204,311 rows = source | 41 min next_drill_due | 2026-10-08

Update the "closed by" column for the admin-to-backups edge. This is the one edge on the graph whose target is not the crown jewels, and until tonight its "closed by" cell said what it would take rather than what exists.

★ The inventory file, one row changed # from -> to | the move | closed by | seen by admin -> backups | DROP and purge, time travel included | object-locked copy in separate account, drilled 2026-09-08 | admin audit log

Put the drill on the calendar before anyone leaves. Monthly at first, with the same person restoring and the same file recording the time. The month the drill slips is the month the export format drifts, and nobody will know until the restore that matters.

Homework

Before session 7

30 min
  1. Answer the one question for every copy of your crown jewels you can find: can the credential that can drop the table also delete this? Write the answer next to each copy in the inventory file. Expect most of them to be yes.
  2. Find out who administers the account your backups live in, and whether that person also holds the warehouse admin login. If it is the same person, the separate account is separate on paper only.
  3. Find the date of your last restore drill. If there is no date, that is the finding, and it goes in the file as a blank rather than being left unrecorded.
  4. Write down the retention period you would propose, and the two people who need to agree to it: the data owner and whoever answers for deletion requests. Retention is their decision, informed by yours.
Check yourself

Three questions

Ironwood's warehouse has seven days of time travel and weekly snapshots. Why does the bench still show zero recoverable tables?

Time travel is excellent against your own mistakes and useless against whoever holds the admin login. A copy the same account can delete is a copy, not a backup. Recovery is about where the copy lives and who can delete it.

Immutable, restore-tested backups take recoverable tables from 0 to 12. What happens to the path count?

The admin-to-backups edge was never a path to the customers table. It was the path to Monday. Two rungs on the ladder move a number other than the path count, and this is the second.

A team exports customers nightly to a bucket in a separate account, but has never restored from it. Which property is missing, and why does it matter?

Ironwood's first drill loaded eleven of twelve tables and failed on customers. The drill is the only proof, and its output is a date and an elapsed time, not a setting.

Sources covered

What tonight maps to

✓ Immutable, object-locked backups as the ransomware control Widely documented professional practice, taught as the norm with its reason: the copy that counts is the one no credential can delete before its retention ends.
✓ Time travel and snapshots are not a backup against account compromise They are features of the account, deleted with it. The bench canon: recoverable 0 of 12 at every rung until immutable backups, then 12 with paths unchanged at 3.
✓ Restore drills A timed restore into a scratch schema with a row-count check, dated in the inventory file, as the only proof a backup exists.
✓ NIST CSF 2.0 - Recover function, applied Assets restored after an incident, proven by drill rather than asserted. The six functions as a whole are leader session 2.
◐ MITRE ATT&CK v19.2 - Impact and Defense Impairment tactics The drop and the purge, named. Leader session 3 maps the fifteen tactics onto warehouse events.
· Ransom negotiation, cyber insurance, regulator notification Not covered. The decision and reporting side of a destructive event is leader session 6 and the data governance course.

Session 6 cheat sheet

Time travel goes with the accountWhoever holds the admin login holds the recovery window too. Drop, purge, demand.
Copy versus backupIf the credential that can drop the table can delete the copy, it is a copy.
Recoverable 0 to 12, paths at 3Prevention never moved this number. The copy removes no way in; it removes the admin's reach to Monday.
Three propertiesImmutable (object lock, retention). Separate (an account the admin has no login to). Restore-tested (a date and a time).
Prove the refusalAttempt the delete as the warehouse admin and as the backup admin. Both must fail. Record both.
Immutability costs you tooYour own mistakes cannot be deleted early either. Retention is a governance decision with named owners.
Back up what cannot be rebuiltThe crown jewels, the DDL, the pipeline commit, the grants, the inventory file. Not everything nightly.
The drill is the proofA backup never restored is a hope with a storage bill. Its output is a date and an elapsed time.