feat(security): add Operator + Verifier roles + policies + LDAP mapping options (T14a)
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
<option value="@Roles.Designer">Designer</option>
|
||||
<option value="@Roles.Deployer">Deployer</option>
|
||||
<option value="@Roles.Viewer">Viewer</option>
|
||||
<option value="@Roles.Operator">Operator</option>
|
||||
<option value="@Roles.Verifier">Verifier</option>
|
||||
</select>
|
||||
<div class="form-text">Deployer role: configure site scope below after saving.</div>
|
||||
</div>
|
||||
|
||||
@@ -74,6 +74,21 @@ public static class AuthorizationPolicies
|
||||
public const string RequireDesign = "RequireDesign";
|
||||
public const string RequireDeployment = "RequireDeployment";
|
||||
|
||||
/// <summary>
|
||||
/// Permission to initiate a two-person Secured Write (M7-A3 / T14a).
|
||||
/// Satisfied by the <see cref="Roles.Operator"/> role claim. Single-role
|
||||
/// policy mirroring <see cref="RequireAdmin"/>.
|
||||
/// </summary>
|
||||
public const string RequireOperator = "RequireOperator";
|
||||
|
||||
/// <summary>
|
||||
/// Permission to approve a two-person Secured Write (M7-A3 / T14a).
|
||||
/// Satisfied by the <see cref="Roles.Verifier"/> role claim. Kept distinct
|
||||
/// from <see cref="RequireOperator"/> so initiation and approval are
|
||||
/// separable duties.
|
||||
/// </summary>
|
||||
public const string RequireVerifier = "RequireVerifier";
|
||||
|
||||
/// <summary>
|
||||
/// Read access to the Audit Log #23 surface (Audit Log page,
|
||||
/// Configuration Audit Log page, Audit nav group). Granted to the
|
||||
@@ -135,6 +150,12 @@ public static class AuthorizationPolicies
|
||||
options.AddPolicy(RequireDeployment, policy =>
|
||||
policy.RequireClaim(JwtTokenService.RoleClaimType, Roles.Deployer));
|
||||
|
||||
options.AddPolicy(RequireOperator, policy =>
|
||||
policy.RequireClaim(JwtTokenService.RoleClaimType, Roles.Operator));
|
||||
|
||||
options.AddPolicy(RequireVerifier, policy =>
|
||||
policy.RequireClaim(JwtTokenService.RoleClaimType, Roles.Verifier));
|
||||
|
||||
// Multi-role permission policies — the policy succeeds when the
|
||||
// principal holds ANY of the mapped roles. RequireClaim with
|
||||
// multiple allowed values is the right primitive: it checks
|
||||
|
||||
@@ -28,8 +28,16 @@ namespace ZB.MOM.WW.ScadaBridge.Security;
|
||||
/// <item><description><c>AuditReadOnly</c> → <c>Viewer</c> (COLLAPSE — keeps
|
||||
/// audit-read + nav, loses bulk export, which it never had)</description></item>
|
||||
/// </list>
|
||||
/// <c>Operator</c> and <c>Engineer</c> exist in the canonical vocabulary but are
|
||||
/// unused by ScadaBridge, so they are intentionally not declared here.
|
||||
/// <c>Engineer</c> exists in the canonical vocabulary but is unused by
|
||||
/// ScadaBridge, so it is intentionally not declared here. <c>Operator</c> is
|
||||
/// now declared (M7-A3 / T14a) for the two-person Secured Writes feature.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Secured Writes (M7-A3 / T14a): <c>Operator</c> initiates a secured write and
|
||||
/// <c>Verifier</c> approves it — two distinct global roles so a single principal
|
||||
/// cannot both initiate and approve (separation of duties). Both are coarse
|
||||
/// global roles, matching the existing role model; site scoping (if any) is
|
||||
/// layered on at the LDAP-mapping level like the other roles.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static class Roles
|
||||
@@ -39,7 +47,15 @@ public static class Roles
|
||||
public const string Deployer = "Deployer";
|
||||
public const string Viewer = "Viewer";
|
||||
|
||||
/// <summary>Initiates a two-person Secured Write (M7-A3 / T14a). Canonical
|
||||
/// vocabulary role; pairs with <see cref="Verifier"/> who approves.</summary>
|
||||
public const string Operator = "Operator";
|
||||
|
||||
/// <summary>Approves a two-person Secured Write (M7-A3 / T14a). Held by a
|
||||
/// principal distinct from the initiating <see cref="Operator"/>.</summary>
|
||||
public const string Verifier = "Verifier";
|
||||
|
||||
/// <summary>All declared ScadaBridge roles — the single source of truth for "all
|
||||
/// permissions" (e.g. the dev auto-login principal). Stays in sync if a role is added.</summary>
|
||||
public static readonly string[] All = [Administrator, Designer, Deployer, Viewer];
|
||||
public static readonly string[] All = [Administrator, Designer, Deployer, Viewer, Operator, Verifier];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user