CloudServices/Sagrada/TokenServer: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 33: Line 33:
== Definitions and assumptions ==
== Definitions and assumptions ==


First, a few definitions:
First, a few definitions.  The major players in the network topology are:


* '''Service''': a service Mozilla provides, like '''Sync''' or '''Easy Setup'''.
* '''Service''': a service Mozilla provides, like '''Sync''' or '''Easy Setup'''.
Line 43: Line 43:
* '''Cluster''': Group of webheads and storage devices that make up a set of Service Nodes.
* '''Cluster''': Group of webheads and storage devices that make up a set of Service Nodes.
* '''Colo''': physical datacenter, may contain multiple clusters
* '''Colo''': physical datacenter, may contain multiple clusters
* '''Master Secret''':  the secret shared between Login Server and Service Node. Never used directly, only for deriving other secrets.
 
Cryptographically, we have the following terms:
 
* '''HKDF''':  HMAC-based Key Derivation Function, a method for deriving multiple secret keys from a single master secret (https://tools.ietf.org/html/rfc5869).
* '''Two-Legged OAuth''':  an authentication scheme for HTTP requests, based on a HMAC signature over the request metadata.  (http://tools.ietf.org/html/rfc5849#section-3)
* '''Auth Token''': used to identify the user after starting a session.  Contains the user application id and the expiration date.
* '''Metadata Token''': used to send application-specific metadata for the Service.
* '''Master Secret''':  a secret shared between Login Server and Service Node. Never used directly, only for deriving other secrets.
* '''Signing Secret''': derived from the master secret, used to sign auth and metadata tokens. For example: sig-secret = HKDF_Expand(master-secret, "SIGN")
* '''Signing Secret''': derived from the master secret, used to sign auth and metadata tokens. For example: sig-secret = HKDF_Expand(master-secret, "SIGN")
* '''Encryption Secret''': derived from the master secret, used to encrypt the metadata token.  For example: enc-secret = HKDF_Expand(master-secret, "ENCRYPT")
* '''Encryption Secret''': derived from the master secret, used to encrypt the metadata token.  For example: enc-secret = HKDF_Expand(master-secret, "ENCRYPT")
Line 61: Line 68:
Here's the proposed two-step flow (with Browser ID):
Here's the proposed two-step flow (with Browser ID):


# the client trades a browser id assertion for a session token
# the client trades a browser id assertion for an auth token and corresponding secret
# the client turns the session token into a oauth token
# the client uses the auth token to sign subsequent requests using two-legged oauth


Getting a session token:
Getting an auth token:


<pre>
<pre>
Line 77: Line 84:
                                 |<--- build token  [5]    |            |                    |               
                                 |<--- build token  [5]    |            |                    |               
keep token <-------- [6] --------|                          |            |                    |                 
keep token <-------- [6] --------|                          |            |                    |                 
create signed auth header [7]    |                          |            |                    |               
</pre>
</pre>


Line 86: Line 92:
Client                                          Service Node
Client                                          Service Node
============================================================
============================================================
call node --------------- [8] ---|---------------->|--> verify token  
create signed auth header [7]    |                | 
                                 |                |<-- process request [9]
call node --------------- [8] ---|---------------->|--> verify token [9]
                                |                |    verify request signature [10]
                                 |                |<-- process request [11]
get response <-------------------|-----------------|
get response <-------------------|-----------------|
</pre>
</pre>




* the client request a token, giving its browser id assertion [1]  
* the client requests a token, giving its browser id assertion [1]  


     POST /request_token HTTP/1.1
     POST /request_token HTTP/1.1
Line 104: Line 112:
* the Login Server asks the Users DB if the user is already allocated to a node. [3]
* the Login Server asks the Users DB if the user is already allocated to a node. [3]
* if the user is not allocated to a node, the Login Server asks a new one to the Node Assignment Server [4]
* if the user is not allocated to a node, the Login Server asks a new one to the Node Assignment Server [4]
* the Login Server creates a response with a session token [5], using the user id, a time stamp and a secret string only known by the selected node and itself, and sends it back to the user along with a secret derived from the shared secret, using HKDF (https://tools.ietf.org/html/rfc5869). It also adds the node url in the response, and optionaly a metadata token. [6]
* 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, and optionaly a metadata token. [6]


   HTTP/1.1 200 OK
   HTTP/1.1 200 OK
   Content-Type: application/json
   Content-Type: application/json
    
    
   {'oauth_consumer_key': <token>,
   {'oauth_consumer_key': <auth-token>,
     'oauth_consumer_secret': <derived-secret>,
     'oauth_consumer_secret': <token-secret>,
     'service_entry': <node>,
     'service_entry': <node>,
     'metadata': <metadata-token>
     'metadata': <metadata-token>
     }
     }


* the client calculates with the information received, an OAuth authorization header, and saves the node location. [6]
* the client saves the node location and oauth parameters to use in subsequent requests. [6]
* the client calls the right node, using the special Authorization header. It tramsmits as-is the token and the metadata token if provided [7]
* for each subsequent request to the Service, the client calculates a special Authorization header using two-legged OAuth [7] and sends the request to the allocated node location [8] along with the metadata token if provided


     POST /request HTTP/1.1
     POST /request HTTP/1.1
     Host: some.node.services.mozilla.com
     Host: some.node.services.mozilla.com
     Authorization: OAuth realm="Example",
     Authorization: OAuth realm="Example",
                    oauth_consumer_key=<token> 
                     metadata=<metadata-token>,
                     metadata=<metadata-token>,
                     oauth_token="kkk9d7dh3k39sjv7",
                     oauth_consumer_key=<auth-token> 
                     oauth_signature_method="HMAC-SHA1",
                     oauth_signature_method="HMAC-SHA1",
                     oauth_timestamp="137131201",  (client timestamp)
                     oauth_timestamp="137131201",  (client timestamp)
Line 130: Line 137:




* the node is able with its shared secret to validate that the request is valid, by calculating the derived key given the salt and the shared secret [9]. If it's an invalid or expired token, the node returns a 401
* 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's an invalid then the node returns a 401
* the node processes the request as defined by the Service [11]


== Tokens ==  
== Tokens ==  


A token is a json encoded mapping. They are two tokens:
A token is a json encoded mapping. The are two tokens:


* the authorization token: contains the user application id and the expiration date.
* the authorization token: contains the user application id and the expiration date.
Line 151: Line 160:
   auth_token = {'uid': '123', 'expires': 1324654308.907832}   
   auth_token = {'uid': '123', 'expires': 1324654308.907832}   


The token is signed using the salted derived secret and base64-ed. The signature is HMAC-SHA1:
The token is signed using the signing secret and base64-ed. The signature is HMAC-SHA1:


   auth_token, signature = HMAC-SHA1(auth_token, secret_key)
   auth_token, signature = HMAC-SHA1(auth_token, sig_secret)
   auth_token = b64encode(auth_token, salt, signature)
   auth_token = b64encode(auth_token, salt, signature)


'''The authorization token is not encrypted'''
'''The authorization token is not encrypted'''
Confirmed users
358

edits

Navigation menu