Image.Plug.Provider.Cloudinary.Signing (image_plug v0.1.0)

Copy Markdown View Source

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

sign(path, keys, options \\ [])

@spec sign(String.t(), [String.t(), ...], keyword()) :: String.t()

Signs a Cloudinary path with the first key in keys.

Arguments

  • path is the path-and-query of a Cloudinary URL without an s--<sig>-- segment. The signer inserts the segment between <delivery> (e.g. upload) and the first transform stage.

  • keys is 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.

split_at_delivery(path)

@spec split_at_delivery(String.t()) :: {String.t(), String.t()}

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.

verify(path, keys, options \\ [])

@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? — when true, missing s--<sig>-- segment produces :signature_required. Default false.