---
title: 'Sector-Specific Compliance Requirements'
source: 'https://academia.sh/en/courses/governance-risk-and-compliance/sector-specific-compliance-requirements'
course: 'Governance, Risk and Compliance'
language: en
updated: '2026-09-26T03:02:52+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Ties sector-specific compliance requirements to the data type, and counts the extra controls each type brings through the difference between the union and the sum'
    - 'Calculates how control lists accumulate in multi-type systems and the load a single system carries'
    - 'Measures how many controls not holding the data at all eliminates: shows that partial removal has no effect and that residual controls come back'
---

# Sector-Specific Compliance Requirements

Tying compliance requirements to the data type, and the control-side counterpart of narrowing the scope: in 16 systems and 4 data types, the extra controls per type add up to 29 when summed separately and to 20 in the union; 9 multi-type systems carry a control load of 129; removing a type from every system drops 4 and 3 controls respectively, while removing it partially drops no controls at all; residual controls come back; and three separate measures order the same four actions in three different sequences.

The previous lesson's matrix took the requirements independent of their sources: each row was a
sentence. But what determines the length of a requirement list is often not what the organization
does, but **what data it touches**. If one of two systems carrying the same architecture processes
payment card data and the other does not, the two do not have equal control lists.

This lesson ties the requirement to the data type. The types are referred to here **as data
types** — payment card data, health data, personal data, measurement data — and no regulation,
institution, or sector-association name is written down. Three things are to be measured: how many
extra controls a type brings, how the lists accumulate when a single system holds two types at
once, and how many controls the harshest form of narrowing the scope — not holding the data at all
— actually eliminates.

- **FW21.** The inventory is 16 systems taken from a fictional **regional measurement network**.
  The systems, data types, and control counts are **fictional**.
- **FW22.** There are four data types, and each type brings a set of extra controls. The sets
  intersect: a control can appear in more than one type.
- **FW23.** A system's control list is the **union** of the control sets of the types it carries;
  if the same control comes from two types, it is counted once.
- **FW24.** Every control produces a certain number of evidence items in the period, and it
  produces this **separately for each system**; the total evidence volume is summed over
  system-control pairs.
- **FW25.** A control disappears only once **no system carrying it** remains. Removing a type from
  some systems does not shorten the control list.
- **FW26.** Removing the data can have a **residual control**: the boundary itself that carries
  the data out, or the assessment of the party it was outsourced to, comes back as a new control.

```js
// sector/data.mjs — sector-specific compliance requirements are tied to the data type.
// MODEL: regional measurement network (fictional); systems, controls, and counts are fictional.
export const row = (s) => s.trim().split("\n").map((l) => l.trim().split("|"));
export const gen = (B) => (...h) => h.map((v, j) =>
  (j ? String(v).padStart(B[j]) : String(v).padEnd(B[0]))).join("");

// code | control | evidence items produced in the period
export const CONTROL = Object.fromEntries(row(`
  C01|encryption at rest|365
  C02|encryption in transit|365
  C03|network segmentation|12
  C04|validation of the tokenization boundary|52
  C05|access logging|365
  C06|privileged access approval|48
  C07|retention-period run|365
  C08|deletion request flow|30
  C09|data inventory refresh|4
  C10|data flow map|2
  C11|consent record|120
  C12|purpose-limitation review|4
  C13|additional access approval for special-category data|24
  C14|personnel confidentiality commitment|1
  C15|additional awareness training|2
  C16|vendor assessment|3
  C17|periodic penetration test|1
  C18|log integrity|365
  C19|measurement-accuracy reconciliation|12
  C20|test data masking|12`)
  .map(([code, name, item]) => [code, { code, name, item: +item }]));

// data type | extra controls brought by that type. No regulation name is written; the type name is.
export const TYPE = Object.fromEntries(row(`
  payment-card|C01 C02 C03 C04 C05 C06 C16 C17 C20
  health|C01 C05 C07 C11 C12 C13 C14 C15
  personal|C01 C02 C05 C07 C08 C09 C10 C11 C12
  measurement|C05 C18 C19`).map(([t, k]) => [t, k.split(" ")]));

// system | data types it carries
export const SYSTEM = row(`
  billing-application|payment-card personal
  billing-database|payment-card personal
  payment-gateway-link|payment-card
  subscriber-portal|personal
  call-center-recording|personal health
  field-crew-app|personal health
  occupational-health-record|health
  aggregator-service|measurement
  validator-service|measurement
  field-meter-network|measurement
  reporting-warehouse|payment-card personal measurement
  backup-store|payment-card personal health measurement
  log-collection-pipeline|personal measurement
  identity-provider|personal
  archive-store|personal health
  test-environment|payment-card personal`).map(([name, t]) => ({ name, type: t.split(" ") }));

export const controlsFor = (types) => new Set(types.flatMap((t) => TYPE[t]));
export const required = (systems) =>
  controlsFor([...new Set(systems.flatMap((s) => s.type))]);

if (import.meta.url === `file://${process.argv[1]}`) {
  const typeNames = Object.keys(TYPE);
  console.log(`model: ${SYSTEM.length} systems, ${typeNames.length} data types, ` +
    `${Object.keys(CONTROL).length} controls`);

  const y = gen([14, 9, 16, 8, 8, 16]);
  console.log("\n" + y("data type", "systems", "extra controls", "unique", "shared",
    "evidence items"));
  for (const t of typeNames) {
    const s = SYSTEM.filter((x) => x.type.includes(t));
    const unique = TYPE[t].filter((k) => !typeNames.some((o) => o !== t && TYPE[o].includes(k)));
    console.log(y(t, s.length, TYPE[t].length, unique.length, TYPE[t].length - unique.length,
      TYPE[t].reduce((a, k) => a + CONTROL[k].item, 0)));
  }
  const sum = typeNames.reduce((a, t) => a + TYPE[t].length, 0);
  const union = required(SYSTEM);
  console.log(`\ncontrols per type summed separately ${sum}; union ${union.size} — ` +
    `${sum - union.size} controls repeat across more than one type`);

  const z = gen([21, 7, 10, 16, 13]);
  console.log("\n" + z("highest-load system", "types", "controls", "evidence items",
    "single-type"));
  const topLoaded = [...SYSTEM].sort((a, b) => controlsFor(b.type).size - controlsFor(a.type).size ||
    b.type.length - a.type.length).slice(0, 4);
  for (const s of topLoaded) {
    const k = [...controlsFor(s.type)];
    const single = k.filter((x) => s.type.filter((t) => TYPE[t].includes(x)).length === 1).length;
    console.log(z(s.name, s.type.length, k.length, k.reduce((a, x) => a + CONTROL[x].item, 0),
      single));
  }
  const multi = SYSTEM.filter((s) => s.type.length > 1);
  console.log(`\nmulti-type systems ${multi.length}/${SYSTEM.length}; their control load ` +
    `${multi.reduce((a, s) => a + controlsFor(s.type).size, 0)} items, single-type ` +
    `${SYSTEM.length - multi.length} systems' load ` +
    `${SYSTEM.filter((s) => s.type.length === 1).reduce((a, s) => a + TYPE[s.type[0]].length, 0)}`);
}
```

```
model: 16 systems, 4 data types, 20 controls

data type       systems  extra controls  unique  shared  evidence items
payment-card          6               9       6       3            1223
health                5               8       3       5            1246
personal             11               9       3       6            1620
measurement           6               3       2       1             742

controls per type summed separately 29; union 20 — 9 controls repeat across more than one type

highest-load system    types  controls  evidence items  single-type
backup-store               4        20            2152           14
reporting-warehouse        3        17            2125           14
billing-application        2        15            1748           12
billing-database           2        15            1748           12

multi-type systems 9/16; their control load 129 items, single-type 7 systems' load 44
```

The place to read in the first table is the fourth and fifth columns. Payment card data brings
nine extra controls, and six of them are unique to that type alone; health data brings eight
controls, but only three are unique — five are shared with other types. This is the item most
often miscalculated in compliance work: when the types are summed separately, 29 controls come
out; the union is 20. Nine controls repeat across more than one type, meaning **the control cost
of taking on a second data type is lower than the first.** Encryption at rest appears in three
types at once; set up once, it answers three obligations at the same time.

The reverse side of sharing must also be counted. If a control comes from more than one type, the
cost of letting that control slip is also spread across more than one obligation: access logging
appears in all four of the four types, so a single logging stream breaking leaves four separate
requirements without evidence at the same time. The previous lesson's leverage measure is
reproduced here by data type — a shared control is the source of both the saving and the
fragility.

The second table shows this accumulation at the system level. Because the backup store carries all
four types, it takes on **all** twenty controls; no system in the inventory carries this much
load, and the backup store itself does no work of its own — it only holds other systems' data.
The reporting warehouse and the test environment are in the same class. Data-type lists accumulate
in these three places because all three collect data **independent of its source**. The last line
says the same thing in aggregate: nine multi-type systems carry a control load of 129, while seven
single-type systems carry 44.

## Not Holding the Data at All

The harshest way to shorten the control list is not to hold the data at all: removing the type
from the system, outsourcing it, or aggregating it in a way that strips the identifiers. The file
below runs four actions on the same inventory and counts how many controls each one actually
drops.

```js
// sector/narrowing.mjs — how many controls not holding the data at all eliminates.
import { CONTROL, TYPE, SYSTEM, controlsFor, required, gen } from "./data.mjs";

// Evidence items a system produces in the period: the controls of the types it carries
const volume = (set) => set.reduce((a, s) =>
  a + [...controlsFor(s.type)].reduce((x, k) => x + CONTROL[k].item, 0), 0);

// action | data type removed | systems touched ("*" = all) | residual control | days
const ACTION = [
  ["token and gateway outsourcing", "payment-card", "*", ["C04", "C16"], 30],
  ["health record outsourcing", "health", "*", ["C16"], 14],
  ["aggregation in reporting", "personal",
    ["reporting-warehouse", "backup-store", "test-environment", "archive-store"], ["C09"], 20],
  ["field summarization of measurement", "measurement",
    ["reporting-warehouse", "backup-store", "log-collection-pipeline"], [], 10],
];

const INIT_CONTROLS = required(SYSTEM), INIT_VOLUME = volume(SYSTEM);
const apply = (type, target, residual) => {
  const next = SYSTEM.map((s) => (target === "*" || target.includes(s.name))
    ? { ...s, type: s.type.filter((t) => t !== type) } : s);
  const k = required(next);
  for (const a of residual) k.add(a);
  return { next, k };
};

console.log(`start: ${INIT_CONTROLS.size} controls, ${INIT_VOLUME.toLocaleString("en-US")} ` +
  `evidence items in the period, ${SYSTEM.length} systems`);
const y = gen([36, 9, 10, 9, 16, 6, 11]);
console.log("\n" + y("action", "systems", "controls", "dropped", "evidence items", "days",
  "items/day"));
const result = [];
for (const [name, type, target, residual, days] of ACTION) {
  const { next, k } = apply(type, target, residual);
  const h = volume(next) + residual.reduce((a, x) => a + CONTROL[x].item, 0);
  const touched = SYSTEM.filter((s) => (target === "*" || target.includes(s.name)) &&
    s.type.includes(type)).length;
  result.push({ name, dropped: INIT_CONTROLS.size - k.size, fell: INIT_VOLUME - h, days });
  console.log(y(name, touched, k.size, INIT_CONTROLS.size - k.size, h.toLocaleString("en-US"),
    days, ((INIT_VOLUME - h) / days).toFixed(0)));
}

const order = (f) => [...result].sort((a, b) => f(b) - f(a)).map((s) => s.name);
const byDropped = order((s) => s.dropped), byVolume = order((s) => s.fell),
  byRate = order((s) => s.fell / s.days);
console.log(`\nby controls dropped : ${byDropped.join(" > ")}`);
console.log(`by items fallen      : ${byVolume.join(" > ")}`);
console.log(`by rate per day      : ${byRate.join(" > ")}`);

// The difference between removing a type from every system and removing it partially
const partial = result.filter((s) => s.dropped === 0);
console.log(`\n${result.length - partial.length} actions removing a type from every system drop ` +
  `controls; ${partial.length} actions removing it partially drop no controls at all but reduce ` +
  `${partial.reduce((a, s) => a + s.fell, 0).toLocaleString("en-US")} evidence items`);
const RESIDUAL = ["C04", "C16"];
const both = apply("payment-card", "*", RESIDUAL).next
  .map((s) => ({ ...s, type: s.type.filter((t) => t !== "health") }));
const afterBoth = required(both);
for (const a of RESIDUAL) afterBoth.add(a);
console.log(`removing two types at once: ${INIT_CONTROLS.size - afterBoth.size} of ` +
  `${INIT_CONTROLS.size} controls disappear, ${afterBoth.size} remain; ` +
  `${RESIDUAL.map((k) => CONTROL[k].name).join(" and ")} come back as residual controls`);
console.log(`of the remaining ${afterBoth.size} controls, ${TYPE["personal"].length} come from ` +
  `the personal data type; evidence items in the period ` +
  `${[...afterBoth].reduce((a, k) => a + CONTROL[k].item, 0).toLocaleString("en-US")}`);
```

```
start: 20 controls, 24,394 evidence items in the period, 16 systems

action                                systems  controls  dropped  evidence items  days  items/day
token and gateway outsourcing               6        16        4          22,586    30         60
health record outsourcing                   5        17        3          23,043    14         97
aggregation in reporting                    4        20        0          22,911    20         74
field summarization of measurement          3        20        0          23,263    10        113

by controls dropped : token and gateway outsourcing > health record outsourcing > aggregation in reporting > field summarization of measurement
by items fallen      : token and gateway outsourcing > aggregation in reporting > health record outsourcing > field summarization of measurement
by rate per day      : field summarization of measurement > health record outsourcing > aggregation in reporting > token and gateway outsourcing

2 actions removing a type from every system drop controls; 2 actions removing it partially drop no controls at all but reduce 2,614 evidence items
removing two types at once: 7 of 20 controls disappear, 13 remain; validation of the tokenization boundary and vendor assessment come back as residual controls
of the remaining 13 controls, 9 come from the personal data type; evidence items in the period 2,052
```

The fourth column is the lesson's harsh result. The actions that remove personal data from four
systems and measurement data from three systems **eliminate no control at all.** The reason is
FW25: a control disappears only once no system that requires it remains; since personal data
appears in eleven systems, removing it from four of them does not shorten the list. These two
actions still pay off — they reduce evidence items by 2,614 — but what they gain is not the control
list, it is the **evidence volume**. Two different gains and two different decisions; folding them
into one heading produces an unmeasurable sentence like "we reduced the data, so our compliance
load went down."

The two actions that remove a type from every system really do drop controls: four for payment
card data, three for health data. But the number dropped is less than the number the type brought.
Payment card data had brought nine controls; removing it drops six unique controls, and then two
come back as **residual controls** — validation of the boundary that keeps the data out, and
assessment of the party it was outsourced to. Outsourcing the data does not zero out the
obligation; it moves it to **the boundary itself**.

The three rankings give three different lists, and none of them is wrong. By controls dropped, the
token action comes first; by rate per day, it comes last, and field summarization of measurement
moves to the front. The choice between dropping four controls with a thirty-day effort and
dropping no controls but reducing 1,131 evidence items with a ten-day effort depends on what the
organization experiences as the real constraint: the length of the audit list, or the labor of
compiling evidence. The last line writes the limit — even after removing two types at once,
thirteen of the twenty controls remain standing, and nine of them come from the personal data
type.

## Summary

- Part of the compliance requirements arises not from what the organization does but from which
  data type it touches; the four types bring 9, 8, 9, and 3 extra controls respectively.
- Summed separately, the types produce 29 controls; the union produces 20: because nine controls
  repeat across more than one type, the control cost of a second data type is lower than the
  first.
- Control load accumulates in systems that collect data independent of its source: the backup
  store takes on all twenty controls because it carries all four types; nine multi-type systems'
  load is 129, seven single-type systems' load is 44.
- A control disappears only once no system that requires it remains: removing personal data from
  four systems and measurement data from three eliminates no control at all, only reducing 2,614
  evidence items.
- Removing a type entirely drops four and three controls, but residual controls come back:
  outsourcing the data does not zero out the obligation, it moves it to the boundary itself. When
  two types are removed at once, thirteen of the twenty controls remain standing.
- Controls dropped, evidence items reduced, and gain per unit day produce three different
  rankings; the action that drops the most controls comes last per unit of effort.

## Next Step

One of this lesson's four types behaved differently from the others: personal data appears in
eleven systems, does not disappear through any narrowing, and even after the removal attempts, it
alone carries nine of the thirteen remaining controls. The reason is not just its prevalence.
For the other types, the obligation is written **to the party holding the data**; for personal
data, part of the obligation is given **to the person the data is about**, as a right, and that
right is exercised the moment it is requested.

The next lesson counts these rights as items: how many separate request types there are, how many
systems are searched while a request is being fulfilled, and how many requests are answered
incompletely because of a system missing from the inventory. Processing principles are handled the
same way — each principle is tied to a control and to an evidence item.
