OpenCyber Academy
Rapid course · Lesson 14 · English
Course code: OCA-016Lesson 14: OCA-016-A014

Evidence-linked recovery decision records

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Week 3, day 4. Work through the teaching and the worked checkpoint before attempting the assigned exercise(s). Compare your artifact with the final worked result only afterward.

3.9 Sourced case study: recovery beyond the backup copy

Harbor Library is invented. A useful real-world contrast is the British Library's own March 2024 review of the October 2023 cyber-attack. The report is the institution's retrospective account, written after investigation; it is not a raw event log, a finding about Harbor Library or a template for a one-month course to reproduce. Its exact descriptions are time-bound to the review date. Read the cited pages when using the case and avoid extending the report's conclusions to unexamined systems.

The review reports that attackers encrypted or destroyed a substantial part of the Library's server estate and that the institution had secure copies of its digital collections, yet lacked viable infrastructure on which to restore services promptly (executive summary, pp. 2–3). By December 2023, viable backup sources had been identified for collections and other data, but the report still describes restricted research services and systems needing modification, migration or replacement (pp. 2–3 and 9). A searchable catalogue returned on 15 January 2024 while other functions remained incomplete (pp. 2 and 9–10). These are reported facts about the British Library, not evidence about the fictional bookings B17–B20. The teaching inference is that copy availability, platform readiness, data validation and service acceptance are different checkpoints. A backup can exist while the environment needed to use it is missing or unsafe.

The same report describes strategic and operational crisis groups coordinating technical response, approving workarounds and communicating during disrupted website and intranet service (section 3, pp. 12–13). This supports a second teaching inference: response records must name decision owners and alternate communications paths, because a status page or ordinary internal channel may itself be unavailable. The British Library's roles and governance are specific to that institution; the incident-lead/service-owner matrix in this course is a fictional teaching arrangement, not a claim that the real Library used it.

Lesson table; scroll horizontally to read all columns →

Source-based statement What a learner may infer for recovery planning What the source does not establish for this course
The British Library reported secure digital-collection copies but damaged restoration infrastructure. Test both the copy and the ability to restore it onto an acceptable platform. It does not give Harbor Library a usable backup, a measured restore time or an approved P1 booking target.
A searchable catalogue returned while other services remained restricted. Define acceptance separately for each user-facing service; a partial return can be useful and still be incomplete. It does not prove that a searchable page means all data and access controls are correct.
Crisis groups coordinated workarounds and communications. Record who can authorize a temporary manual process and how staff and users will be updated. It does not authorize a learner to pause a real booking service or contact real users.

Guided source-reading activity: write a three-row claim ledger with (1) a fact from the British Library report and its page or section, (2) one planning question it raises for the fictional booking service, and (3) one conclusion it cannot support about B17–B20. Include at least one row about restoration infrastructure and one about partial service. Then compare the source date with the time of your own course reading: a 2024 retrospective cannot by itself tell you the Library's current service state. The report also expresses uncertainty about the exact initial intrusion point; do not turn a likely entry point into a certain one. A model ledger appears in the final answer section. This supplementary source analysis is separate from EX027–EX038.

Contrast: a decision record at 09:37

Plausible but incorrect: "At 09:37 we know B20 was an attack. R21 authorizes a write pause, R22 proves the writes have stopped, and R23 proves recovery is ready. Apply the pause and close the incident after the page loads."

Each asserted upgrade is wrong. R18 reports a B20 change but no human attacker or causal mechanism. R21 says a pause is tolerable, not approved or executed. R22 is a narrow earlier query, not a post-change verification. R23 is a backup/old restore-test status, not a current service-acceptance result. A loading page is not evidence of booking correctness or auditability.

Defensible 09:37 proposal: "R17 limits the known approved task list to B17/B18 and R18 reports a further B20 edit under desk-a. The incident lead proposes a bounded current-session revocation, subject to identity-owner approval and preservation of feasible narrow sources. The identity administrator will verify execution if approved; the application and service owners will separately assess later edits and front-desk continuity. R21 supports discussing a short manual-queue fallback but gives no execution authority. Root cause, recovery readiness and personal-data exposure remain unresolved; reassess at the named next review or on a verified continuing edit."

This record does not avoid action. It prevents recommendation, approval, execution and success from becoming a single unsupported sentence.

3.10 Worked decision record and synthesis

Audit the defensible 09:37 proposal above as four separate receipts. This prevents a well-worded recommendation from being mistaken for a change that happened:

Lesson table; scroll horizontally to read all columns →

State What the supplied case supports What a later reviewer would need
Proposed R17–R18 justify asking to revoke the identified current desk-a session. R21 makes a short staff-write pause a possible fallback with a known service cost. A named decision owner, exact session or write routes, review time and a plan for the manual queue or staff reauthentication.
Approved No R1–R24 record approves either action at 09:37. Tolerating a pause is not authorizing it. A separately recorded incident-lead and relevant identity- or service-owner approval for the chosen target and interval.
Executed No R1–R24 record states that a session was revoked or staff writes were paused. Operator receipt with actual target, time, method and any failed or partial steps.
Verified R22 predates the proposal, and its query bounds are incomplete. It cannot show that a later change worked. A post-action protective test tied to the selected target, a separate check of legitimate booking service, reliable source coverage and a defined failure trigger.

The proposal should set a 09:45 review or earlier review on a verified new unexplained edit. Root cause and personal-data exposure remain unresolved; the four rows do not claim a production action.

This chapter converts the earlier timeline into a bounded decision. Module 4 will test the whole response: intake, evidence, authority, proportionate action, recovery criteria and a review of what the team would change before another incident.

3.11 Offline laboratory: decision and recovery gates

Purpose: Validate the logical separation of proposal, approval, execution, protective verification, legitimate service continuity, data correctness and audit attribution. This is a new independent classroom branch, not a replay of W1 write-path tests, the P1/C1 booking-value comparison, V1's specific observations or K1 copy selection.

Environment: Python 3 standard library; data only in memory. No network, files, credentials or system changes. Every G3 row is a separate reset scenario, not a chronological incident timeline.

Inputs and meanings: A value of True means the corresponding fictional test card asserts that a gate passed in its limited scope; False means the card asserts a failed gate; None means no test result is supplied. The flags are not real approval receipts, collection evidence or actual restorations. protective concerns the bounded harmful operation, legitimate the required legitimate business function, data an isolated owner-approved data check and audit sufficient attribution for the tested operation. The model intentionally requires all four for its most favorable limited label.

Executable fixture
SCENARIOS = [
    ("G3-P", False, False, None, None, None, None),
    ("G3-A", True, False, None, None, None, None),
    ("G3-E", True, True, None, None, None, None),
    ("G3-C", True, True, False, True, True, True),
    ("G3-B", True, True, True, False, True, True),
    ("G3-I", True, True, True, True, None, None),
    ("G3-D", True, True, True, True, False, True),
    ("G3-U", True, True, True, True, True, False),
    ("G3-V", True, True, True, True, True, True),
    ("G3-X", False, True, True, True, True, True),
]

def gate(approved, executed, protective, legitimate, data, audit):
    if executed and not approved:
        return "INVALID_UNAPPROVED_EXECUTION"
    if not approved:
        return "PROPOSED_ONLY"
    if not executed:
        return "APPROVED_NOT_EXECUTED"
    if protective is None or legitimate is None:
        return "EXECUTED_UNVERIFIED"
    if not protective:
        return "PROTECTION_GATE_FAIL"
    if not legitimate:
        return "BUSINESS_GATE_FAIL"
    if data is None or audit is None:
        return "RECOVERY_CHECKS_PENDING"
    if not data:
        return "DATA_GATE_FAIL"
    if not audit:
        return "AUDIT_GATE_FAIL"
    return "BOUNDED_TEST_GATES_PASS"

for ident, *fields in SCENARIOS:
    print(ident, gate(*fields))

# Negative control: invalidate attribution for the favorable test card.
print(
    "NEGATIVE_AUDIT",
    gate(True, True, True, True, True, False),
)
Exact expected output — executed against the displayed fixture
G3-P PROPOSED_ONLY
G3-A APPROVED_NOT_EXECUTED
G3-E EXECUTED_UNVERIFIED
G3-C PROTECTION_GATE_FAIL
G3-B BUSINESS_GATE_FAIL
G3-I RECOVERY_CHECKS_PENDING
G3-D DATA_GATE_FAIL
G3-U AUDIT_GATE_FAIL
G3-V BOUNDED_TEST_GATES_PASS
G3-X INVALID_UNAPPROVED_EXECUTION
NEGATIVE_AUDIT AUDIT_GATE_FAIL
G3-DG adversarial follow-up: a failed gate outranks an unknown one

The first G3-DG listing reports only one state per card. Its ordering hides a known failed protection test when the service test is unknown: gate(True, True, False, None, True, True) returns EXECUTED_UNVERIFIED. Likewise, gate(True, True, True, True, False, None) returns RECOVERY_CHECKS_PENDING despite a known failed data test. These results reproduce the code's branch order, not a defensible acceptance decision. First ask whether a required test is known to have failed; only then classify the remaining unknowns. This follow-up is a separate logic-only check and leaves the eleven original lines intact.

def gate_strict(approved, executed, protective, legitimate, data, audit):
    if executed and approved is not True:
        return "INVALID_UNAPPROVED_EXECUTION"
    if approved is not True:
        return "PROPOSED_ONLY"
    if executed is not True:
        return "APPROVED_NOT_EXECUTED"
    if protective is False:
        return "PROTECTION_GATE_FAIL"
    if legitimate is False:
        return "BUSINESS_GATE_FAIL"
    if protective is not True or legitimate is not True:
        return "EXECUTED_UNVERIFIED"
    if data is False:
        return "DATA_GATE_FAIL"
    if audit is False:
        return "AUDIT_GATE_FAIL"
    if data is not True or audit is not True:
        return "RECOVERY_CHECKS_PENDING"
    return "DECLARED_GATES_PASS_NOT_AUTHENTICATED"

CASES = [
    ("ALL_FLAGS_TRUE", (True, True, True, True, True, True)),
    ("PROTECTION_FAIL_SERVICE_UNKNOWN", (True, True, False, None, True, True)),
    ("SERVICE_FAIL_PROTECTION_UNKNOWN", (True, True, None, False, True, True)),
    ("DATA_FAIL_AUDIT_UNKNOWN", (True, True, True, True, False, None)),
    ("AUDIT_FAIL_DATA_UNKNOWN", (True, True, True, True, None, False)),
    ("ALL_CHECKS_UNKNOWN", (True, True, None, None, None, None)),
    ("EXECUTED_WITHOUT_APPROVAL", (False, True, True, True, True, True)),
]
for name, flags in CASES:
    print(f"{name}: {gate_strict(*flags)}")

Supplemental output (seven lines):

ALL_FLAGS_TRUE: DECLARED_GATES_PASS_NOT_AUTHENTICATED
PROTECTION_FAIL_SERVICE_UNKNOWN: PROTECTION_GATE_FAIL
SERVICE_FAIL_PROTECTION_UNKNOWN: BUSINESS_GATE_FAIL
DATA_FAIL_AUDIT_UNKNOWN: DATA_GATE_FAIL
AUDIT_FAIL_DATA_UNKNOWN: AUDIT_GATE_FAIL
ALL_CHECKS_UNKNOWN: EXECUTED_UNVERIFIED
EXECUTED_WITHOUT_APPROVAL: INVALID_UNAPPROVED_EXECUTION

Predict which gate wins when one test is False and another is None, then compare with the seven lines. ALL_FLAGS_TRUE is an internally consistent assertion in a synthetic card; it does not authenticate an approver, operator, source, clock or test scope. A real decision requires separate receipts and a service-owner acceptance decision. Neither this fixture nor its output adds an R-series observation.

Interpretation and negative control

G3-P records only a proposal. G3-A adds a fictional approval but no execution. G3-E claims execution while omitting effectiveness checks; it cannot be described as successful containment. G3-C and G3-B show why the protective and legitimate-service tests are independently necessary. G3-I has both of those bounded passes but no recovery-data or audit result. G3-D fails data correctness. G3-U fails audit attribution. G3-V passes the declared classroom gates for that one modeled test, but does not establish root cause, complete route coverage, production authorization or service-owner acceptance. G3-X contains an internally unacceptable claim of execution without approval and is rejected even when all other flags are true.

The negative control changes only the audit flag of the favorable test to False. The output becomes AUDIT_GATE_FAIL: a missing or failed mandatory attribution check blocks the limited acceptance label even when protection, legitimate service and data appear satisfactory.

Important algorithmic limit: This code is a decision-logic demonstration, not an evidence authentication engine. Setting approved=True does not supply a real signed approval; setting executed=True does not produce an operator receipt. All gates would need independent, scope-appropriate evidence in a real authorized operation. The program also does not estimate probabilities or verify that all paths were tested.

Learner artifact: Before running, predict all eleven lines. Afterward, provide a three-column table scenario | returned state | missing or failed evidence. Add one sentence explaining why G3-V does not mean "recovery complete," and another showing how G3-D might require a new isolated copy or owner-approved reconciliation rather than an unconditional return. Keep G3 cards outside canonical R1–R24 and the later chapter branches.

Acceptance rubric (five-point lab, supplementary rather than a new numbered exercise): one point each for exact output; correct lifecycle separation; independent protective and service gates; distinct data and audit failure interpretation; and an explicit bounded-evidence/canonical-release limitation. Do not claim the classroom True inputs were verified production observations.

Worked checkpoint

An attractive restore candidate can pass integrity but fail the owner target or a bounded RPO test. The decision record should state the failed gate, a safe alternative and the next observation that could change the verdict.

Practice — Lesson 14

EX035 — Return-to-service criteria

Objective: require evidence for a proposed return to service. Inputs: P1/C1 and V1 only after their later release, plus the section 3.5 checklist. Output: three measurable acceptance rows for booking correctness, tested access behavior and audit attribution, each with expected result, current supplied result, owner and action needed. Conclude with a proposed service state, next review and one rollback trigger. A score of 2 marks B19/B20 as mismatched in C1, V1's tested access checks as limited passes, and the blank audit actor as a failure, so it does not declare unrestricted recovery.

Additional queue gate for EX035: If the later Branch P is chosen and only after it is released, add a fourth acceptance row for its two unnamed pending manual requests. The row must require a bounded manifest, owner-approved dispositions and a check of current authoritative booking state; do not borrow MQ3 outcomes, W1 or P1/C1 as the branch queue. The B19/B20 mismatches and V1 missing actor remain independent failed gates.

RTE3 extension: Retain the original booking-correctness, permitted/denied access and audit acceptance conditions and the conditional Branch P queue gate after its proper release. Add an acceptance-time evidence row: actual interruption timestamp/source, last passed mandatory gate, owner acceptance (or rejection) timestamp, scope and outcome. If P1/C1 or V1 reports a failed gate in its later isolated test, explain why no full-service recovery completion time is established by those cards.

RTE3 scoring note: Do not turn the existing V1 limited access results into a completed restore, turn a blank actor into a pass, treat a pending queue as reconciled, or report a measured RTO without comparable start/end receipts and owner-approved acceptance.

Worked answer: EX035 in the final appendix.

EX036 — Decision record

Objective: keep a response recommendation auditable before execution. Inputs: R17–R21 and the 09:37 checkpoint. Output: a six-field card covering time and status, evidence and uncertainty, chosen action and scope, approvers/executor, intended effect plus service side effect, and verification/fallback/review. Name the identity owner and incident lead for the proposed revocation; use R21 only for a possible pause fallback. A score of 2 gives an observable post-action test and says proposed, not completed.

RB3 extension: Additional requirement: Keep the original six-field card for the 09:37 proposal. In field 6 (verification/fallback/review), add a short conditional reversal subcard: last verified configuration reference to obtain, observable trigger, scope and window to request, authority needed, operator/effect receipt to require, post-reversal protection and legitimate-service checks, and the accountable human-review item. Use pending/not supplied for every rollback execution or test not contained in R17–R24.

RB3 2-point refinement: The historical action remains a proposal, the new inverse is not silently authorized, and later branch or RB3 exercise observations never enter the canonical 09:37 decision.

Worked answer: EX036 in the final appendix.

Worked answers

EX035 — Worked result

Lesson table; scroll horizontally to read all columns →

Acceptance check Expected result Current supplied state Owner and next action
Booking correctness New restricted comparison copy matches P1 for B17–B20 after approved correction. Fail/pending: C1 matches B17/B18 but B19 and B20 are reversed against P1. Service owner approves bounded correction; authorized operator acts; analyst checks a new copy.
Access behavior Approved synthetic staff role can edit; tested unauthorized role is denied. Limited pass in isolated copy: V1 reports both observed outcomes, but not every account or live path was tested. Identity and application owners define the acceptable production-scope verification before full release.
Audit visibility Authorized test change is recorded with correct actor and UTC time. Fail: V1 has a UTC time but blank actor. Application/audit owner repairs attribution and reruns the test; incident lead records interim monitoring.

Proposed status: do not declare unrestricted return to service. The service owner and incident lead may consider a time-limited restricted mode with a compensating check, named owner and near-term review, but the failed booking and audit criteria remain open. An unexplained new edit or failed manual-queue reconciliation triggers renewed restriction or escalation. A loading page or backup-success label does not override these observable failures.

MQ3-linked queue gate, conditional on later Branch P: The branch reports two pending requests but does not identify either, their approval, their expected version or a completed effect. Add a separate acceptance row owned by the service owner: obtain the restricted queue manifest; compare each request with approved current booking state and prior-effect record; record applied, duplicate, held or conflicting disposition; verify authorized effect and audit; and retain unresolved items with an owner and next review. This cannot override C1's B19/B20 mismatches or V1's blank actor. MQ3's X-booking outcomes are classroom data, not the branch's pending work.

RTE3 additional reasoning: Only after the later P1/C1 and V1 releases, the supplied comparison shows B19/B20 differing from the approved P1 targets while V1 reports limited permitted/denied access tests and a failed audit actor field. Those are separately scoped results, and they do not establish full service acceptance. The relevant acceptance-time row therefore states: interruption start/time not supplied for an actual completed Harbor Library recovery, required data and audit gates failed or unverified, accountable service-owner acceptance not supplied, and service-level elapsed recovery not measurable. A later restricted-mode proposal would need its own declared service scope, approver, restrictions and accepted decision time; it cannot turn existing failed gates into passes. If Branch P was separately chosen, its two pending queue items remain unresolved until their own owner-approved dispositions are evidenced. RTE3's artificial 85-minute interval is a different exercise and cannot be substituted for a canonical Harbor Library completion time.

Acceptance-time evidence row — model answer for EX035:

Lesson table; scroll horizontally to read all columns →

Acceptance check Expected evidence Currently available exercise result Owner and next action
Scoped owner acceptance and interruption-to-service elapsed time Verified interruption start, passed booking/access/audit gates, owner acceptance/rejection time and declared restricted/full service scope Unmeasured and unaccepted for full return: C1 still mismatches P1 on B19/B20, V1 lacks its audit actor, and no canonical full-service acceptance timestamp is provided Service owner and incident lead retain a pending decision; require new authorized booking/audit checks and a dated scoped approval before calculating elapsed recovery

If Branch P is separately chosen and released, add its queue gate only after a bounded manifest and owner-approved dispositions are available; do not borrow MQ3 results or turn a proposed restricted mode into a full-service pass.

EX036 — Worked result

Lesson table; scroll horizontally to read all columns →

Field Model decision card at 09:37 UTC
1. Time and status 09:37 UTC, proposal; not executed.
2. Evidence and uncertainty R17's approved list names B17/B18; R18 shows B20 changed at 09:24. Account operator and cause unknown.
3. Chosen action and scope Revoke only the identified current desk-a session; preserve narrow available records if doing so does not delay harm reduction.
4. Approver and executor Approval required; no receipt supplied: the incident lead and identity owner would need to approve the exact named-session action under the fictional policy. Only after that distinct decision could the identity administrator execute it, record the actual target and time, and request scoped protective and legitimate-service checks. No approval, execution or verification is established at 09:37.
5. Intended effect and side effect Try to stop edits through that session; legitimate staff may need to reauthenticate and booking work may slow.
6. Verify, fallback and review Check a specific identity revocation result, later bounded booking audit and desk impact at 09:45 UTC. If a verified edit continues, seek service-owner approval for a fifteen-minute write pause under R21's stated tolerance.

R21 does not mean the fallback has already been implemented. Before any Module 4 branch result is released, a completed-action sentence is unsupported.

For full credit, the six-field proposal names the decision owners and prospective operator while marking their approval, execution and effect receipts pending. R21 establishes tolerance for a possible short pause, not authority to implement either action.

RB3 additional worked reasoning: The six-field card remains: (1) 09:37 proposal/not executed; (2) R17's confirmed training scope and R18's B20 edit, with actor/cause unknown; (3) named-current-session restriction proposal; (4) incident lead and identity owner approvals needed, identity administrator prospective executor; (5) intended protection and possible staff reauthentication cost; (6) proposed bounded identity/booking verification, a possible pause fallback and a 09:45 review trigger. The conditional RB3 subcard fits inside field 6, not as a new seventh field. It identifies the baseline and approval details to collect before any action, the service-harm or protection-failure signal that might trigger a new reversal request, the owner of that decision, a target- and time-scoped execution receipt, both post-state checks, and an open human review. Every result that is not supplied remains pending. No Branch S/P or RB3 execution is backdated to the 09:37 R-series case.