Link Search Menu Expand Document

Request Authentication

Authentication allows server to verify the integrity of the request and identify the sender. Based on the identity, access control, usage tracking and rate limiting can be enforced. This section describes how to build authorization signature for request.

Photon P3 REST endpoints use HMAC (Hash Message Authenciation Code) on top of HTTP scheme for authentication. In order to make request to Photon P3 service, you first acquire a P3 access key ID and a access key secret through P3 portal. Keep them in safe place so no one can fabricate your identity. After building an HTTP request, you concatenate selected fields form a string. HMAC of the string is calculated using your access key secret. The HMAC is the “signature” of your request. It is part of the Authorization field in the HTTP header. When a P3 server receives a request, it performs the same signing process and compares the resulting signature against the one extracted the Authorization header. If these two signatures match, the server can proceed to process the request with the authenticated identity. Otherwise, the request is denied.

The authentication header

The Photon P3 REST endpoints receives authentication data by using the standard HTTP Authorization header. The header field value is P3 access key ID concatenated with request signature, deliminated by a colon.

Authorization: access_key_id:signature

The access key ID is a straight copy from what is given by P3 port. The signature is the BASE64 encoding of RFC 2104 HMAC-SHA1 of selected elements from the HTTP request being authenticated. P3 server uses the provided access key ID to find its matching access key secret and signs the request using the same procedure done by a client. The resulting signature is matched against the signature from the Authorization header to verify the identity of the requester.

signature = BASE64( HMAC_SHA1( UTF8_Encoding(access_key_secret), UTF8_Encoding(string_to_sign) ) )

HMAC function takes two parameters. One is your access key secret. The other one is the string composed from selected parts of the request being authenticated. Both parameters should be UTF-8 encoded. The output digest of HMAC function is further encoded using BASE64 encoding scheme to be transferred through HTTP safely.

The string_to_sign has 3 components, concatenated together with delimiter newline “\n”.

string_to_sign = positional_fields + "\n" +
                 canonicalized_p3_headers + "\n" +
                 canonicalized_uri

Positional fields

The positional_fields are 4 field values concatenated together in fixed order with delimieter newline “\n”.

positional_fields = http_verb + "\n" +
                    content_md5 + "\n" +
                    content_type + "\n" +
                    date + "\n" +

The http_verb is either GET or PUT. The content_md5 is the value from P3 specific HTTP header x-p3-content-md5 and falls back to standard header Content-MD5 if missing. Empty string “” is used if both headers are missing. The content_type is the value from P3 specific HTTP header x-p3-content-type and falls back to standard header Content-MD5 if missing. Empty string “” is used if both headers are missing. Finally, the date value is a string representation of the request time in RFC3339 format. Request time is extracted from P3 specific HTTP header x-p3-unixtime, which is a unix timestamp in seconds. If the header is missing, it falls back to standard HTTP header Date. The date is a required value and must be no later than 15 minutes to ensure freshness of a request.

Canonicalized P3 headers

The canonicalized_p3_headers is generated by P3 specific HTTP headers using rules described below:

  1. Select all HTTP headers that have prefix “x-p3-“ in its name and convert names to lowercase.
  2. Sort selected headers lexicographically by header name.
  3. For each header name, corresponding values are concatenated together with delimiter “,”. Then further concatenate with head name using delimiter “:” with all whitespace trimmed. For example, a header “x-p3-example” has two values “foo” and “bar”, the concatenated result is “x-p3-example:foo,bar”.
  4. Finally, results for each header are concatenated together using newline “\n” as delimiter.

Canonicalized URI

The canonicalized_uri identifies P3 object being accessed, similar to AWS S3.

canonicalized_uri = "/" + bucket_name + "/" + object_key

Both bucket_name and object_key are canonicalized with extra and repeated backslash removed. For example, bucket “example_bucket” and key “foo//bar” generate canonicalized URI “/example_bucket/foo/bar”.