Every three years, your Regional Entity walks. They want CIP-007-6 R4 security event monitoring evidence and CIP-010-4 R1 baseline configuration evidence for every High and Medium impact Bulk Electric System Cyber System you own. For the past three years. With cryptographic proof that nothing has been retroactively modified.
In most utilities, this is a six-month project. Your SCADA log holds the security events. Your EMS holds operational changes. Your IT change-management tool holds infrastructure changes. Your config-management database holds baselines. Reconciling them per asset across three years takes a senior compliance team months. And NERC penalties don't wait — they scale at $1.5M per violation per day until the violation is cured.
Why this is so painful in most stacks
The two big CIP standards demand three things that almost never live in the same system:
- CIP-007-6 R4: Security event monitoring. Every BES Cyber System must generate, retain, and protect security event logs. R4.1 specifically requires integrity protection of those logs. Retroactive deletion or modification is a violation.
- CIP-010-4 R1: Configuration change management. Every change to a baseline must derive from an approved change ticket, be tested, and have a rollback plan.
- CIP-013 R1: Supply chain risk. Every vendor on a CIP-impacted asset must have onboarding due-diligence and continuous monitoring on file.
If those three things live in three or four different tools, the auditor has to mentally stitch them together. Mistakes happen. Notices of violation follow.
The one-query CIP-007 R4 reconstruction
MATCH (a:Asset)-[:GENERATED]->(e:SecurityEvent)
WHERE a.cip_impact IN ['High', 'Medium']
AND e.ts >= $windowStart
OPTIONAL MATCH (e)-[:ALERTED]->(r:Response)
OPTIONAL MATCH (a)-[:BASELINED_BY]->(b:Baseline)
RETURN a.id, count(e), count(r), b.last_validated
Pass $windowStart, the start of the three-year window, in the same format that e.ts stores. In the illustrative walkthrough, the query covers 612 CIP-impacted assets and 18.7 million security events.
The R4.1 integrity check
The auditor's hardest CIP question — have any security events been deleted or modified since they were recorded? — is answered by the history check. Each committed node and relationship write, including each security event, is appended to the graph's history log with the SHA-256 hash of the previous record. GET /graphs/{name}/audit/verify re-hashes the graph’s write history and returns clean or the first broken record. The check covers the whole graph and has no date window. The history log is not signed or anchored outside the server, so the check does not detect a rewrite of the whole log, or removal of the most recent records, by someone with write access to the server.
The CIP-010 R1 change lineage
Every configuration change to a CIP-impacted asset must connect backward to an approved change ticket, the test record, the rollback plan, and the responsible engineer. If each change is linked to those records with DERIVED_FROM edges, db.derivedFrom('change:CHG-1042', 2) returns them (the change id is fictional). Node creates refused by field-level write ACLs are recorded in the ACL event log; write ACLs are checked only when a Cypher CREATE creates a node.
The CIP-013 supply chain twist
While CIP-007 and CIP-010 are evidenced, the auditor pivots to supply chain. This vendor's firmware is on dozens of your CIP-impacted assets — when was your last onboarding review? The graph shows every CIP-013 vendor relationship, every onboarding due-diligence record, every continuous monitoring entry. Same primitive, different audience.
The numbers
The figures in this post and in the walkthrough are illustrative.