Overview
MutationContext currently keeps the actor type as an internal property:
internalActorTypeActorType{get;init;}This means that consumers of ModularityKit.Mutator cannot determine whether mutation was initiated by a User, Service, or System. This becomes limitation for external mutation policies and governance components that need to make security or authorization decisions based on the mutation execution context.
Problem
The framework already provides explicit actor types through:
MutationContext.System(...)MutationContext.User(...)MutationContext.Service(...)
However, external consumers cannot inspect the resulting actor type. For example, financial ledger application may need to enforce rule such as:
User nitiated mutations must not be allowed to post entries to protected system accounts, while system level mutations may be allowed.
The mutation policy has access to:
but cannot inspect:
mutation.Context.ActorType
because ActorType is internal.
As a result, consumers may be forced to rely on application specific conventions, such as checking string prefixes:
varisSystemActor=transaction.InitiatedBy.StartsWith("system:",StringComparison.OrdinalIgnoreCase);This is fragile because domain or audit data should not be used as the authoritative source for mutation authorization decisions.
Proposed solution
Expose the actor type for reading while keeping mutation of the property restricted to the framework.
Change:
internalActorTypeActorType{get;init;}to:
publicActorTypeActorType{get;internalinit;}This would allow external consumers to inspect the actor type:
if(mutation.Context.ActorType==ActorType.System){// System level mutation}while preventing external code from directly assigning the value:
context.ActorType=ActorType.System;// still not allowed
The framework would still retain control over how the actor type is assigned.
Optional convenience API
Alternatively, or in addition, MutationContext could expose convenience properties:
publicboolIsSystemActor=>
ActorType == ActorType.System;publicboolIsUserActor=>
ActorType == ActorType.User;publicboolIsServiceActor=>
ActorType == ActorType.Service;
This would allow policies to express their intent more clearly:
if(!mutation.Context.IsSystemActor){returnPolicyDecision.Deny("Non system actors cannot modify protected accounts.",Name);}Additional consideration: System actor identity
MutationContext.System() currently creates system context without an ActorId:
MutationContext.System("Post settlement transaction");Resulting conceptually in:
ActorType = System
ActorId = null
For auditing and governance purposes, it may be useful to identify the specific system component responsible for the mutation. For example:
MutationContext.System(systemId:"ledger-service",reason:"Post settlement transaction");
This would allow downstream consumers to distinguish between different system components while still treating them as system level actors. For example:
ActorType = System
ActorId = ledger-service
Reason = Post settlement transaction
This could be particularly useful in distributed systems where multiple internal services perform mutations.
Expected outcome
External mutation policies should be able to reliably distinguish between:
without relying on application specific string conventions or domain data.
This would make MutationContext more useful for:
- Security policies
- Authorization decisions
- Governance rules
- Audit trails
- Compliance controls
- Financial domain policies
- Multi service mutation workflows
The key principle is that MutationContext should provide the authoritative execution context, while domain entities such as LedgerTransaction should remain responsible for storing audit information about the resulting mutation.
Overview
MutationContextcurrently keeps the actor type as aninternalproperty:This means that consumers of
ModularityKit.Mutatorcannot determine whether mutation was initiated by aUser,Service, orSystem. This becomes limitation for external mutation policies and governance components that need to make security or authorization decisions based on the mutation execution context.Problem
The framework already provides explicit actor types through:
However, external consumers cannot inspect the resulting actor type. For example, financial ledger application may need to enforce rule such as:
The mutation policy has access to:
but cannot inspect:
because
ActorTypeisinternal.As a result, consumers may be forced to rely on application specific conventions, such as checking string prefixes:
This is fragile because domain or audit data should not be used as the authoritative source for mutation authorization decisions.
Proposed solution
Expose the actor type for reading while keeping mutation of the property restricted to the framework.
Change:
to:
This would allow external consumers to inspect the actor type:
while preventing external code from directly assigning the value:
The framework would still retain control over how the actor type is assigned.
Optional convenience API
Alternatively, or in addition,
MutationContextcould expose convenience properties:This would allow policies to express their intent more clearly:
Additional consideration: System actor identity
MutationContext.System()currently creates system context without anActorId:Resulting conceptually in:
For auditing and governance purposes, it may be useful to identify the specific system component responsible for the mutation. For example:
This would allow downstream consumers to distinguish between different system components while still treating them as system level actors. For example:
This could be particularly useful in distributed systems where multiple internal services perform mutations.
Expected outcome
External mutation policies should be able to reliably distinguish between:
UserServiceSystemUnknownwithout relying on application specific string conventions or domain data.
This would make
MutationContextmore useful for:The key principle is that
MutationContextshould provide the authoritative execution context, while domain entities such asLedgerTransactionshould remain responsible for storing audit information about the resulting mutation.