skip to navigation
skip to content

macauthlib 0.6.0


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

To access resources using MAC Access Authentication, the client must have obtained a set of MAC 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 “MAC” as follows:

> GET /protected_resource HTTP/1.1
> Host:

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

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

> GET /protected_resource HTTP/1.1
> Host:
> Authorization: MAC 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 MAC Auth clients, it provides the following function:

  • sign_request(req, id, key, hashmod=sha1): sign a request using MAC Access Auth.

For MAC Auth servers, it provides the following functions:

  • get_id(req): get the claimed MAC Auth id from the request.
  • check_signature(req, key, hashmod=sha1): 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 macauthlib

# Hook up sign_request() to be called on every request.
def auth_hook(req):
    macauthlib.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.

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

class MACAuthMiddleware(object):

    # ...setup code goes here...

    def __call__(self, environ, start_response):

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

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

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

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

0.6.0 - 2013-06-25

  • Support for requests version 1.0.0 and greater; thanks bobbyrward. Unfortunately this is not backwards-compatible with older versions of requests.

0.5.0 - 2012-11-26

  • Support for Python 3, via source-level compatibility.

0.4.0 - 2012-09-31

  • Allow the main API functions to accept a WebOb Request object, a requests Request object, or a WSGI environ dict as first argument. This should make it easier to implement client programs.
  • macauthlib.sign_request() now returns the Authorization header value, which is useful if you pass it something immutable as the request to be signed.
  • Hide functions from macauthlib.utils that were previously available directly from macauthlib. This will ensure users import them from the canonical location.

0.3.0 - 2012-07-11

  • Simplify API of the NonceCache class; it now provides a single method check_nonce() rather than separate is_fresh() and add_nonce() methods.

0.2.0 - 2012-06-01

  • Fix a race condition bug in NonceCache.

0.1.0 - 2012-02-27

  • Initial release.
File Type Py Version Uploaded on Size
macauthlib-0.6.0.tar.gz (md5) Source 2013-06-25 13KB