mozilla

User FlowΒΆ

Here’s the proposed two-step flow (with BrowserID/FxA assertions):

  1. the client trades a BrowserID assertion for an Auth token and corresponding secret
  2. the client uses the auth token to sign subsequent requests using Hawk Auth.

Getting an Auth token:

Calling the Service:

Detailed steps:

  • the client requests a token, giving its browser id assertion [1]:

    GET /1.0/sync/request_token HTTP/1.1
    Host: token.services.mozilla.com
    Authorization: Browser-ID <assertion>
    
  • The Login Server checks the BrowserID assertion [2] this step will be done locally without calling an external browserid server – but this could potentially happen (we can use PyBrowserID + use the BID.org certificate)

    The user’s email address is extracted, along with any Generation Number associated with the BrowserID certificate.

  • The Login Server asks the Users DB for an existing record matching the users’ email address.

    If so, the allocated Node and previously-seen Generation Number are returned.

  • If the submitted Generation Number is smaller than the recorded one, the Login Server returns an error as the client’s BrowserID credentials are out of date.

    If the submitted Generation Number is larger than the recorded one, the Login Server updates the Users DB with the new value.

  • If the user is not allocated to a Node, the Login Server asks for a new one from the Node Assignment Server [4]

  • The Login Server creates a response with an Auth Token and corresponding Token Secret [5] and sends it back to the user.

    The Auth Token contains the user id and a timestamp, and is signed using the Signing Secret. The Token Secret is derived from the Master Secret and Auth Token using HKDF.

    It also adds the Node url in the response under api_endpoint [6]

    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {'id': <token>,
     'secret': <derived-secret>,
     'uid': 12345,
     'api_endpoint': 'https://example.com/app/1.0/users/12345',
    }
    
  • The client saves the node location and hawkauth parameters to use in subsequent requests. [6]

  • For each subsequent request to the Service, the client calculates a special Authorization header using Hawk Auth [7] and sends the request to the allocated node location [8]:

    POST /request HTTP/1.1
    Host: some.node.services.mozilla.com
    Authorization: Hawk id=<auth-token>
                        ts="137131201",   (client timestamp)
                        nonce="7d8f3e4a",
                        mac="bYT5CMsGcbgUdFHObYMEfcx6bsw="
    
  • The node uses the Signing Secret to validate the Auth Token [9]. If invalid or expired then the node returns a 401

  • The node calculates the Token Secret from its Master Secret and the Auth Token, and checks whether the signature in the Authorization header is valid [10]. If it is invalid then the node returns a 401

  • The node processes the request as defined by the Service [11]