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 AuditReadOnlyViewer, AuditAdministrator. 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.