CloudServices/Sagrada/ServiceClientFlow
Introduction
All Sagrada services utilize a common discovery and authentication flow. There are three steps: Discovery, Authentication, and Access, to discover and utilize services in this model.
Discovery
All service providers will have a discovery URL, which provides clients with a list of available services and provider-specific URLs for clients.
API
GET /discover
This is a straightforward GET call, returning a JSON object containing all relevant data.
GET https://directory.services.mozilla.com/discover
HTTP Response Codes
200 | Success |
404 | Resource not found (clients should treat this as a configuration error) |
503 | Service Unavailable, clients should respect Retry-After if provided, otherwise should retry no more than once per 15 minutes. |
Response Object Format
There are two top-level objects, services and urls. services contains the full set of available services, with per-API-version authentication endpoints. urls is for non-service URLs, such as ToS/PP links, and any other non-service URLs that may be necessary/needed for clients.
{ "services": { "simple_storage": { "2.0": "https://token.services.mozilla.com/simple_storage/2.0", "2.1": "https://token.services.mozilla.com/simple_storage/2.1" }, "durable_storage": { "1.0": "https://token.services.mozilla.com/durable_storage/1.0" } }, "urls": { "privacy_policy": "https://services.mozilla.com/pp/", "terms_of_service": "https://services.mozilla.com/tos/" } }
Authentication
API
The specific URL format used for authenticating to a service is an implementation-specific detail. To obtain the authentication URL for a service, a client must call the Service Discovery API, and use the provided URL for the appropriate service.
Access
While the semantics of the specific REST API may vary, all service requests need to be signed using a MAC Auth id and key obtained from a call to the Authentication API. Signatures are constructed according to the MAC Access Authentication standard with the hmac-sha-1 algorithm. An example is included below for clarity.
To make the following authenticated request to a Sagrada service::
GET https://example.services.mozilla.com/user/data
The client will need to:
1) Obtain the current timestamp in seconds and generate a random nonce string::
ts = "1330916952" nonce = "6b710bed"
2) Construct the Normalized Request String by concatenating the following values together with newlines: timestamp, nonce, request method, request URI, server hostname, server port and an empty string for the optional "extension" field::
normalized_request_string = ts + "\n" + nonce + "\n" + "GET" + "\n" + "/user/data" + "\n" + "example.services.mozilla.com" + "\n" + "443" + "\n" + "\n"
3) Take the HMAC signature of the normalized request string, using the MAC Auth key as the HMAC key and SHA1 as the hash function::
mac = HMAC-SHA1(mac_auth_key, normalized_request_string)
4) Include the MAC Auth id, timestamp, nonce and hmac signature in the Authorization header of the request::
GET /user/data Host: example.services.mozilla.com Authorization: MAC id="<mac-auth-id>" ts="1330916952" nonce="6b710bed" mac="<hmac-signature>"
If the server responds with "401 Authentication Required", it indicates one of the following problems with the request:
* the signature was not valid * the MAC Auth credentials have expired * the user has been migrated to a different service endpoint
When receiving a 401 response from the service, clients should obtain new MAC Auth credentials and an updated endpoint URL via the Authentication API.
Why request-signing instead of a simpler bearer-token approach? See this thread on the mailing list for the background discussion.