Eagle Auth - Lightweight PKI for REST Authentication
====================================================
WARNING: still just crazy thoughts :)

Changes to Consider:
Why not Hawk: (and why not do it as part of Hawk)
All in all, hawk is pretty good. Most complaints above have
pros and cons. Eagle is mostly of you want an asymmetric 
cryptographic scheme, which makes it safer to share keys between
different servers.

Things to look at:
Eagle Goals:
As opposed to hawk, eagle does not aim to secure HTTP requests.
Hawk makes HTTP reasonably secure with the following features:
Eagle Auth Overview:
As header:
  authentication: Eagle Version=1
                        Credential=<clientId (url-safe)>,
                        Headers=host;x-eagle-start;...,
                        Signature=<url-safe base64 signature>\n
  x-eagle-date: <ISO 8601 Extended format>\n
  x-eagle-expires: <number of seconds>
  x-eagle-content-hash: SHA512 <url-safe base64 hash>\n
Or using query string:
  ?x-eagle-version=1
  &x-eagle-credential=...
  &x-eagle-headers=...
  &x-eagle-signature=...
  &x-eagle-date=<ISO 8601 Extended format>
  &x-eagle-expires=<number of seconds>
  &x-eagle-content-hash=SHA512 <url-safe base64 hash>

Values:
Credential:   clientId (must be url-safe)
Headers:      list of headers: host;x-eagle-content-hash;...
              (also called list of signed headers)
Signature:    url-safe base64 of ed25519.sign(stringToSign, key)

StringToSign:
  eagle.1\n
  verb:<VERB>\n
  resource:<CanonicalURI>\n
  query:<CanonicalQueryString>\n
  \n
  {<header.lowercase()>:<value>\n foreach in Headers}
  \n
headers from "Headers" are included in the order they are listed
in Headers. Their header key is always in lower case.

CanonicalURI:
In short this is everything after the domain (and port) and before
the querystring.

CanonicalQueryString:
Querystring without the key: "x-eagle-signature"


Configuration Options:
Using the configuration, you can set the max life-time of a
signed URL (or a signature for a request). You can also specify
which headers can be provided by query string. But note that
query string and headers cannot conflict. So you maybe not wish
to be the "range" into headersCanBeQueryString as this would
prevent a request with the header range (meaning one thing)
and the querystring range (meaning another).
Hence, do only use "headersCanBeQueryString" for custom headers
that are properly prefixed "x-<app-name>-"

Notice:
You are always welcome to sign more headers than the ones 
required. But notice that some headers must be signed if present.
Modifying this behaviour makes it easy to add custom headers that
you want to make sure are always signed.
In most cases sign as many headers as possible with XHR in a 
browser there are headers you can't set and, thus, cannot sign.

The "mustBeSignedHeader" allows you to ensure that some extra
(optional) headers are covered by the signature. It's very 
similar the hawk "ext" data, which is covered by the HMAC. 


Client Responsibilities
-----------------------
We leave it up to the client to decide how many security measures
to employ. By tweaking server configuration, one can force the
client to include more information in the stringToSign.

Payload Hashing:
In the default configuration "x-eagle-content-hash" is not a
required header. If present it must, however, be amongst the
signed headers.
Obviously, the client should specify this as often as possible,
as doing so makes the signature harder to reuse.
But we also recognize that with query string authentication it
is sometimes hard to do this.

Clock Synchronization:
Again in the default configuration allows the interval 
x-eagle-expires to 31 days. This is useful for
signed URLs that allows you to GET a resource. But it's a very
big interval for requests that takes place immediately.
However, we do not require x-eagle-expires to be specified, if
not specified we'll assume the signature was written at
x-eagle-date and meant to be used immediately, thus only accepting
the configured clock skew tolerance.

Nonces:
Client should probably include a nonce. In distributed servers
validating it will be hard and complicated, so one may choose not
to do this. But including it is basically free.


General Security Considerations
-------------------------------
Authorization with Eagle Scopes
===============================

Eagle only handles authentication, this is packaged as eagle-auth.
The package eagle-scopes implements an authorization scheme with
scopes and temporary credentials on top of eagle-auth. Using this
authorization scheme is completely optional.

With eagle scopes a client has the following properties:
client:
The following headers are added:
x-eagle-authorized-scopes:    <scope1>;<scope2>;<scope3>\n
    (where <scopeX> is URI encoded)
x-eagle-certificate: Key=<publicKey> Signature=...
x-eagle-certificate-version:
x-eagle-certificate-start:
x-eagle-certificate-end:
x-eagle-certificate-scopes:

stringToSign for the certificate signature:
    version:1\n
    key:<temporary-publicKey>\n
    start:<ISO 8601 Extended format>\n
    end:<ISO 8601 Extended format>\n
    scopes:\n
    <scope1>\n
    <scope2>\n
    ...
    <scopeN>\n
    \n

Note to self:
I'm not sure I want to split the certificate into multiple
headers. It would be nice if the certificate was just this one
string that had to be included.
However, it would also be nice if scopes was separate, because
headers length is fairly limited.