Files
scadaproj/components/auth/spec/CANONICAL-ROLES.md
T

3.9 KiB
Raw Blame History

Canonical roles (standardized)

Status: Standardized. The org-wide role set every sister project maps onto. This is a mapping layer above each project's native authorization: native enforcement (OtOpcUa NodePermissions, mxaccessgw gRPC scopes, ScadaBridge native roles + site-scoping) is unchanged — each project adds a canonical → native expansion via the IGroupRoleMapper<CanonicalRole> seam (SPEC.md §3). LDAP groups (or API keys) are assigned a canonical role; the project translates it to native permissions at runtime.

Capabilities

Capability Meaning
OBSERVE browse / read / subscribe / history + read audit logs
OPERATE operate-level writes; alarm acknowledge / confirm
TUNE tune-level writes; alarm shelve; method calls
AUTHOR create / edit configuration & templates
DEPLOY publish / push configuration to runtime / sites (scoped)
ADMINISTER manage users / security / system + export audit

There is no standalone AUDIT capability and no Auditor role: audit read is part of OBSERVE, audit export is part of ADMINISTER.

The six roles (capability bundles)

Role OBSERVE OPERATE TUNE AUTHOR DEPLOY ADMINISTER
Viewer ✓
Operator ✓ ✓
Engineer ✓ ✓ ✓
Designer ✓ ✓
Deployer ✓ ✓
Administrator ✓ ✓ ✓ ✓ ✓ ✓

Two privilege axes meet at the top: operations (Viewer → Operator → Engineer) and configuration lifecycle (Viewer → Designer → Deployer → Administrator). Administrator is the only role that holds every capability.

Orthogonal modifiers (not roles)

  • Scope — a grant is role × scope. OtOpcUa scopes by OPC-UA node tree (cluster→area→line→equipment→tag); ScadaBridge scopes Deployer by site; mxaccessgw scopes API keys by subtree/tag globs. The canonical layer carries an abstract scope selector; each project resolves it to its own granularity.
  • Principal type — humans (LDAP group → canonical role) and machines (API key → a subset of canonical capabilities) both take canonical roles.

Mapping to each project

Canonical OtOpcUa MxAccessGateway ScadaBridge
Viewer data-plane ReadOnly bundle; ctrl ConfigViewer dashboard Viewer; scopes invoke:read+metadata:read+events:read+session:* AuditReadOnly (← audit read); ⚠ no general config-viewer role yet
Operator data-plane Operator bundle scope invoke:write ⚠ N/A — runtime ops live at sites, not a central role
Engineer data-plane Engineer bundle scope invoke:secure (closest) ⚠ N/A
Designer ctrl ConfigEditor (+ WriteConfigure) ⚠ N/A — no config-authoring surface Design
Deployer ◑ part of FleetAdmin (config publish/generation) ⚠ N/A Deployment (+ site scope)
Administrator ctrl FleetAdmin; data-plane Admin bundle dashboard Admin; scope admin Admin (+ Audit export ←)

Consequences & gaps (accepted)

  • Auditor removed: ScadaBridge AuditReadOnly → Viewer, Audit → Administrator. This loses ScadaBridge's auditor/admin separation-of-duties (an auditor who can export but is not a full admin no longer has a distinct role). Accepted as the cost of standardizing.
  • Each project implements only the subset of canonical roles that applies; the ⚠ cells are simply never assigned there (ScadaBridge: no Operator/Engineer; mxaccessgw: no Designer/Deployer).
  • OtOpcUa has no first-class Deployer (config publish ⊂ FleetAdmin) — Deployer maps partially until/unless OtOpcUa splits a publish-only control-plane role.
  • Adoption is governance + a mapping layer, not enforcement changes — see GAPS.md backlog.