OpenCyber Academy
Bachelor's · Chapter 13 · English
Course code: OCA-115Chapter 13: OCA-115-C013

Chapter 13 — Identity and access

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

Lesson map

Lesson 13 published. Map, example, EX025.

flowchart TD
  N0["Learning outcomes and connection"]
  N1["13.1 Three questions"]
  N2["13.2 Factors and remote access"]
  N3["13.3 Roles and separation of duties"]
  N4["13.4 The account life cycle and reviews"]
  N5["Chapter synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX025"]

Logical drawing

flowchart LR
  N0["Learning outcomes and connection"]
  N1["13.1 Three questions"]
  N2["13.2 Factors and remote access"]
  N3["13.3 Roles and separation of duties"]
  N4["13.4 The account life cycle and reviews"]
  N5["Chapter synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX025"]
[Learning outcomes and connection]
    |
    v
[13.1 Three questions]
    |
    v
[13.2 Factors and remote access]
    |
    v
[13.3 Roles and separation of duties]
    |
    v
[13.4 The account life cycle and reviews]
    |
    v
[Chapter synthesis]
    |
    v
[Worked example] --> [Exercise EX025]

Learning outcomes and connection

After this chapter you can (1) distinguish identification, authentication and authorisation; (2) compare authentication factors and explain why phishing-resistant methods matter for remote access to critical systems; (3) design role-based access with separation of duties; and (4) run an access review that finds orphaned, dormant, shared and toxic-combination accounts. It builds on Chapter 6 (sets) and Chapter 11 (privilege) and prepares Chapter 16 (architecture) and Chapter 24 (controls).

13.1 Three questions

Identification answers "who do you claim to be?" (a username). Authentication answers "prove it" — with something you know (a password), have (a token or phone) or are (a fingerprint). Authorisation answers "what may you do?" — the permissions attached to the authenticated identity. Errors at each stage differ: weak authentication lets the wrong person in; excessive authorisation lets the right person (or whoever stole their session) do too much. NIST's digital-identity guidelines set requirements for authenticators and recommend phishing-resistant options for higher assurance (SP 800-63B).

13.2 Factors and remote access

Passwords are guessed, reused and phished. One-time codes sent by text or typed from an app add a second factor but can be relayed by a convincing fake login page. Phishing-resistant authenticators bind the login cryptographically to the genuine site, so a fake site receives nothing usable. For remote access into OT and other critical systems — the path in the CPN advisory of Chapter 5 — strong authentication is necessary but not sufficient: the session should land on a controlled jump host, be time-limited, approved per session for vendors, and recorded.

13.3 Roles and separation of duties

In role-based access control (RBAC), permissions attach to roles ("scada-operator", "payments-approve") and people receive roles. Roles make reviews tractable: one checks fifty roles, not fifty thousand individual permissions. Separation of duties forbids certain combinations: the person who creates a payment must not approve it; the engineer who changes control logic should not also control the firewall that logs the change. Expressed with sets (Chapter 6), a toxic combination $T$ is violated when $T \subseteq \text{roles}(u)$.

Lab 7 encodes both rules as TOXIC sets and flags chloe, who holds payments-create and payments-approve, and dev, who holds scada-engineer and firewall-admin and has also been dormant for 214 days.

13.4 The account life cycle and reviews

Accounts are created when people join (joiner), changed when they move (mover) and removed when they leave (leaver). Failures accumulate at every step: movers keep old roles ("privilege creep"), leavers' accounts linger, vendors' accounts are created for a project and never removed, and shared operator accounts make actions untraceable. An access review compares accounts with an authoritative source (the HR system, the vendor contract register) and with usage.

Lab 7 shows each failure: ben left but kept his account, vendorx has no HR owner and has not logged in for 304 days, and ops1 is shared. Usage data matters as much as HR status: dev is active in HR but dormant for 214 days in a privileged role.

13.5 Worked example and Lab 7 (synthetic)

This case is synthetic. A joint review of accounts across CPN's control system and Calder Mutual's payment system (combined here only for teaching) uses HR status, last login and two toxic combinations.

# Lab 7 - access review: orphans, dormant accounts and toxic combinations (synthetic, offline)
from datetime import date
TODAY = date(2026, 10, 1)
HR = {"ana": "active", "ben": "left", "chloe": "active", "dev": "active"}
ACCOUNTS = [  # user, roles, last login, shared?
    ("ana",   {"scada-operator"},                       date(2026, 9, 30), False),
    ("ben",   {"scada-engineer"},                       date(2026, 5, 2),  False),
    ("chloe", {"payments-create", "payments-approve"},  date(2026, 9, 29), False),
    ("dev",   {"scada-engineer", "firewall-admin"},     date(2026, 3, 1),  False),
    ("ops1",  {"scada-operator"},                       date(2026, 9, 30), True),
    ("vendorx", {"remote-support"},                     date(2025, 12, 1), False),
]
TOXIC = [{"payments-create", "payments-approve"}, {"scada-engineer", "firewall-admin"}]
for user, roles, last, shared in ACCOUNTS:
    issues = []
    if user not in HR: issues.append("no HR owner")
    elif HR[user] != "active": issues.append("owner has left")
    if (TODAY - last).days > 90: issues.append(f"dormant {(TODAY - last).days} d")
    if shared: issues.append("shared account")
    issues += ["toxic: " + "+".join(sorted(t)) for t in TOXIC if t <= roles]
    print(f"{user:8} {', '.join(issues) if issues else 'ok'}")

Expected output:

ana      ok
ben      owner has left, dormant 152 d
chloe    toxic: payments-approve+payments-create
dev      dormant 214 d, toxic: firewall-admin+scada-engineer
ops1     no HR owner, shared account
vendorx  no HR owner, dormant 304 d

Actions: disable ben now (leaver); remove one of chloe's payment roles; remove dev's dormant privileged roles and ask whether he needs either; ops1 is a shared control-room login — common in 24/7 operations where a fast handover matters — so replace it with individual logins and quick user switching, or at least record who is on shift; vendorx should be disabled and re-enabled per support session under a named sponsor. Note what the script cannot see: whether ana's role still matches her job.

13.6 Common errors and limits

In Lab 7 the script confirms that ana's account is "ok" only in the sense that she is active and not dormant; whether she still needs scada-operator needs her manager. Removing ops1 outright would lead the control room to share one person's password, which is worse. And ops1 and vendorx both show "no HR owner", which is the signal that service and vendor accounts need a different authoritative source, such as the contract register.

Exercises — chapter 13

EX025 — Design the roles. Objective: apply least privilege and separation of duties. Inputs: CEDC needs call handlers, dispatchers, supervisors, a CAD administrator and a vendor support engineer. Steps: define five roles with key permissions and two toxic combinations. Expected evidence: role table and combinations. Rubric: 3 = sensible least-privilege roles, toxic pairs justified (e.g. CAD admin + audit-log admin; vendor support + permanent access); 2 = roles without combinations; 1 = vague; 0 = none.

EX026 — Extend the review. Objective: add a rule. Inputs: Lab 7. Steps: add a check that flags any account with a privileged role (scada-engineer, firewall-admin, payments-approve) that has not been re-approved in 180 days, given a new field approved (a date). Choose dates so at least one account is flagged and show the output. Expected evidence: code and output. Rubric: 3 = correct logic, test data chosen to show both flagged and unflagged cases; 2 = works, weak test; 1 = logic error; 0 = none.

Chapter synthesis

Identity answers three different questions. Use strong, phishing-resistant authentication for critical remote access, grant permissions through roles, forbid toxic combinations and review accounts against authoritative sources and actual use. Shared and vendor accounts need workable alternatives, not just prohibitions.

Worked answers

EX025. Roles: call handler (create incidents, view CAD); dispatcher (assign units, update incidents); supervisor (override, reassign, view reports); CAD administrator (configure system, manage accounts; no dispatch); vendor support (time-limited, session-approved access to test environment by default). Toxic pairs: CAD administrator + audit-log administrator (could hide own changes); vendor support + permanent production access; dispatcher + CAD administrator (could alter rules and act on them unseen).

EX026. Add approved dates to each tuple; flag if roles & PRIV and (TODAY - approved).days > 180. With, for example, dev approved 2025-11-01 (334 days) and chloe approved 2026-07-01 (92 days), output adds "re-approval overdue 334 d" to dev only. The test must show one flagged and one not flagged privileged account.