README.md in rails-auth-0.1.0 vs README.md in rails-auth-0.2.0
- old
+ new
@@ -19,10 +19,101 @@
Rails::Auth can be used to authenticate and authorize end users using browser
cookies, service-to-service requests using X.509 client certificates, or any
other clients with credentials that have proper authenticating middleware.
+## Architecture
+
+Rails::Auth makes use of multiple, independent, single-purpose middleware
+classes to handle specific types of AuthN/AuthZ.
+
+### AuthN
+
+Rails::Auth ships with the following AuthN middleware:
+
+* `Rails::Auth::X509::Middleware`: authenticates X.509 certificates obtained
+ from the Rack environment.
+
+The goal of Rails::Auth's AuthN middleware is to authenticate *credentials*
+taken from the Rack environment and place objects representing them under
+the `"rails-auth.credentials"` key within the Rack environment for use by
+subsequent AuthN or AuthZ middleware. The built-in support is for X.509
+client certificates, but other middleware could handle authentication of
+cookies or (OAuth) bearer credentials.
+
+The intended usage is to have multiple AuthN middlewares that are capable
+of extracting different types of credentials, but also allowing AuthZ
+middleware to apply a single policy to all of them. It's also possible to
+chain AuthN middleware together such that one credential obtained earlier
+in the middleware stack is used to authenticate another (for e.g.
+[channel-bound cookies]).
+
+[channel-bound cookies]: http://www.browserauth.net/channel-bound-cookies
+
+### AuthZ
+
+Rails::Auth ships with one primary AuthZ middleware:
+
+* `Rails::Auth::ACL::Middleware`: support for Access Control Lists.
+
+Access Control Lists (ACLs) let you write a single, declarative policy for
+authorization in your application. ACLs are pluggable and let you write
+a single policy which can authorize access using different types of
+credentials.
+
+ACLs are a declarative approach to authorization, consolidating policies
+into a single file that can be easily audited by a security team without
+deep understanding of the many eccentricities of Rails. These policies
+provide coarse-grained authorization based on routes (as matched by
+regexes) and the credentials extracted by the AuthN middleware. However,
+the do not provide AuthZ which includes specific domain objects, or
+policies around them.
+
+## Comparison to other Rails/Rack auth libraries/frameworks
+
+Below is a comparison of how Rails::Auth relates to the existing landscape
+of Rails AuthN and AuthZ libraries. These are grouped into two different
+categories: libraries Rails::Auth replaces, and libraries with which
+Rails::Auth can be used in a complimentary fashion.
+
+### Replaces:
+
+* [Warden]: Uses a single "opinionated" Rack middleware providing
+ user-centric authentication and methods that allow controllers
+ to imperatively interrogate the authentication context for
+ authorization purposes. By comparison Rails::Auth is not prescriptive
+ and much more flexible about credential types (supporting credentials
+ for both user and service clients) and uses declarative authorization
+ policies in the form of ACLs.
+
+* [Devise]: A mature, flexible, expansive framework primarily intended
+ for user authentication. Some of the same caveats as Warden apply,
+ however Devise provides a framework for modeling users within a Rails
+ app along with common authentication flows, making it somewhat
+ orthogonal to what Rails::Auth provides. Rails::Auth is designed to
+ easily support [claims-based identity] systems where user identity
+ is outsourced to a separate microservice.
+
+### Compliments:
+
+* [Pundit]: Domain object-centric fine-grained authorization using clean
+ object-oriented APIs. Pundit makes authorization decisions around particular
+ objects based on policy objects and contexts. Rails::Auth's credentials
+ can be used as a powerful policy context for Pundit.
+
+* [CanCanCan]: a continuation of the popular CanCan AuthZ library after a
+ period of neglect. Uses a more DSL-like approach to AuthZ than Pundit,
+ but provides many facilities similar to Pundit for domain object-centric
+ AuthZ.
+
+[Warden]: https://github.com/hassox/warden/wiki
+[Devise]: https://github.com/plataformatec/devise
+[Pundit]: https://github.com/elabs/pundit
+[CanCanCan]: https://github.com/CanCanCommunity/cancancan
+
+[claims-based identity]: https://en.wikipedia.org/wiki/Claims-based_identity
+
## Installation
Add this line to your application's Gemfile:
```ruby
@@ -49,16 +140,41 @@
* **AuthZ**: `Rails::Auth::ACL::Middleware`: support for authorizing requests
using Access Control Lists (ACLs).
Documentation of these middleware and how to use them is provided below.
+
+### Controller Methods
+
+Rails::Auth includes a module of helper methods you can use from Rails
+controllers. Include them like so:
+
+```ruby
+class ApplicationController < ActionController::Base
+ include Rails::Auth::ControllerMethods
+
+ def x509_certificate_ou
+ credentials[:x509].try(:ou)
+ end
+
+ def current_username
+ # Note: Rails::Auth doesn't provide a middleware to extract this, it's
+ # just an example of how you could use it with your own claims-based
+ # identity system.
+ credentials[:identity_claims].try(:username)
+ end
+end
+```
+
+This defines the following methods:
+
+* `#credentials`: obtain a HashWithIndifferentAccess containing all of the
+ credentials that Rails::Auth has extracted using its AuthN middleware.
+
### Access Control Lists (ACLs)
ACLs are the main tool Rails::Auth provides for AuthZ. ACLs use a set of
route-by-route matchers to control access to particular resources.
-Unlike some Rails AuthZ frameworks, this gem grants/denies access to
-controller actions, rather than helping you provide different content to
-different roles or varying the parameters allowed in, say, an update action.
Rails::Auth encourages the use of YAML files for storing ACL definitions,
although the use of YAML is not mandatory and the corresponding object
structure output from `YAML.load` can be passed in instead. The following is
an example of an ACL definition in YAML: