Here's one way you could handle this ...
On one side you have a security model (might be a bounded context in ddd speak) that is solving the problem of assigning permissions to subjects (users), maybe indirectly through the use of roles. I would envision upper boundaries (max numbers) to be an attribute associated with the assigned permission.
There's also a query part to this model. Yet, it can only answer "simple" questions:
- Has this user permission to create filters?
- How many filters can this user create?
Some would even say this query part is a separate model altogether.
On the other end you have your application's model which is largely "security" free apart from these pesky requirements along the lines of "user John Doe can only create 3 filter". As an aside, it's doubtful we're still speaking of a "user" at this point, but rather of a person acting in a certain role in this particular use case. Anyway, back to how we could keep this somewhat separate. Suppose we have a somewhat layered approach and we have an application service with an authorization service in front. The responsibility of the authorization service is to answer the question "is this user allowed to perform this operation? yes or no?" and stop processing if the answer is no. Here's a very naive version of that (C#).
public class FilterAuthorizationServices :
Handles<CreateFilter>
{
public FilterAuthorizationServices(FilterRepository filterRepository) { ... }
public void Authorize(Subject subject, CreateFilter message)
{
if(!subject.HasPermissionTo("CreateFilter"))
{
throw new NotAuthorizedException("...");
}
if(filterRepository.CountFiltersCreatedBy(subject.Id) >
subject.GetTheMaximumNumberOfFiltersAllowedToCreate())
{
throw new NotAuthorizedException("...");
}
}
}
Notice how the application service is not even mentioned here. It can concentrate on invoking the actual domain logic. Yet, the authorization service is using both the query part of the above model (embodied by the Subject) and the model of the application (embodied by the FilterRepository) to fulfill the authorization request. Nothing wrong with doing it this way.
You could even go a step further and ditch the need for the application's model if that model could somehow provide the "current number of created filters" to the security model. But that might be a bridge too far for you, since that would lead down the path of evaluating dynamic expressions (which wouldn't necessarily be a bad place to be in). If you want to go there, may I suggest you create a mini DSL to define the required expressions and associated code to parse and evaluate them.
If you'd like brokered authorization you could look at something like XACML (https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml) though you'll have to overcome your fear of XML first ;-)