diff --git a/src/Trax.Effect/Attributes/TraxAuthorizeAttribute.cs b/src/Trax.Effect/Attributes/TraxAuthorizeAttribute.cs index 0a491a3..d37985e 100644 --- a/src/Trax.Effect/Attributes/TraxAuthorizeAttribute.cs +++ b/src/Trax.Effect/Attributes/TraxAuthorizeAttribute.cs @@ -10,11 +10,24 @@ namespace Trax.Effect.Attributes; /// /// Trains without this attribute have no per-train authorization requirements /// (though endpoint-level auth from the configure callback still applies). -/// -/// Multiple attributes can be combined — all must be satisfied. +/// +/// Combinator semantics when the attribute is present: +/// +/// Bare [TraxAuthorize] (no policy, no roles) requires an authenticated user. +/// Policies across all applied attributes are AND'd: every must pass. +/// Roles across all applied attributes are unioned and OR'd: the user must hold at least one of the listed roles. Within a single attribute, is a comma-separated list that is also OR'd. +/// When policies and roles are both specified, both sides must be satisfied. +/// +/// /// The scheduler bypasses this check entirely since it is trusted infrastructure. +/// Authorization is enforced once at API submission time; scheduled and remote-worker +/// executions run against work that was already authorized. /// -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] +[AttributeUsage( + AttributeTargets.Class | AttributeTargets.Interface, + AllowMultiple = true, + Inherited = true +)] public class TraxAuthorizeAttribute : Attribute { ///