Using an exception for authorization failures avoids TOCTOU security holes. Also, in many cases, there are intermediate layers of the call stack that don't have any useful contribution to failure handling; the best they can do is forward the failure return value up the stack. And if one part of an operation fails because of a lack of permissions, it is usually dangerous to continue processing without handling the failure, which is the default behavior that failure return values have in most languages.
By contrast, the performance cost of capturing stack traces when there's an authorization error is insignificant. How many authorization errors do you have per second in normal operation? For many systems, the answer is down in the millibecquerels to microbecquerels.
Under these circumstances, the balance leans quite heavily to the side of using exceptions to report authorization failures.