Sign origin requests with HMAC
Serve a private S3-compatible bucket through a connector by signing each origin request with HMAC credentials.
You can serve the objects of a private bucket through a connector that signs every request to the bucket’s S3-compatible endpoint, from Azion Console, the Azion CLI, or the API. The signing is HMAC, a setting of Origin Shield on a connector of type http. To accept only Azion’s addresses at your origin instead, refer to Allow Azion’s IP ranges at your origin.
The examples use the Azion Object Storage endpoint s3.us-east-005.azionstorage.net with the region us-east-005, and an object named hello.txt at the root of the bucket. Replace them with the endpoint, the region, and an object of your provider.
Select the interface you use. The prerequisites and every task on this page follow that choice.
Prerequisites
- An application served by a workload, and the workload domain or a domain of your own that the workload answers on. To create them, refer to Applications quickstart.
- A private bucket on an S3-compatible endpoint, and an access key and a secret key that can read the bucket. For the credentials of Azion Object Storage, refer to S3 compatibility.
curl, to verify the result.
- Access to Azion Console.
Create the signing connector
The connector reaches the endpoint over HTTPS and sends the endpoint’s own name as the Host header. Its path, /<bucket-name>, goes in front of every request path, so a request for /hello.txt reaches the endpoint as /<bucket-name>/hello.txt. With Origin Shield on, HMAC signs each of these requests with your credentials, using the aws4_hmac_sha256 type.
The CLI creates a connector from a JSON file. Save this body as connector.json, and replace <bucket-name>, <access-key>, and <secret-key> with your values:
The file holds your secret key. Delete it after you create the connector.
To create the connector with the Azion CLI, pass the file and the type. The command needs --type even though the file names the type:
The output carries the ID of the new connector:
Record the ID: the next task passes it as <connector-id>. The connector exists in your account and signs each request it sends to the endpoint.
Turning HMAC off later removes the stored credentials. To turn it back on, enter the access key and the secret key again.
Send requests to the connector
A connector receives no traffic until a rule on your application names it. This rule matches requests for /hello.txt in the request phase, and its Set Connector behavior sends them to the signing connector. Replace /hello.txt with the path of your object. If your application already has a rule that matches every path, keep this rule after it, so this rule decides the connector for the object. For more information, refer to Set Connector.
Keep the rule in a file: on a command line, the shell would expand ${uri}. Save this body as rule.json, and replace <connector-id> with the ID of the signing connector:
To create the rule with the Azion CLI, run this command. Replace <application-id> with the ID of your application:
The output carries the ID of the new rule:
The rule is active on your application, and it sends requests for /hello.txt to the signing connector.
Verify the signed request
The check is the same whichever interface you used. A new connector and a new rule take several minutes to reach Azion’s distributed infrastructure, and data centers apply them at different times. Until then, a request can still reach the connector of another rule. Repeat the request until the endpoint answers. For more information, refer to Propagation.
Request the object through your workload. Replace <workload-domain> with the workload domain or your own domain:
The endpoint answers 200 with the content of the object. These headers identify the storage endpoint as the source of the answer:
To compare, request the same object from the endpoint directly, without a signature:
The endpoint refuses the unsigned request with 401, not 403:
The workload returns the same 401 when HMAC is off on the connector. The connector signs each request to the private bucket, and your workload serves the object. For the fixes, refer to The storage endpoint returns 401 UnauthorizedAccess.