hawkauthlib

Hawk Access Authentication protocol


Keywords
authentication, Hawk, HTTP, request, signing, inactive, unmaintained
License
MPL-2.0
Install
pip install hawkauthlib==2.0.0

Documentation

hawkauthlib: library for implementing Hawk Access Authentication

This is a low-level library for implementing Hawk Access Authentication, a simple HTTP request-signing scheme described in:

https://npmjs.org/package/hawk

To access resources using Hawk Access Authentication, the client must have obtained a set of Hawk credentials including an id and a secret key. They use these credentials to make signed requests to the server.

When accessing a protected resource, the server will generate a 401 challenge response with the scheme "Hawk" as follows:

> GET /protected_resource HTTP/1.1
> Host: example.com

< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Hawk

The client will use their Hawk credentials to build a request signature and include it in the Authorization header like so:

> GET /protected_resource HTTP/1.1
> Host: example.com
> Authorization: Hawk id="h480djs93hd8",
>                     ts="1336363200",
>                     nonce="dj83hs9s",
>                     mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="

< HTTP/1.1 200 OK
< Content-Type: text/plain
<
< For your eyes only:  secret data!

This library provices the low-level functions necessary to implement such an authentication scheme. For Hawk Auth clients, it provides the following function:

  • sign_request(req, id, key, algorithm="sha256"): sign a request using Hawk Access Auth.

For Hawk Auth servers, it provides the following functions:

  • get_id(req): get the claimed Hawk Auth id from the request.
  • check_signature(req, key, algorithm="sha256"): check that the request was signed with the given key.

The request objects passed to these functions can be any of a variety of common object types:

  • a WSGI environment dict
  • a webob.Request object
  • a requests.Request object
  • a string or file-like object of request data

A typical use for a client program might be to install the sign_request function as an authentication hook when using the requests library, like this:

import requests
import functools
import hawkauthlib

# Hook up sign_request() to be called on every request.
def auth_hook(req):
    hawkauthlib.sign_request(req, id="<AUTH-ID>", key="<AUTH-KEY>")
    return req
session = requests.session(hooks={"pre_request": auth_hook})

# Then use the session as normal, and the auth is applied transparently.
session.get("http://www.secret-data.com/get-my-data")

A typical use for a server program might be to verify requests using a WSGI middleware component, like this:

class HawkAuthMiddleware(object):

    # ...setup code goes here...

    def __call__(self, environ, start_response):

        # Find the identity claimed by the request.
        id = hawkauthlib.get_id(environ)

        # Look up their secret key.
        key = self.SECRET_KEYS[id]

        # If the signature is invalid, error out.
        if not hawkauthlib.check_signature(environ, key):
            start_response("401 Unauthorized",
                           [("WWW-Authenticate", "Hawk")])
            return [""]

        # Otherwise continue to the main application.
        return self.application(environ, start_response)

The following features of the Hawk protocol are not yet supported:

  • Bewits.
  • Timestamp adjustment.
  • Calculating or verifying the server's response signature.
  • Calculating or verifying payload hashes.