Class Actor
- Namespace
- Trellis.Authorization
- Assembly
- Trellis.Authorization.dll
Represents the current authenticated user making the request. Contains identity, permissions, forbidden permissions, and contextual attributes used by authorization behaviors.
public sealed class Actor : IEquatable<Actor>
- Inheritance
-
Actor
- Implements
- Inherited Members
- Extension Methods
Remarks
Hydrated during authentication/middleware. Permissions should be pre-flattened from all sources (JWT roles, database groups, organizational hierarchies) before constructing the Actor so that all permission checks remain O(1).
Scoped permissions use the "Permission:Scope" convention
(e.g., "Document.Edit:Tenant_A").
Add scoped entries to Permissions and check with
HasPermission(string, string).
All permission and attribute lookups use ordinal (case-sensitive) comparison. Ensure consistent casing when hydrating permissions, forbidden permissions, and attributes.
Equality is identity-based. Actor is conceptually an entity — its
Id is a stable, externally-meaningful principal identifier (e.g. JWT
sub claim) and the other properties are point-in-time state about that principal
(granted permissions and ABAC attributes change over time). Two Actor
instances with the same Id are equal even when their Permissions
or Attributes differ; two with different Ids are never equal.
This deliberately mirrors the framework's domain-layer
Trellis.Entity<TId> semantics without taking on the full IAggregate
surface (Actor is an authorization-layer principal, not a domain aggregate root).
Constructors
Actor(string, IReadOnlySet<string>, IReadOnlySet<string>, IReadOnlyDictionary<string, string>)
Convenience constructor that accepts the actor id as a raw string (typically a claim value at the authentication boundary) and wraps it in ActorId. Authors writing typed application code should prefer the Actor(ActorId, IReadOnlySet<string>, IReadOnlySet<string>, IReadOnlyDictionary<string, string>) overload.
public Actor(string id, IReadOnlySet<string> permissions, IReadOnlySet<string> forbiddenPermissions, IReadOnlyDictionary<string, string> attributes)
Parameters
idstringThe raw principal id (e.g., a JWT
subclaim value).permissionsIReadOnlySet<string>The set of permissions granted to the actor.
forbiddenPermissionsIReadOnlySet<string>Permissions explicitly denied for this actor.
attributesIReadOnlyDictionary<string, string>Contextual ABAC attributes.
Exceptions
- ArgumentException
Thrown when
idis null, empty, or whitespace.- ArgumentNullException
Thrown when
permissions,forbiddenPermissions, orattributesis null.
Actor(ActorId, IReadOnlySet<string>, IReadOnlySet<string>, IReadOnlyDictionary<string, string>)
Initializes a new Actor and snapshots the supplied authorization state.
[JsonConstructor]
public Actor(ActorId id, IReadOnlySet<string> permissions, IReadOnlySet<string> forbiddenPermissions, IReadOnlyDictionary<string, string> attributes)
Parameters
idActorIdThe unique identifier of the actor (e.g., user ID from JWT sub claim).
permissionsIReadOnlySet<string>The set of permissions granted to the actor. Implementations such as HashSet<T> and FrozenSet<T> provide O(1) lookups. Scoped permissions must use the PermissionScopeSeparator convention (e.g.
"Document.Edit:Tenant_A") so they round-trip correctly through HasPermission(string, string).forbiddenPermissionsIReadOnlySet<string>Permissions that are explicitly denied for this actor. A permission present in both
permissionsandforbiddenPermissionsis treated as denied (deny always overrides allow).attributesIReadOnlyDictionary<string, string>Contextual attributes for attribute-based access control (ABAC). Stores environmental metadata such as IP address, MFA status, risk score, or VPN status. Use ActorAttributes constants for well-known keys.
Exceptions
- ArgumentNullException
Thrown when
id,permissions,forbiddenPermissions, orattributesis null.
Fields
PermissionScopeSeparator
The separator used between permission name and scope in scoped permission strings.
public const char PermissionScopeSeparator = ':'
Field Value
Properties
Attributes
Contextual attributes for attribute-based access control (ABAC).
public IReadOnlyDictionary<string, string> Attributes { get; init; }
Property Value
ForbiddenPermissions
Permissions that are explicitly denied for this actor.
public IReadOnlySet<string> ForbiddenPermissions { get; init; }
Property Value
Id
The unique identifier of the actor (e.g., user ID from JWT sub claim). Strongly typed via ActorId so the principal identity flows through authorization-layer APIs and consumer aggregate fields as a domain type rather than an untyped string.
public ActorId Id { get; init; }
Property Value
Permissions
The set of permissions granted to the actor. Scoped permissions use the
PermissionScopeSeparator convention (e.g. "Document.Edit:Tenant_A")
— the format HasPermission(string, string) reconstructs at lookup time.
public IReadOnlySet<string> Permissions { get; init; }
Property Value
Methods
Create(string, IReadOnlySet<string>)
Convenience factory that accepts the actor id as a raw string (typically a claim value at the authentication boundary) and wraps it in ActorId. Authors writing typed application code should prefer the Create(ActorId, IReadOnlySet<string>) overload.
public static Actor Create(string id, IReadOnlySet<string> permissions)
Parameters
idstringThe raw principal id (e.g., a JWT
subclaim value).permissionsIReadOnlySet<string>The set of permissions granted to the actor.
Returns
Exceptions
- ArgumentException
Thrown when
idis null, empty, or whitespace.- ArgumentNullException
Thrown when
permissionsis null.
Create(ActorId, IReadOnlySet<string>)
Creates an Actor with no forbidden permissions and no ABAC attributes. Convenience factory for the common case where only identity and permissions are needed.
public static Actor Create(ActorId id, IReadOnlySet<string> permissions)
Parameters
idActorIdThe unique identifier of the actor.
permissionsIReadOnlySet<string>The set of permissions granted to the actor.
Returns
Exceptions
- ArgumentNullException
Thrown when
idorpermissionsis null.
Equals(object?)
Determines whether the specified object is equal to the current object.
public override bool Equals(object? obj)
Parameters
objobjectThe object to compare with the current object.
Returns
Equals(Actor?)
Determines whether the specified Actor represents the same principal.
public bool Equals(Actor? other)
Parameters
otherActorThe actor to compare against.
Returns
- bool
true when both actors share the same Id (ordinal comparison); otherwise false. The other properties (Permissions, ForbiddenPermissions, Attributes) are state about the principal, not part of identity, and are intentionally excluded from the equality comparison.
Remarks
Identity-based equality mirrors the domain-layer Trellis.Entity<TId>
pattern without inheriting the full IAggregate contract. Two
Actors with the same Id represent the same principal even
when one carries a freshly-rotated permission set or a different request-bound IP
address — both are point-in-time snapshots of the same actor.
GetAttribute(string)
Returns the value of the specified attribute, or null if the attribute does not exist.
public string? GetAttribute(string key)
Parameters
keystringThe attribute key. Use ActorAttributes constants for well-known keys.
Returns
- string
The attribute value if found; otherwise
null.
Exceptions
- ArgumentNullException
Thrown when
keyis null.
GetHashCode()
Serves as the default hash function.
public override int GetHashCode()
Returns
- int
A hash code for the current object.
Remarks
The hash is derived from Id only, matching the identity-based equality contract on Equals(Actor?).
GetRequiredAttribute<TVo>(string)
Returns the attribute identified by key parsed into the value object
TVo through its IParsable<TSelf> implementation, so a claim-sourced
value is validated by the same domain rule that guards request input. Works for any backing primitive —
string-, Guid-, int-, or decimal-backed value objects alike.
public Result<TVo> GetRequiredAttribute<TVo>(string key) where TVo : class, IParsable<TVo>
Parameters
keystringThe attribute key. Use ActorAttributes constants for well-known keys.
Returns
- Result<TVo>
A success Result<TValue> with the typed value when the attribute is present and valid; otherwise a failed Result<TValue> with an Error.InvalidInput whose field is the attribute
key. A missing attribute is treated as a missing value and fails the same way.
Type Parameters
TVoA Trellis value object — any source-generated
Required*<T>subclass (for exampleRequiredString,RequiredGuid,RequiredInt), which the generator makes IParsable<TSelf>. The attribute string is parsed and validated through the type's ownTryParse, which routes through itsTryCreatevalidation.
Exceptions
- ArgumentNullException
Thrown when
keyis null.
HasAllPermissions(IEnumerable<string>)
Returns true if this actor has ALL of the specified permissions. Each permission is checked against ForbiddenPermissions (deny-aware).
public bool HasAllPermissions(IEnumerable<string> permissions)
Parameters
permissionsIEnumerable<string>The permissions to check.
Returns
- bool
True if the actor has every specified permission and none are forbidden; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
permissionsis null.
HasAnyPermission(IEnumerable<string>)
Returns true if this actor has ANY of the specified permissions. Each permission is checked against ForbiddenPermissions (deny-aware).
public bool HasAnyPermission(IEnumerable<string> permissions)
Parameters
permissionsIEnumerable<string>The permissions to check.
Returns
- bool
True if the actor has at least one non-forbidden specified permission; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
permissionsis null.
HasAttribute(string)
Returns true if this actor has the specified attribute.
public bool HasAttribute(string key)
Parameters
keystringThe attribute key. Use ActorAttributes constants for well-known keys.
Returns
- bool
True if the attribute exists; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
keyis null.
HasPermission(string)
Returns true if this actor has the specified permission and it is not forbidden. If the permission exists in both Permissions and ForbiddenPermissions, deny wins and this returns false.
public bool HasPermission(string permission)
Parameters
permissionstringThe permission to check (case-sensitive, ordinal comparison).
Returns
- bool
True if the permission is granted and not explicitly denied; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
permissionis null.
HasPermission(string, string)
Returns true if this actor has the specified permission within the given scope
and it is not forbidden. Uses the "Permission:Scope" convention with
PermissionScopeSeparator.
public bool HasPermission(string permission, string scope)
Parameters
permissionstringThe base permission (e.g.,
"Document.Edit").scopestringThe scope qualifier (e.g.,
"Tenant_A"or a resource ID). Case-sensitive.
Returns
- bool
True if the scoped permission is granted and not explicitly denied; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
permissionorscopeis null.
IsOwner(string)
Convenience overload that accepts the resource owner id as a raw string. Authors writing typed application code should prefer IsOwner(ActorId) so the comparison is type-checked at the call site.
public bool IsOwner(string resourceOwnerId)
Parameters
resourceOwnerIdstringThe identifier of the resource owner.
Returns
- bool
True if the actor's ID matches the resource owner ID; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
resourceOwnerIdis null.
IsOwner(ActorId)
Returns true if this actor is the owner of the specified resource. Compares the actor's Id against the resource owner id using ActorId's value-equality semantics (ordinal string comparison).
public bool IsOwner(ActorId resourceOwnerId)
Parameters
resourceOwnerIdActorIdThe identifier of the resource owner (e.g., creator's actor id).
Returns
- bool
True if the actor's ID matches the resource owner ID; otherwise false.
Exceptions
- ArgumentNullException
Thrown when
resourceOwnerIdis null.
TryGetAttribute<TVo>(string, out TVo?)
Attempts to parse the attribute identified by key into the value object
TVo through its IParsable<TSelf> implementation.
public bool TryGetAttribute<TVo>(string key, out TVo? value) where TVo : class, IParsable<TVo>
Parameters
keystringThe attribute key. Use ActorAttributes constants for well-known keys.
valueTVoWhen this method returns true, the parsed value; otherwise null.
Returns
- bool
true when the attribute is present and valid; false when it is absent or fails the value object's validation.
Type Parameters
TVoA Trellis value object — any source-generated
Required*<T>subclass (string-,Guid-,int-backed, and so on), which the generator makes IParsable<TSelf>.
Exceptions
- ArgumentNullException
Thrown when
keyis null.
Operators
operator ==(Actor?, Actor?)
Determines whether two actors represent the same principal (identity-based comparison).
public static bool operator ==(Actor? left, Actor? right)
Parameters
Returns
operator !=(Actor?, Actor?)
Determines whether two actors represent different principals.
public static bool operator !=(Actor? left, Actor? right)