The roaming network operator (RNO) runs a roaming network: it owns the network itself, and it decides who is a
member. In POI 3 it is a party of the roaming network: embedded completely in the
RoamingNetwork as operator, a single object, with the public halves of its
keys. A roaming network has no keys of its own: they are the keys of its operator.
One operator may operate many roaming networks, e.g. Prod and QA: each of them embeds it, so that each can be
verified from its own history alone. A roaming network without an operator can not be changed where only the
operator may change it: nobody can sign for it.
It owns its own properties and the roaming network itself, and adds and removes the other parties. It signs in the place of a grid operator or a
conformity assessment body without keys, and its identity keys recover the keys of every other party.
It never changes the data of another party. Its identification is any nonempty text without surrounding
whitespace, compared case-insensitively, e.g. GraphDefined.
| Class | RoamingNetworkOperator — source |
| Identification | RoamingNetworkOperator_Id (WWCP_POI2), e.g. GraphDefined |
| Admin status | RoamingNetworkOperatorAdminStatusType, initially operational |
| Status | RoamingNetworkOperatorStatusType, initially available |
| Embedded in | RoamingNetwork as operator |
| Owner | itself: its data and signing keys by a signing key, its signing keys also by an identity key, its identity keys by an identity key; neither added nor removed |
| Embeds | nothing |
| HTTP | in GET ~/RNs/{RN_Id}, as operator |
See Common properties. It writes no eTags.
| JSON key | Change set |
|---|---|
@id |
— |
name |
update/remove |
description |
update/remove |
dataSource |
update/remove |
created |
— |
lastChange |
— (set to the change set's createdAt by every change of it) |
customData |
update/remove |
| JSON key | C# property | Type | Change set | Description |
|---|---|---|---|---|
address |
Address |
Address? |
update/remove | Address of the headquarters, as Styx writes it embedded. |
homepage |
Homepage |
URL? |
update/remove | Homepage. |
hotline |
HotlinePhoneNumber |
PhoneNumber? |
update/remove | Hotline phone number. |
signingKeys |
SigningKeys |
ImmutableArray<POIPublicKey> |
— (not written) | Its keys signing change sets, those its signingKeyCertificates certify, see Keys. |
identityKeys |
IdentityKeys |
ImmutableArray<POIPublicKey> |
update (identity key) | Long-term keys signing changes of keys, see Keys. Can not be removed. |
minConsensus |
MinConsensus |
Byte, 1 by default, written unless 1 |
update (identity keys) | How many holders of its keys of one kind sign what it owns, see Quorum. |
keyStatement |
KeyStatement |
RoamingNetworkKeyStatement? |
update/remove | Its identity keys and its minConsensus, stated by identity keys of the quorum, for apps (SPECIFICATION.md, section 8.6). |
signingKeyCertificates |
SigningKeyCertificates |
ImmutableArray<RoamingNetworkSigningKeyCertificate> |
update (signing or identity key; a holder's own by one of its identity keys) | Its signing keys, each certified by an identity key of its holder, for apps (section 8.6). Can not be removed or emptied. |
A change set names the properties above by their JSON keys (RoamingNetworkOperatorRegistry in
RoamingNetwork.RegistryChanges.cs), with
entityType RoamingNetworkOperator and its @id. Add and Remove of it are refused: it comes with the
roaming network it operates.
RoamingNetworkChange.UpdateProperty(rn.Operator!, "homepage", null, "https://open.charging.cloud") // signed by its signing key
RoamingNetworkChange.UpdateProperty(rn.Operator!, "signingKeyCertificates", null,
new JArray(RoamingNetworkSigningKeyCertificate.Create(identityKey, COSEAlgorithm.ES512, rn.Operator!.Id,
newKey, now).ToJSON(Embedded: true))) // signed by a signing or an identity keyThe party of its signatures is POIPartyId("RoamingNetworkOperator", id), RoamingNetwork.OperatorParty; it is
the first of RoamingNetwork.Parties.
The public keys of the RNO (POIPublicKey, source; checked by
POIPartyKeys). Every party has the same two arrays; see ../README.md and
SPECIFICATION.md.
| JSON key | Type | Description |
|---|---|---|
@id |
string | The SHA-256 COSE key thumbprint [RFC 9679] of key, 64 lowercase hex digits. Must match key. |
key |
string | Canonical Base64 of the deterministic CBOR of the public COSE key; private parts are refused. |
notBefore |
timestamp | Optional start of validity (UTC, to the millisecond). |
notAfter |
timestamp | Optional end of validity; not before notBefore. |
holder |
string | Optional: who holds the private key, e.g. one company of a quorum. No part of @id. |
usages |
array of texts | Optional, signing keys only: what it may sign (infrastructure, tariffs, priceStatements, models, software, certificates, payments, party); everything without. Commits and attestations of the RNO need party. No part of @id. |
- signingKeys — short keys (e.g. secp256r1) signing change sets of RNO data: its own properties, the network's
properties, adding and removing parties, and the rotation of the signing keys themselves. A
server operating the network signs its commits with one as well, in the role
roamingNetworkOperator. The RNO names them in itssigningKeyCertificatesonly, each certified by an identity key of its holder; it writes nosigningKeys, and one naming them is refused. A certificate names the operator, not a network: the same keys in every network it operates. - identityKeys — long-term keys (e.g. secp521r1) signing changes of the RNO's
identityKeys, of its certificates when none of its signing keys can sign any more, and, for recovery, of the keys of any other party. A change of them certifies the signing keys anew in the same change set. - Two identity keys at least. Nobody can replace the RNO's identity keys once they are lost or expired: there is
nobody above the RNO, and no external trust configuration. An RNO should therefore name at least two identity keys
with different
notAfter, one of them kept offline, and replace an identity key well before it expires. This is advice, not checked. - Both arrays are ordered by
@id(ordinal); a key must not be given twice, nor be both a signing and an identity key. - A key counts only when valid at the
createdAtof the change set (IsValidAt), and only in the version the change set is applied to. - A change set can only replace them with a nonempty array (
UpdateProperty);RemovePropertyis refused.
Several holders, e.g. companies, may share the keys of the RNO, so that none of them changes the network alone
(SPECIFICATION.md, section 4.1): each names its keys with its holder,
and the RNO names its minConsensus, e.g. 2 of 3.
- What needs it: everything the RNO signs needs signatures with keys of
minConsensusdifferent holders: its data and that of the network with signing keys; its keys, itsminConsensusand the recovery of the keys of other parties with identity keys; its key statement (…/keyStatement/v3, its identity keys and itsminConsensus, signed by identity keys of as many holders). An app takes a version only when signing keys of as many holders attest it, each certified by an identity key of its holder. - Own signing keys: each holder certifies its own signing keys with one of its identity keys
(
RoamingNetworkSigningKeyCertificate.Create(…)), and replaces them, with their certificates, by a change set signed by one of its identity keys alone: a signing key gives its holder one voice only. The keys of another holder need the quorum. - Holders, not keys: a holder renewing its key signs with two keys, but has one voice. Keys naming no holder
have one holder together: an RNO without a quorum is one holder with
minConsensus1. - More than half:
minConsensusis more than half of the holders of each kind of keys and at most as many, so that two quorums always share a holder (POIPartyKeys.CheckQuorum): 2 of 3, 3 of 4, 3 of 5. An odd number of holders is not needed. - Signing on one's own: each holder signs a change set or key statement with its own key and adds its
signature to the others (
changeSet.Sign(…),keyStatement.WithSignature(…)); one of them commits it, or the change set waits at a server for the signatures still missing, and is committed once they are there (~/history/changeSets/pending, SPECIFICATION.md, section 4.2).
var statement = RoamingNetworkKeyStatement.Create([ (alphaIdentityKey, COSEAlgorithm.ES512) ], 2,
rn.Id, rn.Operator!.Id, rn.Operator.IdentityKeys,
now, now.AddDays(30)).
WithSignature(betaIdentityKey, COSEAlgorithm.ES512); // at the place of Beta
var certificate = RoamingNetworkSigningKeyCertificate.Create(alphaIdentityKey, COSEAlgorithm.ES512,
rn.Id, rn.Operator!.Id, alphaSigningKey, now); // Alpha aloneAdmin status and status are kept in the status schedules shared by all versions, see
README.md; in a history as entityType RoamingNetworkOperator. No energy status.
| Type | Predefined values | Initially | |
|---|---|---|---|
| Admin status | RoamingNetworkOperatorAdminStatusType |
unknown, unspecified, planned, inDeployment, operational, internalUse, outOfService |
operational |
| Status | RoamingNetworkOperatorStatusType |
unknown, unspecified, offline, inDeployment, available, error |
available |