Skip to main content

Overview

AWSV4Signer implements AWS Signature Version 4 signing for S3-compatible APIs. This service signs HTTP requests with HMAC-SHA256 authentication, enabling secure access to Cloudflare R2 storage.
Located at: Fiaxe/Services/AWSV4Signer.swift:6

Type Definition

Implemented as a nonisolated enum to allow calling from any actor context without isolation restrictions.

Methods

sign()

Signs a URLRequest with AWS Signature V4 and returns the signed request.
URLRequest
required
Request with url, httpMethod, and headers already set. This request will be modified with authentication headers.
R2Credentials
required
R2 credentials containing:
  • Account ID
  • Access key ID
  • Secret access key
  • Bucket name
String
default:"UNSIGNED-PAYLOAD"
SHA-256 hex digest of the request body. Use:
  • "UNSIGNED-PAYLOAD" for streaming uploads or when the payload isn’t pre-hashed
  • AWSV4Signer.sha256Hex("") for empty body (GET, DELETE, HEAD requests)
  • AWSV4Signer.sha256Hex(bodyContent) for requests with a body
Date
default:"Date()"
Signing date. Defaults to current time. Must match the date in x-amz-date header.
Returns: Signed URLRequest with Authorization, x-amz-date, x-amz-content-sha256, and Host headers.

Implementation Details

The signing process follows the AWS Signature Version 4 specification:
  1. Add required headers
  1. Build canonical request
  1. Create string to sign
  1. Derive signing key and compute signature

presignedURL()

Generates a presigned GET URL valid for a specified duration.
String
required
Object key in the bucket. Example: "photos/vacation.jpg"
R2Credentials
required
R2 credentials for signing the URL.
Int
default:"3600"
Number of seconds the URL should remain valid. Default is 1 hour (3600 seconds).
Date
default:"Date()"
Signing date. The expiration is calculated from this date.
Returns: Presigned URL that can be fetched without auth headers, or nil if URL construction fails.

Implementation Details

Presigned URLs embed authentication in query parameters instead of headers:

sha256Hex()

Computes SHA-256 hash of a string and returns hex-encoded result.
String
required
Input string to hash.
Returns: Lowercase hex-encoded SHA-256 digest.

Helper Methods

URI Encoding

The signer uses strict URI encoding that matches AWS requirements:
Only alphanumerics and -._~ are left unencoded, matching AWS Signature V4 specifications.

Canonical Path

The canonical path preserves trailing slashes and applies strict encoding:
This is crucial for R2 folder operations where trailing slashes distinguish folders from files.

Canonical Query String

Query parameters are sorted and strictly encoded:

Signing Key Derivation

The signing key is derived through multiple HMAC operations:
This creates a key hierarchy: kSecret -> kDate -> kRegion -> kService -> kSigning

Date Formatting

Two date formats are used:

Usage Examples

AWS Signature V4 Specification

The implementation follows the official AWS Signature Version 4 specification:
1

Canonical Request

Normalize the HTTP request into a canonical format:
2

String to Sign

Create a string that includes the algorithm, timestamp, credential scope, and hashed canonical request:
3

Signing Key

Derive a signing key through a series of HMAC operations:
4

Signature

Calculate the signature by HMAC-SHA256 of the string to sign with the signing key:
5

Authorization Header

Add the Authorization header to the request:

Cloudflare R2 Specifics

R2 uses the region "auto" instead of standard AWS regions like "us-east-1". The endpoint format is: