persona-idp

Persona (BrowserID) Identity Provider https://github.com/frasertweedale/hs-persona-idp

Latest on Hackage:0.1.0.2

This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.

AGPL-3 licensed by Fraser Tweedale
Maintained by frase@frase.id.au
persona-idp is a simple `Mozilla Persona`_ (formerly BrowserID)
identity provider (IdP).

.. _Mozilla Persona: https://www.mozilla.org/persona


Installation
============

Installation is via ``cabal``, the Haskell package tool::

cabal install persona-idp

Help packaging persona-idp for specific operating systems would be
very much appreciated.


Initialisation
==============

To initialise the IdP, run::

persona init --app-path <path> --hostname <host>

The ``--app-path`` argument species the path under the domain at
which the IdP will be mounted. If it is at the root, use `/`.

The ``--hostname`` argument is the fully qualified domain name of
the *authority*, which will either be the users' email domain, or
the host that is delegated to when using a *delegated support
document*.

The ``init`` command generates the authority keypair and support
documents. Files are stored in ``~/.persona-idp``. There is
currently no mechanism for overriding the config directory - patches
welcome!


Starting the server
===================

To run the IdP, execute::

persona serve

The IdP listens on port 3000 by default (use ``-p <port>`` to listen
on a different port) and is designed to be run behind a reverse
proxy providing TLS termination and user authentication.


Web server configuration
========================

TLS is required. Acquiring a server certificate and enabling TLS is
beyond the scope of this README.

persona-idp requires the webserver to authenticate users. Several
mechanisms are supported:

* Any authentication mechanism where the user's email address can be
provided to the IdP via the ``REMOTE_USER`` HTTP header. For
security reasons, this header MUST NOT be passed from the original
request to the IdP.

* X.509 client certificate authentication can be used. The
``REMOTE_USER`` header MUST NOT be set, and the PEM-encoded client
certificate is provided in the ``SSL_CLIENT_CERT`` header. The
email address is first looked for in the Subject Alternative Name
extension, then the Subject DN.

Support for other authentication methods could be added. Please
contact the author to discuss.

Nginx
-----

The following example explains how to configure Nginx to use client
certificate authentication. The IdP is assumed to be running on the
same host as Nginx and listening on port 3000.

Nginx does not support the ``ssl_verify_client`` directive in
location context, so the server as a whole must request (but not
require) a client certificate. If a valid certificate is provided,
details are passed to the IdP via the ``proxy_set_header``
directive.

::

server {
listen 443 ssl;
server_name persona.example.com;
ssl_certificate /path/to/chainedcert.pem;
ssl_certificate_key /path/to/key;

ssl_client_certificate /path/to/ca.pem;
ssl_verify_client optional;
proxy_set_header REMOTE_USER "";
proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;

location / {
proxy_pass http://localhost:3000;
}
}

If the IdP is not mounted at the root, two location blocks are
required. The mount point is the ``--app-path`` argument
used for ``persona init``::

server {
... # as above

location /the/mountpoint {
proxy_pass http://localhost:3000;
}

location /.well-known/browserid {
proxy_pass http://localhost:3000/support;
}
}


Finally, any hosts delegating to the authority can also be
configured to read the delegated support document from the IdP::

server {
listen 443 ssl;
servername example.com;

...

location /.well-known/browserid {
proxy_pass http://localhost:3000/delegated-support;
}
}


Apache
------

The Apache configuration is similar to the Nginx configuration, but
note that Apache supports ``SSLVerifyClient`` in location context so
so the server could be configured to *require* a valid client
certificate for the ``/provisioning`` location whilst not requesting
a certificate for other locations. Such a configuration requires
TLS renegotiation and is untested - but if you try it I would like
to know your results.

A complete example configuration for Apache would be a valued
contribution to this README.


Testing the IdP
===============

#. Ensure that the browser will be able to authenticate the user
when the provisioning workflow begins (e.g. install client
certificate if using certificate authentication).

#. Visit https://login.persona.org/ and click *Sign In*.

#. Enter your email address and click *next*.

#. If prompted, select a certificate or complete the required
authentication. The login process should now complete without
further interaction.


License
=======

persona-idp is free software: you can redistribute it and/or modify
it under the terms of the `GNU Affero General Public License`__ as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

__ http://www.gnu.org/licenses/agpl.html


Contributing
============

The persona-idp source code is available from
https://github.com/frasertweedale/hs-persona-idp.

Bug reports, patches, feature requests, code review and
documentation are welcome.

To submit a patch, please use ``git send-email`` or create a GitHub
pull request. Write a `well formed commit message`_. If your patch
is nontrivial, update the copyright notice at the top of each added
or changed file.

.. _well formed commit message: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
comments powered byDisqus