# Energy compliance: NERC CIP, IEC 62351 & Rule 21

NERC CIP, IEC 62351, CA Rule 21, EU NIS2 and the EU Network Code on Cybersecurity all press a DER control plane on one question: which party is on this connection, is it authorised, and can you prove it and cut it off?

A backend gated by OAuth bearer tokens and shared, NAT'd egress IPs cannot answer that. A routable, DANE-provable, one-call-revocable IPv6 `/128` per party can. It produces the log, the attribution and the kill-switch those frameworks want as *evidence*, not as a paragraph in a policy binder. This page is the honest map of where that evidence fits (and, just as important, where it does not).

> **How to read this page.** We grade every control into one of three verdicts and never blur them. **DIRECT-ADDITIVE**: Whisper produces evidence that maps to the control (as one input to your package, never the whole standard). **COMPLEMENTARY**: the framework mandates the sector's own PKI or certificate; Whisper sits alongside it and can DANE-pin it, but does *not* satisfy that requirement. **STRETCH**: controls Whisper is honestly irrelevant to; we list them so nobody over-claims.

## What every framework is really asking

Read the DER regulations side by side and the same three questions surface, phrased in five vocabularies:

- **Identity**: who or what is on the other end of this DER-to-cloud connection, and can a third party verify it without trusting your word for it?
- **Attribution & monitoring**: what did that party do, to which destinations, who is enumerating your fleet, and can you show a continuous, non-repudiable record?
- **Response**: when one party turns hostile, or a vendor's access should end, can you contain it, provably and fast, across every operator?

None of these is a logging problem you fix with more log lines. They are *identity* problems: you cannot attribute, monitor or contain an actor that has no stable, provable identity in the first place. The IEEE 2030.5 `LFDI` is a genuinely good key-derived name, but it lives in a private `SERCA→MCA→MICA` root, is allow-listed per-utility out-of-band, is not IP/DNS-addressable, and by its own managed-PKI rules *cannot be revoked*. Whisper's job here is to give every party on the cloud/IP boundary an identity that *is* addressable, publicly verifiable and revocable, then let the standard toolchain read the evidence off it.

## Three verdicts, stated up front

Before a single row of the map, here's the grading rule: an energy-compliance page that claimed to "satisfy NERC CIP" would be lying. Whisper is a network primitive. Against a given control it does exactly one of three things, and we mark which:

- **DIRECT-ADDITIVE**: Whisper produces the evidence, as one input to your package. CIP-005 R3 · CIP-013 R1.2 · NIS2 Art.21 · NCCS Art.33 · NISTIR 7628 · Sandia.
- **COMPLEMENTARY**: sits alongside, DANE-pins the cert, never satisfies it. Rule 21 / CSIP · UL 1741-SB · SunSpec PKI · IEC 62351-9 · ISO 15118 / OCPP · NIST IR 8498.
- **STRETCH (not claimed)**: controls Whisper is honestly irrelevant to. CIP-010 · CIP-005 R2 · CIP-007 R5.

The honesty rule is the whole point of this page: a network primitive earns a verdict per control, and we mark `DIRECT-ADDITIVE`, `COMPLEMENTARY` or `STRETCH` so a buyer, an auditor and a regulator all read the same thing.

## The evidence: real, and shipped

Everything this page grades DIRECT-ADDITIVE rests on primitives that exist and answer *today*. Each is checkable with `dig`, `curl`, or one control-plane call over the public API: `POST https://graph.whisper.security/api/query` with your `X-API-Key`.

> **Shipped & live.** The device-derived `/128`, per-`/128` logs, `op:lookups`, one-call `revoke`, the Merkle transparency log and the attribution graph are in production. The **Splunk** connector ships. Everything grouped under *roadmap* below is labelled as such: nothing on this page is described as working unless you can reproduce it.

### A device-derived `/128` identity

A DER already holds a key: the public half of its IEEE 2030.5 `EndDevice` certificate, a SunSpec/Kyrio device cert, a TPM, or a secure element. Whisper derives a deterministic IPv6 `/128` from that key's *public* `SubjectPublicKeyInfo`, with the `LFDI` (or a DER serial) as the domain separator. The address is tenant-bound (fleet-unlinkable to an outsider), DNSSEC-anchored, DANE-EE `3 1 1` pinned, and RDAP-registered. Re-deriving from the same key and LFDI yields the same `/128`; nothing new to store, nothing to steal that would let a scraper forge it.

```
# Provision a DER identity from the key it already holds (control plane, live).
# identity_public_key is the base64 SPKI of the EndDevice / SunSpec-Kyrio / TPM key.
CALL whisper.agents({op:'connect', args:{
  tier:'wireguard',
  identity_public_key:'<base64 SPKI of the device key>',
  device_id:'3F2504E04F8911D39A0C0305E82C33018B2E44F9'   // the IEEE 2030.5 LFDI
}}) YIELD op, ok, status, result, error RETURN op, ok, status, result, error
# -> deterministic /128 + a WireGuard config. Same key + LFDI -> same /128 (idempotent).
#    A different LFDI on the same tenant -> 409; a non-string device_id -> 400. Never a 500.
```

> `3F2504E0…44F9` is a placeholder 40-hex LFDI; no real DER or operator is implied. The `device_id` argument is generic: pass an `LFDI`, an `SFDI`, or a bare DER serial. A first-class `--lfdi` CLI flag is **on the roadmap**; provision via the control-plane call above today, which **is** live.

### Per-`/128` logs, and who's looking back

Because each party owns a dedicated `/128`, every DNS lookup and connection it makes is unambiguously *its*, with no shared-IP noise to reconstruct. And because the identity resolves through Whisper's own authoritative DNS and RDAP, you can also ask who is enumerating *you*: a reconnaissance tripwire the LFDI's private, out-of-band registry never offered.

```
# The DER's OWN outbound activity, per-event: timestamp, kind, destination, decision, bytes
CALL whisper.agents({op:'logs',    args:{agent:'2a04:2a01:5e0::50c', kind:'conn', from:'-24h'}})

# Reverse observability: WHO resolved this DER's PTR/AAAA/TLSA or hit its RDAP object, and when
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:5e0::50c', window:'24h'}})
curl -s https://whisper.online/ip/2a04:2a01:5e0::50c/lookups | jq   # same view, keyless
```

### One-call revoke

Containment, and the end of a vendor's access, is a single call. It tears down the `/128`, its PTR and its DANE record worldwide at DNS-TTL speed, and the teardown is provable with the same public tools that proved the identity.

```
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:5e0::50c'}})
# after the TTL:
dig -x 2a04:2a01:5e0::50c +short                          # -> empty
curl -s https://whisper.online/verify-identity/2a04:2a01:5e0::50c   # -> {"is_whisper_agent": false}
```

### The attribution graph

Turning a raw destination (or a suspicious controller in your logs) into "known-bad C2" or "clean CDN" is a read-only query against the public graph API. Attribution survives IP rotation because it fingerprints the operator and the tooling (ASN and hosting genealogy for cloud rotation, a `JA4/JA3` client fingerprint for a residential-proxy swarm), not the ephemeral egress IP.

```
curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_xxx" \
  --data-urlencode "q=CALL whisper.identify('34.90.x.x')"
# -> what the address is, who operates it, threat-intel reputation, relationships:
#    a reproducible, replayable JSON evidence chain your OT SOC, PSIRT and a regulator can replay.
```

The read-only verbs (`identify`, `origins`, `walk`, `variants`, `history`) run the same way, over an infrastructure-and-threat-intelligence graph of billions of nodes. That is the enrichment that turns a per-DER egress log into a detection.

## The map, at a glance

Each row is a framework, the control it asks for, our verdict, and the shipped evidence behind it. The deep sections below unpack each group. Read the verdict column first: it is the load-bearing part.

| Framework · control | What it asks for | Verdict | Whisper evidence (shipped) |
|---|---|---|---|
| **NERC CIP-005-7** R3.1 / R3.2 | Determine active vendor remote-access sessions, and have a method to disable them | DIRECT-ADDITIVE | `op:list` / `op:lookups` (determine) · attribution (who) · `op:revoke` (disable), all logged |
| **NERC CIP-013-2** R1.2.3 / R1.2.6 | Notify when vendor access should end; coordinate controls for vendor-initiated & system-to-system remote access | DIRECT-ADDITIVE | Per-device identity + one-call `revoke` + a transparency-log record of grant/removal |
| **EU NIS2** Art.21 | Access control, identity & asset management, logging, supply-chain security | DIRECT-ADDITIVE | Per-`/128` identity + `logs` + `lookups` + `revoke` as evidence |
| **EU NCCS** Reg. 2024/1366 Art.33 | Zero-trust posture + ICT-lifecycle asset traceability | DIRECT-ADDITIVE ¹ | Identity-per-device + attributable egress + a lifecycle transparency log |
| **NISTIR 7628 r1** SG.IA / SG.AU | Device identification & authentication (IA); audit & accountability (AU) | DIRECT-ADDITIVE | `/128` identity (SG.IA) · signed logs / lookups / transparency log (SG.AU) |
| **Sandia SAND2019-1490** | "Verify the identity of devices" + DER access control (guidance) | DIRECT-ADDITIVE | Device `/128` identity + source-bound egress governance |
| **CA Rule 21 / IEEE 2030.5 CSIP** | Mandates IEEE 2030.5 + the `LFDI` / managed-PKI cert | COMPLEMENTARY | Bind the existing `LFDI` to a public `/128`; DANE-pin the 2030.5 endpoint; never satisfies the cert |
| **UL 1741-SB** | Interconnection type-test of an inverter model (SB / IEEE 1547-2018) | COMPLEMENTARY | Adds the live, per-unit, revocable identity alongside the model type-test |
| **SunSpec / Kyrio PKI** | The private `SERCA→MCA→MICA` device-cert root | COMPLEMENTARY | Keeps its key-derived property; adds public verifiability + DNS-TTL revocation; never cross-signs |
| **IEC 62351-9** | Key management, revocation & lifecycle for power-system comms | COMPLEMENTARY | DNS-TTL revocation + transparency log at the IP/DNS boundary, not on the substation bus |
| **ISO 15118 / OCPP 2.0.1** | Plug&Charge contract-cert PKI + charger↔CSMS protocol | COMPLEMENTARY | A revocable network identity per EVSE, alongside the 15118 PKI, never inside the handshake |
| **NIST IR 8498** G3 / G7 | Logging (G3); protect connections (G7) for smart inverters | COMPLEMENTARY | Per-`/128` logs (G3) · DANE-pinned, source-bound egress (G7) |
| **NERC CIP-010** | Configuration change management, baselines & vulnerability assessment | STRETCH (not claimed) | Whisper is not a configuration-baseline tool |
| **NERC CIP-005-7** R2 | Interactive Remote Access via an Intermediate System, with encryption + MFA | STRETCH (not claimed) | Whisper is not an Intermediate System and provides no MFA |
| **NERC CIP-007-5** R5 | System access control: account & authentication management | STRETCH (not claimed) | Whisper is not an account / authentication manager |

¹ DIRECT-ADDITIVE against the *published articles* of Reg. (EU) 2024/1366; the binding control lists finalise around 2027 (see the caveats below).

## DIRECT-ADDITIVE: the evidence we produce

Where a control asks a question the four shipped primitives answer, Whisper is a concrete input to your compliance package. Never the whole standard. One verifiable control, with reproducible artifacts.

### NERC CIP-005-7 R3: determine & disable active vendor remote access

CIP-005-7 added the vendor-remote-access requirements the sector had been missing: **R3.1** requires a method to *determine* active vendor remote-access sessions (including system-to-system), and **R3.2** requires a method to *disable* them. That is precisely a determine-then-disable loop, and it maps one-to-one onto shipped ops. It is the strongest fit on this page.

```
# R3.1: determine which vendor identities are active on your tenant, and who's looking
CALL whisper.agents({op:'list',    args:{kind:'agent'}})
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:5e0::50c', window:'24h'}})

# who is the operator behind a session? (attribution survives egress rotation)
curl -s https://graph.whisper.security/api/query -H "X-API-Key: whisper_live_xxx" \
  --data-urlencode "q=CALL whisper.identify('34.90.x.x')"

# R3.2: disable it. One call, worldwide, at DNS-TTL, and provable afterward.
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:5e0::50c'}})
```

**Honest scope.** CIP-005 R3 is written for the Responsible Entity's own EACMS and Electronic Security Perimeter. Whisper anchors at the cloud/IP boundary and supplies the *determine* and *disable* evidence there; it is one control in your RSAW, additive to your ESP architecture, not a replacement for it.

### NERC CIP-013-2 R1.2.3 & R1.2.6: supply-chain risk controls

CIP-013-2 R1.2 obliges a supply-chain risk-management plan that addresses, among other items, **R1.2.3** (notification when vendor remote or onsite access should no longer be granted) and **R1.2.6** (coordination of controls for vendor-initiated Interactive Remote Access and system-to-system remote access). A per-device identity you can revoke in one call, with a tamper-evident record of exactly when access was granted and removed, is a direct artifact for both. The transparency log is what makes the "we removed access on date X" claim non-repudiable rather than a database row an auditor must take on faith.

### EU NIS2: Article 21 risk-management measures

NIS2 (Directive (EU) 2022/2555) Art.21 requires essential and important entities (energy squarely among them) to take measures including access-control and asset-management policies, security in network and information systems acquisition and maintenance, and logging. A per-`/128` identity gives you machine-level access control at the cloud boundary; `op:logs` and `op:lookups` give you the continuous, per-party record; `op:revoke` plus the transparency log give you the supply-chain offboarding evidence. Evidentiary and additive: one measurable input to the Art.21 posture.

### EU Network Code on Cybersecurity: Reg. (EU) 2024/1366, Art.33

The NCCS is the electricity-sector network code adopted in 2024; Art.33 points at zero-trust access and traceability across the ICT lifecycle. An identity that is per-device, attributable on egress, and whose issuance and revocation live in an auditable lifecycle log is a natural fit for both. **The honest caveat:** the NCCS's binding control lists and the classification of high- and critical-impact entities are still being finalised. Completion is expected around 2027. We map to the *published articles* today and will track the control text as it lands; we make no claim against text that does not yet exist.

### NISTIR 7628 r1: SG.IA & SG.AU

The NIST smart-grid security guidelines organise controls into families. Two land directly: **SG.IA** (Identification and Authentication), where the device `/128` is a cryptographic device identifier, publicly verifiable and bound to the key the device already holds, and **SG.AU** (Audit and Accountability), where the per-`/128` logs, `op:lookups`, the signed graph evidence chains, and the append-only transparency log are exactly the reviewable, accountable record the family asks for.

### Sandia SAND2019-1490: DER cybersecurity guidance

Sandia's DER cybersecurity work (SAND2019-1490 and the follow-on 2021-0977) recommends, in plain words, to *verify the identity of devices* and enforce access control on DER communications. The device-derived `/128` is that verifiable identity; source-bound egress governance (default-deny, allow only the DERMS head-end and OTA endpoint) is that access control. Guidance-additive: a concrete implementation of an advisory recommendation.

## COMPLEMENTARY: we sit alongside, we don't satisfy the cert

Several frameworks mandate the sector's *own* PKI or a certificate. Whisper does not, and must not claim to, satisfy those. It complements them: it keeps the good property they already have (a key-derived name), adds the two they lack (public verifiability and DNS-TTL revocation), and where a certificate is in play it can DANE-pin that exact certificate to DNSSEC to cut single-CA trust risk.

- **CA Rule 21 / IEEE 2030.5 CSIP.** Rule 21 mandates IEEE 2030.5 (SEP2) with the `LFDI` and the CSIP managed-PKI cert. Whisper binds that *existing* `LFDI` to a public `/128` and can DANE-pin the head-end's 2030.5 endpoint certificate; it never issues or replaces the CSIP cert.
- **UL 1741-SB.** A type-test of an inverter *model* against IEEE 1547-2018 grid-support functions, not a live, per-unit, revocable identity. Whisper adds exactly that live per-unit layer next to the model certification.
- **SunSpec / Kyrio `SERCA→MCA→MICA` PKI.** The private device-certificate root. Whisper keeps its key-derived `LFDI` property, adds public verifiability and DNS-TTL revocation, and never cross-signs into the private root.
- **IEC 62351-9.** Key management, revocation and credential lifecycle for power-system communications. Whisper's DNS-TTL revocation and transparency log complement 62351-9 at the IP/DNS boundary; it does not implement 62351 on the substation bus.
- **ISO 15118 / OCPP 2.0.1.** Plug&Charge's contract-certificate PKI and the charger↔CSMS protocol. Whisper gives each EVSE a revocable *network* identity alongside the 15118 PKI, never inside the charging handshake.
- **NIST IR 8498.** Cybersecurity for grid-edge smart-inverter systems. The per-`/128` logs map to its logging goal (G3) and the DANE-pinned, source-bound egress to its protect-connections goal (G7): a complementary control mapping, not a conformance claim.

> Why this whole group is COMPLEMENTARY and not DIRECT: the CSIP managed-PKI model is explicit that *"no certificates within the MPKI can be revoked … CAs are not required to issue CRLs nor provide OCSP"*: life-long certs that cannot be revoked. Whisper adds public verifiability and a real off-switch *on top* of that cert. It complements the mandate; it is not the mandated cert.

## STRETCH: what we do NOT claim

The most useful rows on a compliance page are often the ones a vendor omits. These controls exist, they matter, and Whisper is honestly the wrong tool for them. We list them so nobody plans against an over-claim:

- **NERC CIP-010**: configuration change management, security baselines and vulnerability assessment. Whisper is not a configuration-baseline or vuln-assessment tool.
- **NERC CIP-005-7 R2**: Interactive Remote Access routed through an Intermediate System with encryption and multi-factor authentication. Whisper is not an Intermediate System and provides no MFA. (Note the deliberate split: R3 vendor-remote-access is DIRECT-ADDITIVE; R2 IRA/MFA is not claimed.)
- **NERC CIP-007-5 R5**: system access control, account and authentication management on BES Cyber Systems. Whisper is not an account or authentication manager.

## Two caveats we state up front

Buyer trust is built by naming the limits before the sales call does:

- **NERC CIP scope is the Bulk Electric System.** CIP obligations attach at the utility / aggregation / registered-entity / vendor-access layer, *not* to most behind-the-meter residential DER. A Whisper `/128` is useful at both layers, but only the BES layer is in CIP scope; we do not pretend a rooftop inverter is a BES Cyber Asset. Where CIP maps, it maps at the aggregator↔utility↔vendor boundary, which is exactly where Whisper sits.
- **EU NCCS control lists finalise around 2027.** Reg. (EU) 2024/1366 is adopted, but its binding cybersecurity control lists and impact-classification are still being worked out. We map to the published articles today and treat the detailed control text as forthcoming: no claims against undecided text.

## Nothing issued in the dark: the transparency-log audit trail

Every identity mint and every revocation lands in a public, append-only Merkle transparency log (RFC 6962 `tlog-tiles`), with Ed25519-signed C2SP checkpoints, each root anchored to Bitcoin via OpenTimestamps. That gives a regulated operator something a database row cannot: a *non-repudiable* answer to "when was this vendor's access granted, and when was it removed", provably not back-dated, provably in order.

```
# An identity's ordered lifecycle (issuance, any rotations, revocation), keyless
curl -s https://whisper.online/ip/2a04:2a01:5e0::50c/transparency | jq

# The signed log checkpoint + its Bitcoin anchor: the tamper-evidence root
curl -s https://whisper.online/checkpoint
# -> a C2SP signed note; the root is OpenTimestamps-anchored to Bitcoin
```

> **Honest status.** The log is tamper-evident, Ed25519-signed and Bitcoin-anchored *today*, but it is **not yet independently witnessed** (our two authoritative nodes co-signing is availability, not independence). It already speaks the C2SP `tlog-witness` protocol, so an external witness can co-sign; until one does, treat the guarantee as tamper-*evident*, not third-party-attested. It is also GDPR-compatible: leaves are salted opaque commitments with selective disclosure, so erasing the salt renders a leaf's meaning unrecoverable while the proofs stay valid.

## Evidence you can hand an auditor

The point of every primitive above is that the auditor does not have to trust Whisper. Each artifact is reproducible from the internet's own records with stock tools: the same `--trustless` walk any resolver could run. A per-control evidence bundle for an RSAW or a NIS2 review looks like this, and every line is checkable without an account:

```
# IDENTITY (SG.IA / CIP-013): the identity is genuine and current, verified to the IANA root
whisper verify --trustless 2a04:2a01:5e0::50c
✓ DNSSEC chain valid to the IANA root   ✓ DANE-EE (TLSA 3 1 1) matches the key
✓ RDAP: registered under AS219419 · 2a04:2a01::/32   identity: VERIFIED (our API never trusted)

# MONITORING (CIP-005 R3.1 / SG.AU): the per-party record and who enumerated it
CALL whisper.agents({op:'logs',    args:{agent:'2a04:2a01:5e0::50c', kind:'conn', from:'-30d'}})
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:5e0::50c', window:'30d'}})

# DISABLE + NON-REPUDIATION (CIP-005 R3.2 / CIP-013 R1.2.3): the offboarding, provable and timestamped
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:5e0::50c'}})
curl -s https://whisper.online/ip/2a04:2a01:5e0::50c/transparency   # the timestamped lifecycle leaf
```

And because telemetry can be bound to (and signed under) the DER's forge-proof `/128`, the ISO, the utility and your own market settlement can trust the numbers came from the real device, which is the non-repudiation those audit families ultimately want.

## SIEM & threat-intel export

The evidence above is pullable now via `op:logs`, `op:lookups` and the graph API, and it exports to **Splunk** today as signed, replayable JSON mapped to CEF / ECS fields. Broader connectors are on the roadmap, labelled honestly so nobody plans against vapour:

| Destination | Status |
|---|---|
| Splunk (signed JSON → CEF / ECS) | **Shipped** |
| Microsoft Sentinel connector | **Shipped** |
| OpenCTI | **Shipped** |
| STIX 2.1 / TAXII feed | Roadmap |
| E-ISAC machine-readable JSON export | Roadmap |

Until the roadmap items land, the same records are already reachable. The exports are a convenience layer over evidence you can pull today.

## What this is, and is not

Whisper anchors **one** boundary: the cloud/IP interface between a DER (or an aggregator-API consumer) and the backend. It is deliberate about what it does not touch.

- It is **not** your CSMS, DERMS, or SUMS: it is the identity-and-attribution layer those systems consume. It complements them; it does not replace them.
- It does **not** sit inside the IEC 61850 GOOSE/MMS bus, the DNP3 outstation link, or the ISO 15118 charging handshake. Those keep their own PKIs; a Whisper DANE-anchored identity complements them at the network layer without cross-signing.
- These platform mappings are *proposed*, not vendor-endorsed, and no operator is named as a breach victim. The exposure classes on this page are drawn from public research and advisories at the class level only.

Everything described as working is checkable, today, with `dig`, `curl` and one control-plane call. Everything on the roadmap is labelled as such. That is the whole contract of this page.

## Next

- [DER & inverter identity](/docs/industries/energy/der-identity): how the device-derived `/128` is computed from the key a DER already holds, and why the `LFDI` is the natural domain separator.
- [Grid-API-abuse cure](/docs/industries/energy/grid-api-abuse-cure): the same identity, applied to the stolen-aggregator-token problem at the API ingress (the BOLA root cause).
- [Telemetry · egress · attribution](/docs/industries/energy/energy-recipes): runnable recipes that generate exactly the artifacts this page maps to a control.
