The rise of web platforms and their associated apps represents a
new way of developing and deploying software. Sites such as
Facebook and Yammer are no longer written by a single entity, but
rather are freely extended by third-party developers offering
competing features to users.
Allowing an app to access more user data allows developers to build
more compelling products. It also opens the door to accidental or
malicious breaches of user privacy. In the case of a website like
Facebook, exposing access to a user's private messages would allow
an external developer to build a search feature. Exciting! But,
another developer can take advantage of this feature to build an app
that mines private messages for credit card numbers, ad keywords, or
other sensitive data.
Frameworks such as Ruby on Rails, Django, Yesod, etc. are geared
towards building monolithic web sites. And, they are great for
this! However, they are not designed for websites that integrate
third-party code, and thus lack a good mechanism for building such
multi-app platforms without sacrificing a user's security or an
app's functionality.
Hails is explicitly designed for building web platforms, where it
is expected that a site will comprise many mutually-distrustful
components written by a variety of entities. We built Hails around
two core design principles.
Separation of policy:
Data access policies should be concisely specified alongside data
structures and schemas, rather than strewn throughout the
codebase in a series of conditionals. Code that implements this
is called a policy module in Hails (see Hails.PolicyModule).
Mandatory access control (MAC):
Data access policies should be mandatory even once code has
obtained access to data. MAC lets platform components modules
productively interact by sharing data, despite mutual distrust.
Haskell lets us implement MAC at a fine grained level using the
information flow control library LIO.
A Hails platform hosts two types of code: apps and /policy
modules/. Apps encompass what would traditionally be considered
controller and view logic. Policy modules are libraries that
implement both the model and the data security policy. They are
invoked directly by apps or other policy modules, but run with
different privileges from the invoking code. Both apps and policy
modules can be implemented by untrusted third parties, with the user
only needing to trust the policy module governing the data in
question. Separating of policy code from app code allows users to
inspect and more easily unserstand the overall security provided by
the system, while MAC guarantees that these policies are enforced
in an end-to-end fashion.