Morocco UNS Standard v0.2 — Security Model & Arabic Localization
Delta document — extends Morocco UNS Standard v0.1 without replacing it. v0.1 §§1–10 remain in force; v0.2 adds §§11–13. When a producer or consumer claims
schema_version: morocco-uns-0.2, both v0.1 and the additions below apply.
11. Security Model
11.1 Threat model (in scope)
| Threat | Mitigation in this section |
|---|---|
| Unauthenticated publish/subscribe on the broker | mTLS + Sparkplug B authentication |
| Topic spoofing (a producer publishes outside its scope) | Topic-prefix ACLs derived from the UNS path |
| Eavesdropping on industrial telemetry | TLS 1.3 transport |
| Replay of historical payloads | Sparkplug B sequence numbers + monotonic timestamp_utc enforcement |
| Tampering with CBAM-relevant metrics | Producer-side signing of the metadata envelope (§11.6) |
| Cross-tenant signal leakage in shared brokers | ACL isolation by enterprise segment |
Out of scope for v0.2: hardware root of trust on edge nodes (deferred to v0.3), formal vulnerability disclosure process (governance, not standard).
11.2 Transport — TLS 1.3 mandatory
- All MQTT connections (broker, edge node, consumer) MUST use TLS 1.3.
- Cipher suite floor:
TLS_AES_128_GCM_SHA256. Operators MAY restrict further. - Plain MQTT on port 1883 MUST be refused at the broker. Use 8883 (mqtts) and 8884 (mqtts over WebSocket).
- Self-signed certificates are forbidden in any environment touching production data, including pilots.
11.3 Authentication — mTLS for OT, OAuth2 for IT
Two authentication paths, chosen by the type of client:
| Client class | Authentication |
|---|---|
| Edge node (PLC connector, gateway) | mTLS with client certificate issued from the enterprise PKI |
| Backend service (analytics, ERP bridge, dashboard backend) | mTLS OR OAuth2 client-credentials with broker-validated JWT |
| Human operator dashboard | OAuth2 authorization-code with PKCE, broker validates JWT |
| Sparkplug B device | Inherits the edge node’s mTLS identity; no separate creds |
Edge-node certificate Common Name (CN) MUST encode the producer identity:
CN=<edge-node-id>.<enterprise>.uns.ma
Example: CN=edge-safi-line3-01.ocp.uns.ma. The broker derives ACL scope from the CN; the certificate itself is the source of truth for which paths the producer may publish on.
11.4 Authorization — ACL derived from UNS path
The ACL model is path-prefix based. The broker computes each client’s allowed publish prefix from its identity (mTLS CN or JWT claim) and rejects publishes outside the prefix.
Default rules:
| Identity component | Maps to | Allowed publish prefix |
|---|---|---|
<edge-node-id> | Edge node | uns/ma/<region>/<enterprise>/<site>/<area>/... (the area scope it was provisioned for) |
enterprise claim in JWT | Backend service of the enterprise | uns/ma/+/<enterprise>/# |
multi_enterprise claim with explicit list | Cross-enterprise consumer (e.g. CBAM regulator portal, port operator joining upstream signals) | union of listed enterprise prefixes |
Subscribe rules:
- Default: a client may subscribe only to its own publish prefix.
- A client MAY be granted broader subscribe scope via an explicit
subscribe_prefixclaim. Use sparingly. - A
cbam_aggregatorrole grantsuns/#subscribe scope filtered tocbam_relevant: truepayloads only (filtering enforced by a broker plugin or a Sparkplug-aware bridge).
11.5 Sparkplug B specifics
- Sparkplug birth/death certificates (
NBIRTH,NDEATH,DBIRTH,DDEATH) MUST be authenticated via mTLS like any other publish. - Sequence numbers: every device MUST monotonically increment
seqper Sparkplug spec; the broker SHOULD enforce. A consumer that observes aseqregression treats the device state as suspect and re-requests rebirth. - Sparkplug
bdSeqmust roll over correctly across reconnects; reconnect storms are detected as abnormal at the broker.
11.6 Payload integrity for CBAM-relevant metrics
Any payload with cbam_relevant: true MUST additionally carry:
| Field | Type | Description |
|---|---|---|
producer_signature | base64 string | Detached signature over the canonical JSON form of the payload (excluding producer_signature itself), using the edge node’s private key. |
signature_alg | enum | ed25519 (recommended) or ecdsa-p256. |
Consumers building the CBAM declaration MUST verify signatures against the producer-certificate public key and reject unsignable payloads. This forecloses post-hoc tampering with the May 2027 emissions ledger.
For non-CBAM signals, signing is OPTIONAL.
11.7 Broker-side validation
A v0.2-conformant broker SHOULD reject (with REASON_CODE 0x97 — Quota exceeded or vendor extension) any publish where:
- The topic does not match the §5 grammar of v0.1.
- The payload is missing any §7 mandatory field, OR the §11.6 fields when
cbam_relevant: true. - The
producer_iddoes not match the authenticated identity (CN or JWT subject). unitin the envelope does not match the unit suffix in the signal name.timestamp_utcis more than 60 s in the future or older than 24 h (configurable).
Brokers that cannot enforce these natively MAY delegate to a sidecar validator on a wildcard subscription that re-publishes only conformant payloads on a uns/... topic, with raw input on staging/....
11.8 Data localization (CNDP Loi 09-08)
- Signals tagged
cndp_class: personalorcndp_class: sensitiveMUST be routed to a broker physically located in Morocco. v0.2 introduces the topic prefixuns-local/as a parallel namespace for these signals; cross-border bridges MUST NOT forwarduns-local/#. - For pure industrial telemetry (
cndp_class: none), cross-border forwarding to cloud regions is permitted; the standard does not mandate residency for non-personal data.
11.9 Audit logging
Brokers MUST log connection (success and failure), subscribe, and publish-rejection events with:
- timestamp (ms, UTC)
- authenticated identity (CN or sub)
- topic
- outcome
- reason code
Logs are out of scope of this document beyond the requirement to retain them ≥ 90 days. Specific SIEM integration is implementation-dependent.
11.10 Operational observability
A v0.2-conformant deployment SHOULD expose operational telemetry for the namespace itself. This is required for production trust: a plant team cannot rely on evidence streams if it cannot see whether connectors, brokers, validators, buffers, and consumers are healthy.
Minimum metrics:
| Component | Required observations |
|---|---|
| Broker | connection count, publish/subscribe rate, rejected publish count, retained message count, authentication failures |
| Edge node | connector status, last successful read, read error count, source protocol latency, local clock skew |
| Validator | accepted/quarantined/rejected payload count, rejection reason, schema version distribution |
| Pipeline/bridge | event rate, error rate, retry count, last successful publish, destination status |
| Store-and-forward buffer | buffered message count, oldest buffered timestamp, disk usage, replay success/failure count |
| Evidence consumer | last successful evidence object, signature verification failures, export failures |
Implementations SHOULD emit these observations as OpenTelemetry metrics or an equivalent structured metrics format. Human-facing dashboards MAY summarize them, but raw metrics must remain machine-readable.
11.11 Resilience and federation
Industrial sites in Morocco often face WAN instability, segmented OT networks, and mixed brownfield equipment. A conformant production deployment SHOULD therefore support:
- local edge buffering for every external dependency;
- explicit store-and-forward depth monitoring per §11.10;
- idempotent replay so buffered payloads do not duplicate evidence objects;
- broker or bridge restart without losing accepted-but-unforwarded payloads;
- remote-site federation through read-only mapped namespaces when multiple sites feed a group-level view;
- clear degradation behavior when a central namespace or cloud destination is unreachable.
Federation MUST preserve the original source path and producer_id. A central/group namespace may create additional views, but it MUST NOT rewrite the originating site path in a way that breaks audit reconstruction.
12. Arabic Localization
12.1 Principle
The standard’s canonical identifiers remain EN-only ASCII kebab-case as defined in v0.1 §5.2. This is non-negotiable for technical interoperability — every PLC, broker, database, and protocol stack along the path expects ASCII identifiers, and many will silently corrupt non-ASCII input.
Arabic appears only in human-facing labels, never in topic paths or metric identifiers.
12.2 Labels in the metadata envelope
v0.2 adds optional fields to the §7 envelope for bilingual UI rendering:
| Field | Type | Description |
|---|---|---|
label_en | string | English display label (e.g. “Discharge flow rate”) |
label_fr | string | French display label (e.g. “Débit de refoulement”) |
label_ar | string | Arabic display label, native script (e.g. “معدل تدفق التصريف”) |
These are descriptive only. A consumer rendering an Arabic dashboard reads label_ar; a consumer building an analytics pipeline ignores all three.
12.3 Transliteration table — Arabic ⇄ ASCII
For Moroccan place names where multiple romanizations exist, this standard adopts a single canonical ASCII form per name. Transliteration is lossy and one-way — these strings are identifiers, not translations.
| Arabic | Canonical ASCII (this standard) | Notes / forbidden alternates |
|---|---|---|
| الدار البيضاء | casablanca | not dar-al-baida |
| الرباط | rabat | |
| طنجة | tangier | not tanger (FR), not tanja (translit) |
| فاس | fes | not fez |
| مكناس | meknes | |
| مراكش | marrakech | not marrakesh |
| أكادير | agadir | |
| وجدة | oujda | |
| تطوان | tetouan | strip diacritic from tétouan |
| القنيطرة | kenitra | |
| العيون | laayoune | not el-aaiun, not layoune |
| الداخلة | dakhla | |
| الجديدة | el-jadida | hyphenated |
| آسفي | safi | |
| خريبكة | khouribga | |
| اليوسفية | youssoufia | |
| بن جرير | benguerir | one word |
| الجرف الأصفر | jorf-lasfar | |
| سيدي بنور | sidi-bennour | |
| بني ملال | beni-mellal | |
| الناظور | nador | |
| سطات | settat | |
| برشيد | berrechid | |
| تارودانت | taroudant |
The same principle applies to enterprise names: use the legal Latin-script registered name as the basis, then lowercase and kebab-case it. If the entity has only an Arabic legal name, transliterate using the Arabic-Chat Alphabet rules in §12.4 and document the chosen form in the project’s site README.
12.4 Transliteration rules (when no canonical form exists)
For new place or company names not in §12.3:
- Strip Arabic definite article
الunless it is part of the registered name. - Use the simple consonant map:
- ا→a · ب→b · ت→t · ث→th · ج→j · ح→h · خ→kh · د→d · ذ→dh · ر→r · ز→z · س→s · ش→sh · ص→s · ض→d · ط→t · ظ→z · ع→a · غ→gh · ف→f · ق→q · ك→k · ل→l · م→m · ن→n · ه→h · و→w · ي→y · ة→a · ى→a · ء→(omit)
- Short vowels (fatha/kasra/damma) →
a/i/uonly where needed for clarity. - Drop all diacritics in the resulting Latin string.
- Replace any remaining whitespace with
-.
This is intentionally simple and one-way; readability for an English/French reader takes priority over reversibility.
12.5 Direction handling in dashboards
Dashboards rendering label_ar MUST set dir="rtl" on the cell or component containing the Arabic label. Numeric values, units (kwh, m3h, etc.), and identifiers remain LTR. Mixed-direction rendering inside the same line follows the Unicode Bidirectional Algorithm with explicit isolates (U+2068/U+2069) where needed.
12.6 What v0.2 does not do
- Does not introduce Arabic into the topic path. Any consumer expecting Arabic identifiers in the path will break and is non-conformant.
- Does not provide French labels universally —
label_fris optional and intended for sites where the operating language is FR. - Does not localize unit suffixes.
kwhstayskwheverywhere.
13. Conformance update
A producer claiming morocco-uns-0.2 conformance MUST:
- Be conformant to v0.1 (§§1–10).
- Connect over TLS 1.3 with mTLS (§11.2–11.3).
- Publish only on paths permitted by its derived ACL (§11.4).
- Sign all
cbam_relevant: truepayloads (§11.6). - Tolerate broker rejection per §11.7 without crashing.
- Use the §12.3 canonical ASCII forms for Moroccan place names.
- Expose operational health signals for its connector and buffer state when deployed in production (§11.10).
A v0.2 broker MUST enforce §§11.2, 11.3, 11.4, and SHOULD enforce §11.7 and emit metrics per §11.10.
A v0.2 consumer MUST verify CBAM signatures (§11.6) and MAY render label_ar/label_fr/label_en per §12.
Change log
- 2026-05-27 — HighByte ingestion delta. Added vendor-neutral observability, store-and-forward, and federation requirements inspired by Industrial DataOps benchmarking; no HighByte-specific claims added.
- 2026-04-27 — v0.2 draft. Adds §§11–13. v0.1 unchanged.