How We Authorize Access to Our Apps
Given a need for tiered authorization rules where each tier has a strict superset of the previous tier’s privileges, we use a minimal authorization framework that assigns controller actions to minimum authorization tiers and nothing else because REST endpoints provide a natural model of capabilities, and security is too important and too difficult to manage ad hoc or at any level deeper than the service boundary.
Given an application domain has multiple different classes of user with non-overlapping responsibilities and capabilities, we build a discrete application within the same app domain per orthogonal role (e.g., career path) of end user, sharing a git repository, a core library, and database with the rest of the application domain because the most reliable way to deny authorization to an endpoint is to not have the code for that endpoint be defined at all in the running code.
We use nothing but trust root (e.g., current_user
) chaining for
authorization within a controller action, and do no authorization deeper
in the model layer because the relationships traversed represent the
best documentation of the authorized intent. If a traversed relationship
is intended for read-only access, we enforce this by returning read-only
models.