Appendix A List of Acronyms

DER

Distributed Energy Resource

GW

Gateway

IP

Internet Protocol

ISO

Optical disk image in International Standards Organization 9660 format

IT

Information Technology

LAN

Local Area Network

LTE

Long Term Evolution

NCCoE

National Cybersecurity Center of Excellence

NIST

National Institute of Standards and Technology

OT

Operational Technology

OVA

Open Virtualization Appliance

PV

Photovoltaic

SIEM

Security Information and Event Management

SP

Special Publication

vLAN

Virtual Local Area Network

VM

Virtual Machine

UMD

University of Maryland

Appendix B Software for Using Immutably

This appendix presents the software used to send records to the command register. This same software, with minor variations, is used in the distribution ops system, front end processor, and microgrid master controller.

import requests

import json

from requests_oauthlib import OAuth1, OAuth1Session

from pyModbusTCP.client import ModbusClient

from pyModbusTCP.server import ModbusServer, DataBank

from time import sleep

class Proofworks:

   def __init__(self):

      self.host = 'https://immutably.client.cxl.io/api'

      self.key = 'kXHeHvHnwEDeGFPOmjTs39Oest42WxmXz62y1LfJ'

      self.secret ='GiXxoeWk26DnFUloSn3rQQ97tZHm7SGdK86au5bLqTJtIHuzrzK6nd0J4lqArYrI'

      self.realm ='74b8e784-242b-11e8-b467-0ed5f89f718b.0d091c52-2431-11e8-b467-0ed5f89f718b.fee64f24-f8c5-4406-953e-3705cccd9c3c'

      self.project_id = 'b269de55-8c42-482f-a0cb-2077c3f9be9f'

      self.session = None

   def login(self):

      payload = json.dumps({

         "key": self.key,

         "secret": self.secret,

         "realm": self.realm

      })

      headers = {

         'Content-Type': 'application/vnd.io.cxl.credentials.consumer-key+json',

         'Authorization': 'OAuth realm="realm",oauth_consumer_key="key",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1504127763",oauth_nonce="6ULC6xT4Fxi",oauth_version="1.0", oauth_signature="%2BegGM2djZ032sy7MyTwpfnqByZg%3D"'

      }

      oauth = OAuth1(self.key, client_secret=self.secret)

      response = requests.request("POST", f"{self.host}/authc/login", auth=oauth, headers=headers, data=payload)

      token = str(response.json()['access-token'])

      self.session = OAuth1Session(self.key, client_secret=self.secret, resource_owner_key=token, realm=self.realm)

   def get_total_proofs_in_project(self):

      response = self.session.get(

         f"{self.host}/proofworks/projects/{self.project_id}/proofs", timeout=10,

      )

      r = response.json()

      return r.get('count')

   def create_proof(self, source, NetRealEnergy, V_LL, Current, Frequency):

      headers = {

         "Content-Type": "application/json"

      }

      proof = json.dumps([

         {"==": ["source: ", source]},

         {"==": ["Real Energy - Net: ", NetRealEnergy]},

         {"==": ["Voltage - L-L: ", V_LL]},

         {"==": ["Current: ", Current]},

         {"==": ["Frequency: ", Frequency]}

      ])

      response = self.session.post(

         f"{self.host}/proofworks/projects/{self.project_id}/proofs",

         data=proof,

         timeout=10,

         headers=headers,

      )

Appendix C References

C1

Xage Security, Xage Security Fabric Installation Guide, Version 3.2.0, February 2021.