Skip to content

Instantly share code, notes, and snippets.

@richmidwinter
Created April 30, 2026 13:22
Show Gist options
  • Select an option

  • Save richmidwinter/f986d21beb82b9039f72c81ee3a22d8a to your computer and use it in GitHub Desktop.

Select an option

Save richmidwinter/f986d21beb82b9039f72c81ee3a22d8a to your computer and use it in GitHub Desktop.
Review your obligations as proposed under the Cyber Security and Resilience (Network and Information Systems) Bill — the UK government's proposed update to the NIS 2018 regulations.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>UK Cyber Compliance Explorer</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
href="https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700&family=Epilogue:ital,wght@0,300;0,400;0,500;1,300&display=swap"
rel="stylesheet"
/>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--bg: #0a0a0a;
--surface: #141414;
--border: #242424;
--border2: #333;
--text: #f0ede8;
--sub: #b0aaa0; /* body text — was #999, now much more readable */
--muted: #a0a0a0; /* secondary labels — was #888 */
--faint: #3a3a3a;
--accent: #e8f542;
--red: #ff5555;
--blue: #5599ff;
--new-col: #ff6b35;
--tight: #ffaa00;
}
html {
font-size: 15px;
}
body {
background: var(--bg);
color: var(--text);
font-family: 'Epilogue', sans-serif;
font-weight: 300;
min-height: 100vh;
letter-spacing: 0.01em;
}
/* ── HEADER ── */
header {
padding: 2.5rem 3rem 2rem;
border-bottom: 1px solid var(--border);
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 2rem;
}
.wordmark {
font-family: 'Syne', sans-serif;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 1.1rem;
}
h1 {
font-family: 'Syne', sans-serif;
font-size: clamp(1.8rem, 3vw, 2.6rem);
font-weight: 700;
line-height: 1.05;
letter-spacing: -0.02em;
}
h1 .accent {
color: var(--accent);
}
.subtitle {
font-family: 'Epilogue', sans-serif;
font-size: 0.9rem;
font-weight: 300;
color: var(--sub);
margin-top: 0.6rem;
line-height: 1.4;
max-width: 480px;
}
.header-right {
text-align: right;
flex-shrink: 0;
}
.header-meta {
font-size: 0.8rem;
color: var(--muted);
letter-spacing: 0.04em;
line-height: 1.8;
margin-bottom: 0.75rem;
}
.bill-link {
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-family: 'Syne', sans-serif;
font-size: 0.65rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent);
text-decoration: none;
border: 1px solid rgba(232, 245, 66, 0.3);
border-radius: 4px;
padding: 0.35rem 0.7rem;
transition: all 0.15s;
}
.bill-link:hover {
background: rgba(232, 245, 66, 0.08);
border-color: var(--accent);
}
.bill-link svg {
flex-shrink: 0;
}
.status-dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
margin-right: 0.4rem;
vertical-align: middle;
animation: pulse 2.5s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.25;
}
}
/* ── PENALTY STRIP — always visible ── */
.penalty-section {
padding: 1.5rem 3rem;
border-bottom: 1px solid var(--border);
}
.penalty-label {
font-family: 'Syne', sans-serif;
font-size: 0.65rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 0.85rem;
}
.penalty-grid {
display: grid;
grid-template-columns: 180px repeat(4, 1fr);
gap: 1px;
background: var(--border);
border: 1px solid var(--border);
border-radius: 6px;
overflow: hidden;
font-size: 0.75rem;
}
.pen-head-cell {
background: var(--surface);
padding: 0.65rem 0.9rem;
font-family: 'Syne', sans-serif;
font-size: 0.62rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
display: flex;
align-items: center;
}
.pen-row-label {
background: var(--surface);
padding: 0.7rem 0.9rem;
font-size: 0.75rem;
color: var(--sub);
display: flex;
align-items: center;
}
.pen-cell {
background: var(--surface);
padding: 0.7rem 0.9rem;
display: flex;
align-items: center;
}
.pen-cell.nis-cell {
color: var(--sub);
font-size: 0.78rem;
}
.pen-cell.csr-cell {
font-size: 0.78rem;
}
.pen-val {
font-family: 'Syne', sans-serif;
font-size: 0.95rem;
font-weight: 700;
color: var(--accent);
letter-spacing: -0.01em;
}
.pen-na {
color: var(--muted);
font-style: italic;
font-size: 0.72rem;
}
.pen-change {
font-family: 'Syne', sans-serif;
font-size: 0.6rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
background: var(--tight);
color: #000;
border-radius: 3px;
padding: 2px 6px;
white-space: nowrap;
}
.pen-change.new {
background: var(--new-col);
}
/* ── ENTITY BAR ── */
.entity-bar {
padding: 1.1rem 3rem;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 1.25rem;
flex-wrap: wrap;
position: sticky;
top: 0;
z-index: 10;
background: rgba(10, 10, 10, 0.96);
backdrop-filter: blur(10px);
}
.entity-bar-label {
font-family: 'Syne', sans-serif;
font-size: 0.65rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
flex-shrink: 0;
}
.entity-chips {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
}
.e-chip {
display: flex;
align-items: center;
padding: 0.38rem 0.8rem;
border-radius: 99px;
border: 1px solid var(--border2);
font-family: 'Epilogue', sans-serif;
font-size: 0.78rem;
font-weight: 300;
color: var(--muted); /* unselected readable, not invisible */
cursor: pointer;
transition: all 0.15s;
user-select: none;
white-space: nowrap;
}
.e-chip:hover {
border-color: var(--muted);
color: var(--sub);
}
.e-chip.on {
background: var(--accent);
border-color: var(--accent);
color: #000;
font-weight: 500;
}
.e-chip input {
display: none;
}
.multi-note {
font-size: 0.7rem;
color: var(--muted);
margin-left: auto;
white-space: nowrap;
flex-shrink: 0;
}
/* ── MAIN ── */
main {
padding: 2.5rem 3rem;
}
.empty {
display: none;
padding: 5rem 2rem;
text-align: center;
color: var(--muted);
}
.empty.show {
display: block;
}
.empty-eyebrow {
font-family: 'Syne', sans-serif;
font-size: 0.7rem;
letter-spacing: 0.18em;
text-transform: uppercase;
margin-bottom: 1rem;
}
.empty h2 {
font-family: 'Syne', sans-serif;
font-size: 1.5rem;
font-weight: 700;
color: var(--text);
margin-bottom: 0.5rem;
letter-spacing: -0.02em;
}
.empty p {
font-size: 0.85rem;
line-height: 1.6;
color: var(--sub);
}
/* Section */
.ob-section {
margin-bottom: 2.5rem;
}
.ob-section-head {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border);
}
.ob-section-title {
font-family: 'Syne', sans-serif;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
}
.ob-section-count {
font-family: 'Syne', sans-serif;
font-size: 0.65rem;
font-weight: 600;
color: var(--muted);
margin-left: auto;
}
/* Obligation row */
.ob-row {
border: 1px solid var(--border);
border-radius: 6px;
margin-bottom: 6px;
overflow: hidden;
transition: border-color 0.15s;
animation: up 0.18s ease both;
}
@keyframes up {
from {
opacity: 0;
transform: translateY(5px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.ob-row:hover {
border-color: var(--border2);
}
.ob-row.open {
border-color: var(--border2);
}
.ob-trigger {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.85rem 1.1rem;
cursor: pointer;
background: var(--surface);
}
.ob-marker {
width: 3px;
align-self: stretch;
border-radius: 2px;
flex-shrink: 0;
}
.ob-title {
font-size: 0.9rem;
font-weight: 400;
flex: 1;
min-width: 0;
color: var(--text);
}
.ob-chips {
display: flex;
gap: 0.35rem;
flex-shrink: 0;
}
.chip {
font-family: 'Syne', sans-serif;
font-size: 0.6rem;
font-weight: 600;
letter-spacing: 0.07em;
text-transform: uppercase;
padding: 3px 8px;
border-radius: 3px;
}
.c-nis {
border: 1px solid var(--blue);
color: var(--blue);
}
.c-csr {
border: 1px solid var(--red);
color: var(--red);
}
.c-both {
border: 1px solid var(--border2);
color: var(--sub);
}
.c-new {
background: var(--new-col);
color: #000;
}
.c-tight {
background: var(--tight);
color: #000;
}
.ob-arrow {
color: var(--muted);
font-size: 0.8rem;
transition: transform 0.2s;
flex-shrink: 0;
}
.ob-row.open .ob-arrow {
transform: rotate(180deg);
color: var(--sub);
}
.ob-body {
display: none;
background: var(--surface);
}
.ob-row.open .ob-body {
display: block;
}
.ob-inner {
display: grid;
grid-template-columns: 1fr 1fr;
border-top: 1px solid var(--border);
}
.ob-col {
padding: 1.1rem 1.3rem;
}
.ob-col + .ob-col {
border-left: 1px solid var(--border);
}
.col-label {
font-family: 'Syne', sans-serif;
font-size: 0.85rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 0.5rem;
}
.ob-text {
font-size: 0.84rem;
line-height: 1.75;
color: var(--sub);
}
.ob-text.absent {
color: var(--muted);
font-style: italic;
}
.ob-delta {
padding: 0.85rem 1.3rem;
border-top: 1px solid var(--border);
font-size: 0.82rem;
line-height: 1.65;
color: var(--sub); /* was #888 — bumped up */
display: flex;
gap: 0.75rem;
align-items: flex-start;
}
.delta-pip {
width: 2px;
flex-shrink: 0;
align-self: stretch;
border-radius: 2px;
margin-top: 2px;
}
.delta-inner {
flex: 1;
}
.delta-head {
font-family: 'Syne', sans-serif;
font-size: 0.62rem;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 0.3rem;
}
.source-line {
padding: 0.65rem 1.3rem;
border-top: 1px solid var(--border);
font-size: 0.7rem;
color: var(--muted);
display: flex;
align-items: center;
gap: 0.4rem;
}
.source-line a {
color: inherit;
text-decoration: none;
border-bottom: 1px solid var(--faint);
transition: border-color 0.15s;
}
.source-line a:hover {
border-color: var(--accent);
}
.entity-tags {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
margin-top: 0.65rem;
}
.etag {
font-family: 'Syne', sans-serif;
font-size: 0.6rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted);
border: 1px solid var(--faint);
border-radius: 3px;
padding: 2px 6px;
}
.no-results {
display: none;
text-align: center;
padding: 3rem;
color: var(--muted);
font-size: 0.83rem;
}
.no-results.show {
display: block;
}
.regulator-section {
margin-top: 3rem;
padding-top: 2.5rem;
border-top: 1px solid var(--border);
}
.regulator-card {
border: 1px solid var(--border);
border-radius: 6px;
background: var(--surface);
padding: 1.25rem 1.4rem;
}
.regulator-name {
font-family: 'Syne', sans-serif;
font-size: 1rem;
font-weight: 700;
color: var(--text);
margin-bottom: 0.2rem;
}
.regulator-name a {
color: inherit;
text-decoration: none;
border-bottom: 1px solid var(--faint);
transition: border-color 0.15s;
}
.regulator-name a:hover {
border-color: var(--accent);
}
.regulator-scope {
font-size: 0.84rem;
color: var(--sub);
line-height: 1.6;
}
.header-logo {
height: 28px;
width: auto;
display: block;
margin-bottom: 0.75rem;
margin-left: auto;
}
footer {
padding: 3rem;
border-top: 1px solid var(--border);
text-align: center;
}
.footer-logo {
height: 36px;
width: auto;
margin-top: 1rem;
}
.footer-text {
font-size: 0.85rem;
color: var(--sub);
line-height: 1.6;
max-width: 480px;
margin: 0 auto;
}
.footer-text a {
color: var(--accent);
text-decoration: none;
border-bottom: 1px solid transparent;
transition: border-color 0.15s;
}
.footer-text a:hover {
border-color: var(--accent);
}
@media (max-width: 860px) {
header {
flex-direction: column;
align-items: flex-start;
}
.header-right {
text-align: left;
}
.header-logo {
margin-left: 0;
}
.penalty-section,
.entity-bar,
main {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.penalty-grid {
grid-template-columns: 1fr;
}
.pen-head-cell {
display: none;
}
.ob-inner {
grid-template-columns: 1fr;
}
.ob-col + .ob-col {
border-left: none;
border-top: 1px solid var(--border);
}
.multi-note {
display: none;
}
}
</style>
</head>
<body>
<!-- HEADER -->
<header>
<div>
<div class="wordmark">UK Cyber Regulation · Compliance Explorer</div>
<h1>
<span class="accent">NIS</span> & <span class="accent">CSR Bill</span><br />Obligations
</h1>
<p class="subtitle">
Review your obligations as proposed under the Cyber Security and Resilience (Network and
Information Systems) Bill — the UK government's proposed update to the NIS 2018
regulations.
</p>
</div>
<div class="header-right">
<a href="https://thecisonetwork.com" target="_blank" rel="noopener">
<img
src="https://thecisonetwork.com/images/logo.svg"
alt="The CISO Network"
class="header-logo"
/>
</a>
<div class="header-meta">
<span><span class="status-dot"></span>Bill at report stage, H.o.C.</span>
<span>As at April 2026 · Bill 385 · 59th Parliament</span>
</div>
<a
class="bill-link"
href="https://bills.parliament.uk/bills/4035"
target="_blank"
rel="noopener"
>
<svg
width="11"
height="11"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2 10L10 2M10 2H5M10 2V7"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
View bill on parliament.uk
</a>
</div>
</header>
<!-- PENALTY STRIP — always visible -->
<div class="penalty-section">
<div class="penalty-label">Penalty regime</div>
<div class="penalty-grid">
<!-- Header row -->
<div class="pen-head-cell">Breach type</div>
<div class="pen-head-cell" style="color: var(--blue)">NIS 2018</div>
<div class="pen-head-cell" style="color: var(--red)">CSR Bill</div>
<div class="pen-head-cell">Change</div>
<div class="pen-head-cell">Notes</div>
<!-- Row 1 -->
<div class="pen-row-label">Standard breach</div>
<div class="pen-cell nis-cell">Up to £17m</div>
<div class="pen-cell csr-cell">
<span class="pen-val">£10m</span
><span style="color: var(--muted); font-size: 0.75rem; margin-left: 0.4rem"
>/ 2% turnover</span
>
</div>
<div class="pen-cell"><span class="pen-change">Restructured</span></div>
<div class="pen-cell" style="font-size: 0.8rem; color: var(--sub)">
Whichever is higher — for large orgs the turnover figure will far exceed the nominal cap
</div>
<!-- Row 2 -->
<div class="pen-row-label">National security direction failure</div>
<div class="pen-cell nis-cell"><span class="pen-na">No equivalent</span></div>
<div class="pen-cell csr-cell">
<span class="pen-val">£17m</span
><span style="color: var(--muted); font-size: 0.75rem; margin-left: 0.4rem"
>/ 10% turnover</span
>
</div>
<div class="pen-cell"><span class="pen-change new">New</span></div>
<div class="pen-cell" style="font-size: 0.8rem; color: var(--sub)">
Highest tier — applies to the new ministerial direction power
</div>
<!-- Row 3 -->
<div class="pen-row-label">Continuing non-compliance</div>
<div class="pen-cell nis-cell"><span class="pen-na">No equivalent</span></div>
<div class="pen-cell csr-cell"><span class="pen-val">£100k / day</span></div>
<div class="pen-cell"><span class="pen-change new">New</span></div>
<div class="pen-cell" style="font-size: 0.8rem; color: var(--sub)">
Daily fine accrues until the breach is remediated
</div>
<!-- Row 4 -->
<div class="pen-row-label">Information notice failure</div>
<div class="pen-cell nis-cell"><span class="pen-na">No equivalent</span></div>
<div class="pen-cell csr-cell">
<span class="pen-val">£10m</span
><span style="color: var(--muted); font-size: 0.75rem; margin-left: 0.4rem"
>/ £50k daily</span
>
</div>
<div class="pen-cell"><span class="pen-change new">New</span></div>
<div class="pen-cell" style="font-size: 0.8rem; color: var(--sub)">
Failure to respond to regulator information requests or permit inspections
</div>
</div>
</div>
<!-- ENTITY BAR -->
<div class="entity-bar">
<span class="entity-bar-label">Organisation type</span>
<div class="entity-chips" id="entity-chips">
<label
class="e-chip"
data-entity="oes"
title="Organisations in essential sectors (energy, transport, health, water, digital infrastructure) that are designated by a competent authority as providing a service the public relies on."
><input type="checkbox" />OES</label
>
<label
class="e-chip"
data-entity="rdsp"
title="Online marketplaces, search engines and cloud computing providers. Micro and small enterprises are exempt; medium and large providers must self-register with the relevant authority."
><input type="checkbox" />RDSP</label
>
<label
class="e-chip"
data-entity="dc"
title="Facilities that house IT equipment for hosting or colocation. In scope if above capacity thresholds (enterprise 10 MW+; colocation 1 MW+ IT load)."
><input type="checkbox" />Data centre</label
>
<label
class="e-chip"
data-entity="msp"
title="Organisations providing ongoing managed IT services. In scope if medium or large (50+ employees or €10m+ turnover). Micro and small enterprises are exempt unless designated as critical suppliers."
><input type="checkbox" />MSP</label
>
<label
class="e-chip"
data-entity="llc"
title="Organisations that can remotely control the energy use of smart appliances, batteries or electric vehicles to balance grid load."
><input type="checkbox" />Large load controller</label
>
<label
class="e-chip"
data-entity="dcs"
title="A supplier designated by a regulator as critical to a regulated organisation's ability to provide its essential service. Carries full OES-equivalent obligations and cannot opt out."
><input type="checkbox" />Designated critical supplier</label
>
<label
class="e-chip"
data-entity="general"
title="An organisation that does not fall within any regulated category. Not directly subject to NIS or CSR duties, but may face contractual security requirements from regulated customers."
><input type="checkbox" />General org (out of scope)</label
>
</div>
<span class="multi-note">Multiple types? Select all that apply.</span>
</div>
<!-- MAIN -->
<main>
<div class="empty show" id="empty">
<div class="empty-eyebrow">Getting started</div>
<h2>Select your organisation type</h2>
<p>
Choose one or more entity types above.<br />Your obligations under NIS 2018 and the CSR
Bill will appear side by side.<br />Multiple types can be selected if your organisation
spans more than one category.
</p>
</div>
<div id="content" style="display: none">
<div id="ob-list"></div>
<div class="no-results" id="no-results">No obligations found for the selected filters.</div>
</div>
<div class="regulator-section" id="regulator-section">
<div class="ob-section-head">
<span class="ob-section-title">Find your regulator</span>
</div>
<p style="font-size: 0.85rem; color: var(--sub); margin-bottom: 1.25rem; line-height: 1.6">
Select your industry to see which competent authority regulates you under NIS 2018 and the
CSR Bill.
</p>
<div class="entity-chips" id="industry-chips" style="margin-bottom: 1.5rem"></div>
<div id="regulator-result"></div>
</div>
<div class="regulator-section" style="margin-top: 1.5rem; padding-top: 1.5rem">
<div class="ob-section-head">
<span class="ob-section-title">Simultaneous notification</span>
</div>
<div class="regulator-card">
<div class="regulator-name">
<a href="https://www.ncsc.gov.uk/" target="_blank" rel="noopener"
>National Cyber Security Centre (NCSC)</a
>
</div>
<div class="regulator-scope">
Under the CSR Bill, you must notify the NCSC <strong>simultaneously</strong> with your
competent authority within 24 hours of becoming aware of a significant incident.
</div>
</div>
</div>
</main>
<footer>
<p class="footer-text">
Need help with NIS or CSR compliance?
<a href="https://thecisonetwork.com" target="_blank" rel="noopener">The CISO Network</a>
can help.
</p>
<a href="https://thecisonetwork.com" target="_blank" rel="noopener">
<img
src="https://thecisonetwork.com/images/logo.svg"
alt="The CISO Network"
class="footer-logo"
/>
</a>
</footer>
<script>
const DATA = [
{
id: 'ir1',
cat: 'reporting',
title: 'Initial incident notification',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Notify the competent authority without undue delay — generally interpreted as within 72 hours of becoming aware of a significant incident.',
csr: 'Notify the competent authority AND NCSC simultaneously within 24 hours of becoming aware of a significant incident.',
delta_type: 'tighter',
delta:
'Deadline tightened from 72 hours to 24 hours. Notification must now go to both the competent authority and NCSC simultaneously — not the competent authority alone.',
source:
'CSR Bill, Clause 15 (new NIS Regulations 11(5), 11(8); 11A(5), 11A(7); 12A(5), 12A(7); 14E(5), 14E(7))',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'ir2',
cat: 'reporting',
title: 'Full incident report',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'Submit a full incident report within 72 hours of the incident covering root cause, full scope of impact, and affected systems or services.',
delta_type: 'new',
delta:
'Introduces a two-stage regime: 24h initial notification followed by a 72h full report. NIS 2018 had only a single notification obligation with no separate full-report requirement.',
source:
'CSR Bill, Clause 15 (new NIS Regulations 11(5), 11(8); 11A(5), 11A(7); 12A(5), 12A(7); 14E(5), 14E(7))',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'ir3',
cat: 'reporting',
title: 'Reportable incident threshold',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Report incidents that have a significant impact on the continuity of essential or digital services — i.e. events actively causing disruption.',
csr: 'Report incidents that have or are capable of having a significant impact. Near-misses, security compromises, and unauthorised access — even without visible disruption — are now reportable.',
delta_type: 'tighter',
delta:
'The threshold shifts from actual to potential impact. Near-miss events and security compromises without disruption must now be reported.',
source:
'CSR Bill, Clause 15 (new NIS Regulations 11(5), 11(8); 11A(5), 11A(7); 12A(5), 12A(7); 14E(5), 14E(7))',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'ir4',
cat: 'reporting',
title: 'Direct customer notification',
entities: ['rdsp', 'dc', 'msp'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'Directly notify affected UK customers of significant incidents, setting out the incident particulars and underlying causes. This is a direct obligation — it does not flow via the regulator.',
delta_type: 'new',
delta:
'Entirely new for data centres, RDSPs, and MSPs. You must proactively notify affected customers directly. The regulator does not do this on your behalf.',
source: 'CSR Bill, Clause 16 (new NIS Regulation 14G)',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'sec1',
cat: 'security',
title: 'Appropriate and proportionate security measures',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'same',
nis: 'Take appropriate and proportionate technical and organisational measures to manage risks to the security of network and information systems. Regulators assess compliance against the NCSC CAF.',
csr: 'Core duty retained unchanged. The NCSC CAF remains the primary benchmark. The Cyber Governance Code of Practice (2024) adds board-level obligations alongside.',
delta_type: 'same',
delta:
'The fundamental security duty is unchanged. However, regulators now have broader proactive investigatory powers — compliance can be assessed without waiting for an incident to occur.',
source: 'NIS Regulations 2018, Regulation 10 (retained)',
},
{
id: 'sec2',
cat: 'security',
title: 'Business continuity and resilience',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Maintain appropriate measures to ensure business continuity in the event of a significant incident.',
csr: 'Enhanced resilience duties including tested incident response plans, documented recovery time objectives, and evidenced continuity arrangements. Regulators can request proof of testing.',
delta_type: 'tighter',
delta:
'Regulators gain powers to proactively request evidence of continuity testing rather than only assessing arrangements after an incident occurs.',
source:
'NIS Regulations 2018, Regulation 10(1)(b) (retained); CSR Bill, Clauses 20 and 34',
},
{
id: 'sec3',
cat: 'security',
title: 'National security directions',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'The Secretary of State may direct your organisation to take specific action during credible national security cyber threats — such as enhanced monitoring, network segmentation, or access restrictions. These directions take precedence over other legal and contractual obligations. Compliance timelines will be short.',
delta_type: 'new',
delta:
'Entirely new executive power with no NIS 2018 equivalent. Non-compliance carries the highest penalty tier: up to £17m or 10% of worldwide turnover.',
source: 'CSR Bill, Clauses 43–44',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'gov1',
cat: 'governance',
title: 'NCSC CAF alignment',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'same',
nis: 'Regulators assess OES compliance through the NCSC CAF — four objectives covering managing security risk, protecting systems, detecting events, and minimising impact.',
csr: 'CAF remains the primary regulatory benchmark. All newly in-scope entities (data centres, MSPs, large load controllers, DCS) will be assessed against CAF from commencement.',
delta_type: 'same',
delta:
'CAF scope expands to cover all newly regulated entity types. If your organisation is newly in scope, begin a CAF self-assessment before Royal Assent.',
source:
'NIS Regulations 2018, Regulation 10 / CSR Bill, Clause 29 (regulations framework)',
},
{
id: 'gov2',
cat: 'governance',
title: 'Cyber Governance Code of Practice',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs', 'general'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'The Cyber Governance Code of Practice (2024) is explicitly referenced alongside this bill. Directors must understand cyber risk, receive regular briefings, approve the cyber strategy, and be capable of responding to significant incidents. Not statutory, but regulators expect alignment.',
delta_type: 'new',
delta:
'Applies to all organisations including those not directly regulated. Treat it as a de facto requirement — it will feature in regulatory assessments and client or investor due diligence.',
source: 'Government guidance — not statutory',
},
{
id: 'gov3',
cat: 'governance',
title: 'Board-level accountability',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Senior management must take responsibility for security measures. No specific board reporting or skills requirement.',
csr: 'Explicit requirement for board engagement: boards must be capable of understanding, governing, and responding to cyber risk. Regulators can examine board-level governance arrangements during proactive inspections.',
delta_type: 'tighter',
delta:
'Board governance moves from implicit to explicit. Regulators can now proactively assess board capability, not just whether technical controls are in place.',
source:
'NIS Regulations 2018, Regulation 10 (senior management) / CSR Bill (strengthened)',
},
{
id: 'gov4',
cat: 'governance',
title: 'Registration and designation',
entities: ['oes', 'rdsp'],
leg: 'nis',
status: 'same',
nis: 'OES must be identified and designated by competent authorities. RDSPs above the threshold must self-register with the relevant authority. Maintain accurate registration details.',
csr: 'Registration requirements carry forward unchanged. Newly in-scope entities will be subject to designation processes by competent authorities after Royal Assent.',
delta_type: 'same',
delta:
'No material change for existing OES and RDSPs. Newly in-scope entities should expect designation processes to begin in the period following Royal Assent.',
source: 'NIS Regulations 2018, Regulation 8 (OES) / Regulation 14 (RDSP)',
},
{
id: 'sc1',
cat: 'supply',
title: 'Supply chain security management',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Consider supply chain risks as part of overall security risk management. No specific statutory supply chain obligations.',
csr: 'Supply chain resilience becomes a statutory obligation. You must identify critical suppliers, assess their security posture, implement contractual controls, and maintain continuity plans for supplier failure.',
delta_type: 'tighter',
delta:
'Supply chain security moves from best practice to statutory duty. Secondary legislation will specify minimum contractual requirements for critical suppliers.',
source:
'NIS Regulations 2018, Regulation 10 (risk management); CSR Bill, Clause 29 (secondary legislation framework)',
},
{
id: 'sc2',
cat: 'supply',
title: 'Designated Critical Supplier obligations',
entities: ['dcs'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'If designated as a DCS by a competent authority, you carry the full equivalent of OES obligations — security measures, incident reporting, CAF alignment, and regulator inspection duties. Designation is made by regulators; you cannot opt out.',
delta_type: 'new',
delta:
'Entirely new category. If you supply an OES or RDSP and your failure would significantly impact their essential service, you may be designated. Review all regulated customer relationships now.',
source: 'CSR Bill, Clause 12 (new NIS Regulation 14H)',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'sc3',
cat: 'supply',
title: 'Supplier contract requirements',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'Contracts with critical suppliers must include minimum cyber security standards, incident disclosure obligations with timelines, right-to-audit clauses, and continuity provisions. Secondary legislation will define the minimum terms.',
delta_type: 'new',
delta:
'New contractual obligations flowing in both directions — into your supply chain, and from your regulated customers down to you. Begin contract reviews now; renegotiating major contracts takes time.',
source: 'CSR Bill, Clause 29 (secondary legislation framework)',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
{
id: 'sc4',
cat: 'supply',
title: 'Supply chain obligations (indirect)',
entities: ['general'],
leg: 'csr',
status: 'new',
nis: null,
csr: 'Not directly regulated, but your OES, RDSP, data centre, and MSP customers will be required to impose contractual cyber security standards on you as part of their own statutory supply chain obligations. Expect minimum security standards, incident disclosure requirements, and right-to-audit clauses.',
delta_type: 'new',
delta:
"Indirect but material impact. Regulated customers' statutory supply chain duties will flow down contractually — even without a direct regulatory obligation on you.",
source: 'Derived from CSR Bill, Clauses 12 and 29',
},
{
id: 'reg1',
cat: 'regulator',
title: 'Regulator inspection and information powers',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Competent authorities may request information and carry out audits following an incident or on a scheduled basis. Generally reactive in practice.',
csr: 'Regulators gain proactive investigation powers — information requests and inspections without waiting for an incident. A cost-recovery mechanism means enforcement costs can be recovered from the investigated organisation.',
delta_type: 'tighter',
delta:
'The regulatory model shifts from reactive to proactive. Expect regulators to develop structured inspection programmes. Build internal audit-readiness now, not after an incident.',
source: 'NIS Regulations 2018 / CSR Bill, Clauses 20, 34 and Schedule 1',
},
{
id: 'reg2',
cat: 'regulator',
title: 'Penalty exposure',
entities: ['oes', 'rdsp', 'dc', 'msp', 'llc', 'dcs'],
leg: 'both',
status: 'tightened',
nis: 'Penalties up to £17m for the most serious failures. In practice, NIS penalties have been rare and significantly below the maximum.',
csr: 'New tiered regime with GDPR-style turnover-based fines. See penalty table above for full breakdown. Turnover-based figures will far exceed nominal caps for any significant business.',
delta_type: 'tighter',
delta:
'A company with £500m global revenue faces up to £10m for a standard breach and up to £50m for failing to follow a national security direction. These are not hypothetical — regulators are being given broader investigatory tools to enforce them.',
source:
'CSR Bill, Clause 21 (new NIS Regulation 18(8)–(9)); Clause 49(2) (national security directions)',
sourceUrl: 'https://publications.parliament.uk/pa/bills/cbill/59-01/0385/240385.pdf',
},
];
const CAT_COLORS = {
reporting: '#e07b39',
security: '#5599ff',
governance: '#e8f542',
supply: '#b44bff',
regulator: '#888',
};
const CAT_NAMES = {
reporting: 'Incident reporting',
security: 'Security measures',
governance: 'Governance',
supply: 'Supply chain',
regulator: 'Regulator duties',
};
const ENTITY_NAMES = {
oes: 'OES',
rdsp: 'RDSP',
dc: 'Data centre',
msp: 'MSP',
llc: 'Large load ctrl',
dcs: 'DCS',
general: 'General org',
};
const ENTITY_TOOLTIPS = {
oes: 'Organisations in essential sectors (energy, transport, health, water, digital infrastructure) designated by a competent authority.',
rdsp: 'Online marketplaces, search engines and cloud computing providers. Micro and small enterprises are exempt; medium and large providers must self-register.',
dc: 'Facilities housing IT equipment for hosting or colocation. In scope above capacity thresholds (enterprise 10 MW+; colocation 1 MW+).',
msp: 'Organisations providing ongoing managed IT services. In scope if medium or large (50+ employees or €10m+ turnover). Micro and small enterprises are exempt unless designated critical suppliers.',
llc: 'Organisations that can remotely control energy use of smart appliances, batteries or electric vehicles to balance grid load.',
dcs: "A supplier designated by a regulator as critical to a regulated organisation's essential service. Carries full OES-equivalent obligations.",
general:
'An organisation not falling within any regulated category. Not directly subject to NIS or CSR duties but may face contractual flow-downs.',
};
let entities = new Set();
const INDUSTRIES = [
{
id: 'energy',
name: 'Energy',
regulators: [
{ name: 'Ofgem', url: 'https://www.ofgem.gov.uk/', detail: 'Electricity and gas' },
{
name: 'North Sea Transition Authority (NSTA)',
url: 'https://www.nstauthority.co.uk/',
detail: 'Oil and gas infrastructure',
},
],
},
{
id: 'transport',
name: 'Transport',
regulators: [
{
name: 'Civil Aviation Authority (CAA)',
url: 'https://www.caa.co.uk/',
detail: 'Air traffic control and airports',
},
{
name: 'Office of Rail and Road (ORR)',
url: 'https://www.orr.gov.uk/',
detail: 'Rail transport',
},
{
name: 'Maritime and Coastguard Agency (MCA)',
url: 'https://www.gov.uk/government/organisations/maritime-and-coastguard-agency',
detail: 'Maritime transport',
},
{
name: 'Department for Transport (DfT)',
url: 'https://www.gov.uk/government/organisations/department-for-transport',
detail: 'Ports and road traffic authorities',
},
],
},
{
id: 'health',
name: 'Health',
regulators: [
{
name: 'Department of Health and Social Care / NHS England',
url: 'https://www.gov.uk/government/organisations/department-of-health-and-social-care',
detail: 'NHS trusts and foundation trusts',
},
{
name: 'Care Quality Commission (CQC)',
url: 'https://www.cqc.org.uk/',
detail: 'Social care providers',
},
],
},
{
id: 'water',
name: 'Water',
regulators: [
{
name: 'Ofwat',
url: 'https://www.ofwat.gov.uk/',
detail: 'Water and sewerage services',
},
{
name: 'Drinking Water Inspectorate (DWI)',
url: 'https://www.gov.uk/government/organisations/drinking-water-inspectorate',
detail: 'Drinking water quality',
},
],
},
{
id: 'digital',
name: 'Digital services',
regulators: [
{
name: "Information Commissioner's Office (ICO)",
url: 'https://ico.org.uk/',
detail:
'Relevant Digital Service Providers (RDSPs) and Relevant Managed Service Providers (RMSPs)',
},
],
},
{
id: 'datacentre',
name: 'Data centre',
regulators: [
{
name: 'Ofcom',
url: 'https://www.ofcom.org.uk/',
detail:
'Data centres above capacity thresholds (enterprise 10 MW+; colocation 1 MW+ IT load)',
},
],
},
];
function renderIndustries() {
const container = document.getElementById('industry-chips');
if (!container) return;
container.innerHTML = INDUSTRIES.map(
ind => `
<label class="e-chip" data-industry="${ind.id}" style="cursor:pointer;">
<input type="radio" name="industry" value="${ind.id}" style="display:none;" />
${ind.name}
</label>
`
).join('');
container.querySelectorAll('label').forEach(label => {
const input = label.querySelector('input');
input.addEventListener('change', () => {
container.querySelectorAll('label').forEach(l => l.classList.remove('on'));
if (input.checked) {
label.classList.add('on');
showRegulator(label.dataset.industry);
}
});
});
}
function showRegulator(id) {
const ind = INDUSTRIES.find(i => i.id === id);
if (!ind) return;
const regulatorsHtml = ind.regulators
.map(
(reg, idx) => `
<div style="${idx > 0 ? 'margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border);' : ''}">
<div class="regulator-name">
${reg.url ? `<a href="${reg.url}" target="_blank" rel="noopener">${reg.name}</a>` : reg.name}
</div>
<div class="regulator-scope">${reg.detail}</div>
</div>
`
)
.join('');
document.getElementById('regulator-result').innerHTML = `
<div class="regulator-card" style="animation: up 0.18s ease both;">
<div style="font-family: 'Syne', sans-serif; font-size: 0.62rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.75rem;">${ind.name} — Competent authority</div>
${regulatorsHtml}
</div>
`;
}
document.addEventListener('DOMContentLoaded', () => {
renderIndustries();
document.querySelectorAll('#entity-chips label').forEach(label => {
const e = label.dataset.entity;
const cb = label.querySelector('input');
cb.addEventListener('change', () => {
if (cb.checked) {
// General org is mutually exclusive with in-scope types
if (e === 'general') {
entities.clear();
document
.querySelectorAll('#entity-chips label')
.forEach(l => l.classList.remove('on'));
document.querySelectorAll('#entity-chips input').forEach(i => (i.checked = false));
cb.checked = true;
} else {
const generalLabel = document.querySelector(
'#entity-chips label[data-entity="general"]'
);
const generalCb = generalLabel?.querySelector('input');
if (generalCb) {
entities.delete('general');
generalLabel.classList.remove('on');
generalCb.checked = false;
}
}
entities.add(e);
label.classList.add('on');
} else {
entities.delete(e);
label.classList.remove('on');
}
render();
});
});
render();
});
function toggle(id) {
document.getElementById('ob-' + id).classList.toggle('open');
}
function render() {
const empty = document.getElementById('empty');
const content = document.getElementById('content');
if (entities.size === 0) {
empty.classList.add('show');
content.style.display = 'none';
return;
}
empty.classList.remove('show');
content.style.display = 'block';
const vis = DATA.filter(ob => ob.entities.some(e => entities.has(e)));
const groups = {};
vis.forEach(ob => {
(groups[ob.cat] = groups[ob.cat] || []).push(ob);
});
let html = '';
['reporting', 'security', 'governance', 'supply', 'regulator'].forEach(c => {
if (!groups[c]) return;
html += `<div class="ob-section">
<div class="ob-section-head">
<span style="width:6px;height:6px;border-radius:50%;background:${CAT_COLORS[c]};display:inline-block;flex-shrink:0"></span>
<span class="ob-section-title">${CAT_NAMES[c]}</span>
<span class="ob-section-count">${groups[c].length}</span>
</div>`;
groups[c].forEach((ob, i) => {
html += card(ob, i * 30);
});
html += '</div>';
});
document.getElementById('ob-list').innerHTML = html;
document.getElementById('no-results').classList.toggle('show', vis.length === 0);
}
function card(ob, delay) {
const markerCol = ob.leg === 'nis' ? '#5599ff' : ob.leg === 'csr' ? '#ff5555' : '#3a3a3a';
const legChip =
ob.leg === 'nis'
? '<span class="chip c-nis">NIS only</span>'
: ob.leg === 'csr'
? '<span class="chip c-csr">CSR Bill</span>'
: '<span class="chip c-both">NIS + CSR</span>';
const statChip =
ob.status === 'new'
? '<span class="chip c-new">New</span>'
: ob.status === 'tightened'
? '<span class="chip c-tight">Tightened</span>'
: '';
const eTags = ob.entities
.filter(e => entities.has(e))
.map(
e =>
`<span class="etag" title="${ENTITY_TOOLTIPS[e] || ENTITY_NAMES[e]}">${ENTITY_NAMES[e]}</span>`
)
.join('');
const nisHtml = ob.nis
? `<p class="ob-text">${ob.nis}</p>`
: `<p class="ob-text absent">No obligation under NIS 2018.</p>`;
const csrHtml = ob.csr
? `<p class="ob-text">${ob.csr}</p>`
: `<p class="ob-text absent">No change introduced by the CSR Bill.</p>`;
const dc =
ob.delta_type === 'new' ? 'new' : ob.delta_type === 'tighter' ? 'tighter' : 'same';
const pipCol =
dc === 'new' ? 'var(--new-col)' : dc === 'tighter' ? 'var(--tight)' : 'var(--muted)';
const dlabel =
dc === 'new' ? 'New obligation' : dc === 'tighter' ? 'Tightened' : 'Unchanged';
const deltaHtml = ob.delta
? `
<div class="ob-delta">
<div class="delta-pip" style="background:${pipCol}"></div>
<div class="delta-inner">
<div class="delta-head" style="color:${pipCol}">${dlabel}</div>
${ob.delta}
</div>
</div>`
: '';
const entityFooter = eTags
? `<div style="padding:.4rem 1.3rem .85rem"><div class="entity-tags">${eTags}</div></div>`
: '';
const sourceHtml = ob.source
? `<div class="source-line">
${ob.sourceUrl ? `<a href="${ob.sourceUrl}" target="_blank" rel="noopener">${ob.source}</a>` : ob.source}
</div>`
: '';
return `<div class="ob-row" id="ob-${ob.id}" style="animation-delay:${delay}ms">
<div class="ob-trigger" onclick="toggle('${ob.id}')">
<div class="ob-marker" style="background:${markerCol}"></div>
<span class="ob-title">${ob.title}</span>
<div class="ob-chips">${legChip}${statChip}</div>
<span class="ob-arrow">▾</span>
</div>
<div class="ob-body">
<div class="ob-inner">
<div class="ob-col">
<div class="col-label" style="color:var(--blue)">NIS 2018</div>
${nisHtml}
</div>
<div class="ob-col">
<div class="col-label" style="color:var(--red)">CSR Bill</div>
${csrHtml}
</div>
</div>
${deltaHtml}
${entityFooter}
${sourceHtml}
</div>
</div>`;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment