◇ OpenCyber Academy
Technical · Chapter 15 · English

Chapter 15 — Critical infrastructure and sector security: integration and dependencies

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

Chapter 15 — Critical infrastructure and sector security: integration and dependencies

Lesson map

Lesson 15 published. Map, example, EX057.

flowchart TD
  N0["Learning outcomes and connection"]
  N1["15.1 Interdependency"]
  N2["15.2 Dependencies as a graph"]
  N3["15.4 Integration points are boundaries"]
  N4["15.5 Practical activity"]
  N5["Chapter synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX057"]

Logical drawing

flowchart LR
  N0["Learning outcomes and connection"]
  N1["15.1 Interdependency"]
  N2["15.2 Dependencies as a graph"]
  N3["15.4 Integration points are boundaries"]
  N4["15.5 Practical activity"]
  N5["Chapter synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX057"]
[Learning outcomes and connection]
    |
    v
[15.1 Interdependency]
    |
    v
[15.2 Dependencies as a graph]
    |
    v
[15.4 Integration points are boundaries]
    |
    v
[15.5 Practical activity]
    |
    v
[Chapter synthesis]
    |
    v
[Worked example] --> [Exercise EX057]

Learning outcomes and connection

After this chapter you should be able to:

Chapter 13 found a path to KW-04 that bypassed the firewall through a carrier network. That was a dependency nobody had drawn. This chapter draws them systematically.

15.1 Interdependency

Critical infrastructures depend on each other physically (power for pumps), through information (telemetry over a carrier network), geographically (shared ducts and sites) and logically (shared staff, software and administration). This classification comes from Rinaldi, Peerenboom and Kelly's widely cited paper (Rinaldi et al., 2001). For a technician the most frequent surprises are logical: a directory, a hypervisor cluster, a time source or a monitoring collector shared by systems whose owners each think it is theirs.

For a technician the most frequent surprises are logical: a directory, a hypervisor or a time source that several services share without any one owner claiming them. Draw those first, then the physical and carrier links. Lab 15 makes the shared nodes visible as counts across services.

15.2 Dependencies as a graph

Write each dependency as "A needs B". To find what fails when B fails, follow the edges backwards — everything that needs B, everything that needs those, and so on. That is a breadth-first search on the reversed graph. Two results matter: the set of services affected, and the path by which each is affected, because the path tells you where a control or a redundancy would break the chain.

Indirect sharing is the important case. In the KVROC model the hospital BMS server and the SCADA server both authenticate against ad-ops, which runs on esx-03, while the grid front end also runs on esx-03. No service owner lists esx-03 as "theirs"; all three depend on it.

15.3 Worked example: KVROC dependencies (synthetic)

Lab 15 (save as lab15.py, run with python3 lab15.py):

# Lab 15 - trace failure impact through technical dependencies (offline, standard library only)
# Synthetic dependency map for the Kestrel Vale operations centre: "A needs B" edges.
from collections import deque
needs = {
 "water-telemetry": ["scada-01", "cell-router-kw", "fw-01"],
 "scada-01": ["ad-ops", "ntp-ops", "hist-02", "esx-02"],
 "hist-02": ["esx-02", "san-01"],
 "hospital-bms": ["bms-server", "fw-02"],
 "bms-server": ["esx-02", "ad-ops"],
 "grid-ss3-telecontrol": ["fep-01", "telco-mpls"],
 "fep-01": ["ntp-ops", "esx-03"],
 "ad-ops": ["esx-03"],
 "ntp-ops": ["gps-clock"],
}
def impacted(failed):
    rev = {}
    for a, bs in needs.items():
        for b in bs: rev.setdefault(b, []).append(a)
    seen, q = set(), deque([failed])
    while q:
        for a in rev.get(q.popleft(), []):
            if a not in seen: seen.add(a); q.append(a)
    return sorted(seen)
services = {"water-telemetry", "hospital-bms", "grid-ss3-telecontrol"}
for comp in ["esx-02", "esx-03", "gps-clock", "san-01", "telco-mpls"]:
    hit = impacted(comp)
    print(f"{comp:<10} -> services {sorted(services & set(hit))} via {len(hit)} dependants")
counts = {c: len(services & set(impacted(c))) for c in {b for bs in needs.values() for b in bs}}
print("shared by all three services:", sorted(c for c, n in counts.items() if n == 3))

Expected output (Python 3.13.5):

esx-02     -> services ['hospital-bms', 'water-telemetry'] via 5 dependants
esx-03     -> services ['grid-ss3-telecontrol', 'hospital-bms', 'water-telemetry'] via 7 dependants
gps-clock  -> services ['grid-ss3-telecontrol', 'water-telemetry'] via 5 dependants
san-01     -> services ['water-telemetry'] via 3 dependants
telco-mpls -> services ['grid-ss3-telecontrol'] via 1 dependants
shared by all three services: ['esx-03']

esx-02 hosts the SCADA server, the historian and the BMS server, so its failure affects water and hospital monitoring. esx-03 is the only component that affects all three services — directly for the grid front end, indirectly through the directory for the other two. gps-clock, the reference for ntp-ops, affects water and grid: losing it does not stop anything immediately, but Chapter 7 showed what drifting clocks do to every later investigation. telco-mpls affects only the grid, and san-01 only water.

Technical actions follow: the directory needs a second domain controller on a different host (and the SCADA server's behaviour when the directory is unreachable must be tested — can operators still log in to the HMI?); ntp-ops needs a second, independent reference and monitoring of offset; esx-03 capacity and administrator group become a cross-sector concern reviewed with all three owners.

15.4 Integration points are boundaries

Every place the service connects to something it does not control is a boundary:

CISA's National Critical Functions work frames these dependencies at national scale (National Critical Functions); the technician applies the same reasoning to one operations centre.

15.5 Practical activity

Add a power-ups-a node that esx-02 and esx-03 both need, and a cell-carrier node that cell-router-kw and telco-mpls both need. Re-run Lab 15 and record which components are now shared by all three services. Then propose one technical change for each.

After the change, record which components are shared by all three services and propose one technical response for each, such as a second domain controller or a second power feed. Keep the new edges in the same format as the lab so that the graph stays runnable. Review the proposals with the three service owners before any change.

15.6 Common errors and limits

Exercises — chapter 15

EX057 — Paths matter. Objective: trace an impact path. Inputs: Lab 15. Steps: modify the program to print, for esx-03, one dependency path from it to each affected service. Expected evidence: code and three paths. Rubric: 3 = for example esx-03 → fep-01 → grid-ss3-telecontrol; esx-03 → ad-ops → scada-01 → water-telemetry; esx-03 → ad-ops → bms-server → hospital-bms; explains that a second directory on another host breaks two of the three; 2 = paths without interpretation; 1 = attempted; 0 = none.

EX058 — New shared components. Objective: run the activity. Inputs: activity 15.5. Steps: run and interpret. Expected evidence: output and two technical changes. Rubric: 3 = power-ups-a and esx-03 shared by all three (and cell-carrier affecting water and grid); changes such as separate UPS feeds for the two hosts and a second carrier or radio path for the most critical stations; 2 = output only; 1 = partial; 0 = none.

EX059 — Degraded-mode test. Objective: test behaviour when a dependency fails. Inputs: ad-ops unavailable. Steps: write a scoped test plan, in a maintenance window, to establish whether operators can still log in to the HMI and whether SCADA polling continues. Expected evidence: test plan with stop conditions. Rubric: 3 = test on a standby or lab replica first; in production, blocks only the HMI's path to the directory for a short window with operations present; checks cached logins, local emergency accounts, polling continuity; stop conditions; evidence; 2 = no replica step; 1 = "turn off the domain controller"; 0 = none.

EX060 — Export direction. Objective: configure a boundary correctly. Inputs: the corporate report server currently logs in to hist-02 every night with a stored password to pull the CSV. Steps: redesign and list the configuration changes on both hosts and on fw-01. Expected evidence: design and changes. Rubric: 3 = hist-02 pushes over HTTPS to one endpoint; corporate credential into Z2 removed; fw-01 rule direction reversed (Z2 → Z6 only, specific host and port); push integrity checked (digest in the payload or a signed file); monitoring for failed pushes; 2 = push without removing old credential; 1 = vague; 0 = none.

Chapter synthesis

Services fail through what they depend on, and the most dangerous dependencies are shared ones that no owner claims. Model dependencies as a graph, search it backwards from each component, and look at the paths, not just the counts. Treat every integration point — station routers, carriers, vendor gateways, exports, directory and time — as a boundary under the same control, change and monitoring discipline as the firewall.

Continue studying — chapter 15 of 18

← Chapter 14 · Course chapter index · Chapter 16 →

Continue to the next authored lesson.

Worked answers

EX057 — Paths matter. Keep a parent map in the breadth-first search and walk back from each service. Paths: esx-03 → fep-01 → grid-ss3-telecontrol; esx-03 → ad-ops → scada-01 → water-telemetry; esx-03 → ad-ops → bms-server → hospital-bms. A second directory server on a different host breaks the water and hospital paths; the grid path needs fep-01 redundancy on another host.

EX058 — New shared components. After adding the nodes, shared by all three services: esx-03 and power-ups-a (verified). cell-carrier affects water and grid. Changes: feed esx-02 and esx-03 from separate UPS units and circuits; give the most critical stations and the SS-3 telecontrol a second, independent communication path (different carrier or licensed radio).

EX059 — Degraded-mode test. First on a replica or standby HMI: block its directory traffic and test login with cached credentials and with the documented local emergency account. In production, in an agreed window with Kestrel Water operations present: block the HMI's path to ad-ops for 10 minutes at fw-01; confirm operators can log in and act, and that scada-01 polling continues (historian count). Stop conditions: any loss of operator view or control, any alarm; immediate rule removal as rollback. Evidence: rule change log, login records, historian counts.

EX060 — Export direction. hist-02 pushes the CSV over HTTPS to report-01 with a service credential that can only upload; the corporate account and stored password used to log in to hist-02 are removed and the password rotated; fw-01 permits only hist-02 → report-01 tcp/443, and nothing from Z6 to hist-02; include a SHA-256 digest of the file in the upload metadata and check it on receipt; alert if no push arrives by 06:30.