65 lines
2.8 KiB
C#
65 lines
2.8 KiB
C#
namespace w4c_workflows.Services.Security;
|
|
|
|
/// <summary>
|
|
/// One allow/deny rule for node execution. Shared by the global policy and the
|
|
/// per-tenant overrides, so an operator can restrict a noisy or high-risk tenant
|
|
/// without changing what everyone else may run.
|
|
///
|
|
/// Semantics, in evaluation order (deny always wins): the deny lists are checked
|
|
/// first, then the two convenience guards, then the allow lists. An empty allow
|
|
/// list means "no restriction"; a non-empty allow list means "only these match".
|
|
/// Entry patterns support <c>*</c> wildcards, e.g. <c>core.*</c> or <c>*.code</c>.
|
|
/// </summary>
|
|
public class NodePermissionRule
|
|
{
|
|
/// <summary>Node types allowed to run; empty means any (unless denied).</summary>
|
|
public List<string> AllowTypes { get; set; } = new();
|
|
|
|
/// <summary>Node types that may never run, checked before the allow list.</summary>
|
|
public List<string> DenyTypes { get; set; } = new();
|
|
|
|
/// <summary>Node kinds (<see cref="Models.Nodes.NodeKind"/>) allowed; empty means any.</summary>
|
|
public List<string> AllowKinds { get; set; } = new();
|
|
|
|
/// <summary>Node kinds that may never run.</summary>
|
|
public List<string> DenyKinds { get; set; } = new();
|
|
|
|
/// <summary>Blueprint origins (<see cref="Models.Nodes.NodeOrigin"/>) allowed; empty means any.</summary>
|
|
public List<string> AllowOrigins { get; set; } = new();
|
|
|
|
/// <summary>Blueprint origins that may never run.</summary>
|
|
public List<string> DenyOrigins { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// When false the <c>core.code</c> node is refused. Sugar for
|
|
/// <c>DenyTypes = ["core.code"]</c>; kept as an explicit switch because it is
|
|
/// the highest-risk core node (it runs tenant-authored scripts).
|
|
/// </summary>
|
|
public bool AllowCodeNodes { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// When false the <c>core.executeWorkflow</c> node is refused. Sugar for
|
|
/// <c>DenyTypes = ["core.executeWorkflow"]</c>.
|
|
/// </summary>
|
|
public bool AllowSubWorkflows { get; set; } = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Operator policy deciding which node types a workflow run may use. Bound from
|
|
/// the <c>Nodes:Permissions</c> configuration section. The default is
|
|
/// permissive (nothing is restricted) so adding the feature changes no existing
|
|
/// workflow; operators opt into the restrictions they want.
|
|
/// </summary>
|
|
public sealed class NodePermissionOptions : NodePermissionRule
|
|
{
|
|
/// <summary>Configuration section this policy binds from.</summary>
|
|
public const string SectionName = "Nodes:Permissions";
|
|
|
|
/// <summary>
|
|
/// Per-tenant rules. A tenant present here is evaluated against its own rule
|
|
/// instead of the global one, so a single tenant can be locked down without
|
|
/// affecting the rest.
|
|
/// </summary>
|
|
public Dictionary<string, NodePermissionRule> Tenants { get; set; } = new(StringComparer.Ordinal);
|
|
}
|