Cloudinary-flavoured URL signing.
Per Cloudinary's docs:
- SHA-256 (modern, default) over the canonical-string
<transforms>/<public-id><api-secret>. - Signature appears as a path segment
s--<base64url-truncated>--inserted between the delivery type (upload) and the first transform stage. - Cloudinary truncates the SHA-256 digest to 32 url-safe-base64 characters by default. We follow that convention; longer signatures are rejected as invalid even if the prefix matches.
v0.1 ships SHA-256 only. Cloudinary's older SHA-1 scheme (8-char
signature, no -- delimiters around the segment) is not
supported — open an issue if you need it.
Sign and verify share the same wire format. The module mirrors
Image.Plug.Signing's public API so it's a drop-in alternative
when configuring the Cloudinary provider.
Summary
Functions
Signs a Cloudinary path with the first key in keys.
Splits a Cloudinary path into {prefix, transforms_and_source}
where prefix is /<account>/<resource-type>/<delivery> and the
remainder is the rest of the path with no leading /.
Verifies the signature on a Cloudinary path.
Functions
Signs a Cloudinary path with the first key in keys.
Arguments
pathis the path-and-query of a Cloudinary URL without ans--<sig>--segment. The signer inserts the segment between<delivery>(e.g.upload) and the first transform stage.keysis a non-empty list of API secrets.
Options
:expires_at— currently unused. Cloudinary's signed-URL flow relies on path-bound signatures rather than a per-URL expiry parameter; expirations live on the API-secret rotation cycle.
Returns
The signed path.
Splits a Cloudinary path into {prefix, transforms_and_source}
where prefix is /<account>/<resource-type>/<delivery> and the
remainder is the rest of the path with no leading /.
Used by both signing and verification to canonicalise.
@spec verify(String.t(), [String.t(), ...], keyword()) :: :ok | {:error, Image.Plug.Error.t()}
Verifies the signature on a Cloudinary path.
Returns :ok or an Image.Plug.Error with one of
:signature_required, :invalid_signature.
Options
:required?— whentrue, missings--<sig>--segment produces:signature_required. Defaultfalse.