w4c-workflows-api/Services/Security/NodePermissionOptions.cs
Vitali sharp8n 42ffcb9adc workflows
2026-09-13 19:28:47 +03:00

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);
}