SummaryShould authorization in CQRS/DDD be implemented per-command/query or not?I am developing for the first time an online application using more or less strictly the DDD CQRS pattern. I bumped into some problem, which I can't really get my head around.The application I am building is a ledger application allowing people to create ledgers, as well as allowing other people to view/edit/delete them, such as employees. The creator of a ledger should be able to edit the access rights of the ledger he created. Could even change ownership. The domain has two aggregates TLedger and TUser.I read a lot of posts with the DDD / CQRS keyword concerning security, authorization, etc. Most of them stated that authorization was a Generic Subdomain, unless one was building a security application. In this case, the core domain is a certainly an accounting domain interested with transactions, balancing and accounts. But the functionality of being able to manage fine grained access to the ledgers is also required. I'm wondering how to design this in DDD/CQRS terms.It's stated in the DDD tutorials all around the place that the commands are part of the ubiquitous language. They're meaningful. They're concrete actions that represent the real thing.Because all those commands and queries are actual actions that users would execute in real life, should the implementation of the authorization be coupled with all these commands and queries ? A user would have authorization to execute TLedger.addTransaction() but not TLedger.removeTransaction() for example. Or, a user would be allowed to execute the query getSummaries() but not getTransactions().A tri-dimensional mapping would exist in the form of user-ledger-command or user-ledger-query to determine the access rights.Or, in a decoupled way, named permissions would be registered for a user. Permissions that would then be mapped for specific commands. For example, permission ManageTransactions would allow a user to execute AddTransaction(), RemoveTransaction(), etc.Permissions mapping user -> ledger -> command/queryPermissions mapping user -> ledger -> permission -> command/queryThat's the first part of the question. Or in brief, should authorization in CQRS/DDD be implemented per-command or per-query? Or, should authorization be decoupled from the commands?Secondly, concerning authorization based on permissions. A User should be able to manage the permissions on his Ledgers or on the Ledgers he's been allowed to manage.Authorization management commands happens in the LedgerI thought of adding the events/commands/handlers into the Ledger aggregate, such as grantPermission(), revokePermission(), etc. In this case, enforcing those rules would happen into the command handlers. But this would require all commands to include the id of the user who issued that command. Then I would check into the TLedger if the permission exists for that user to execute that command.For example :class TLedger{     function addTransactionCmdHandler(cmd){        if (!this.permissions.exist(user, 'addTransaction')            throw new Error('Not Authorized');    }}Authorization management commands in the UserThe other way around would be to include the permissions into the TUser. A TUser would have a set of permissions. Then, in the TLedger command handlers, I would retrieve the user and check if he has permission to execute the command. But this would require me to fetch the TUser aggregate for every TLedger command.class TAddTransactionCmdHandler(cmd) {    this.userRepository.find(cmd.userId)    .then(function(user){        if (!user.can(cmd)){            throw new Error('Not authorized');        }        return this.ledgerRepository.find(cmd.ledgerId);    })    .then(function(ledger){        ledger.addTransaction(cmd);    })}Another domain with serviceAnother possibility would be to model another authorization domain completely. This domain would be interested in access rights, authorization etc. The accounting subdomain would then use a service to access this authorization domain in the form of AuthorizationService.isAuthorized(user, command).class TAddTransactionCmdHandler(cmd) {    authService.isAuthorized(cmd)    .then(function(authorized){        if (!authorized) throw new Error('Not authorized');        return this.ledgerRepository.find(cmd.ledgerId)    })    .then(function(){        ledger.addTransaction(cmd);    })}What decision would be the most DDD/CQRS way?
DDD CQRS - per-query and per-command authorization
domain driven design;cqrs